diff --git a/maca_common/include/ProgramParameters.hpp b/maca_common/include/ProgramParameters.hpp
index f97160c0661097e6de2872b48300d032b9bed7f7..1e8e5274214ead767108ac2b00b85ebf0f5efd35 100644
--- a/maca_common/include/ProgramParameters.hpp
+++ b/maca_common/include/ProgramParameters.hpp
@@ -12,6 +12,9 @@ struct ProgramParameters
   static std::string input;
   static std::string expName;
   static std::string expPath;
+  static std::string langPath;
+  static std::string templatePath;
+  static std::string templateName;
   static std::string tmFilename;
   static std::string tmName;
   static std::string bdFilename;
diff --git a/maca_common/src/ProgramParameters.cpp b/maca_common/src/ProgramParameters.cpp
index d55f7e23a1f298e70fea252ac02c59cd9492d240..e864d3faf4e502adbb2f37af2e3ea4466e22774f 100644
--- a/maca_common/src/ProgramParameters.cpp
+++ b/maca_common/src/ProgramParameters.cpp
@@ -7,6 +7,9 @@ ProgramParameters::ProgramParameters()
 std::string ProgramParameters::input;
 std::string ProgramParameters::expName;
 std::string ProgramParameters::expPath;
+std::string ProgramParameters::langPath;
+std::string ProgramParameters::templatePath;
+std::string ProgramParameters::templateName;
 std::string ProgramParameters::tmFilename;
 std::string ProgramParameters::tmName;
 std::string ProgramParameters::bdFilename;
diff --git a/trainer/src/macaon_train.cpp b/trainer/src/macaon_train.cpp
index b041515c6c3aaf48ff33b8f357c4e23be99ef631..5debf9da6ddf36425b83bd8731aa6f8dbd3570cb 100644
--- a/trainer/src/macaon_train.cpp
+++ b/trainer/src/macaon_train.cpp
@@ -25,6 +25,8 @@ po::options_description getOptionsDescription()
   req.add_options()
     ("expName", po::value<std::string>()->required(),
       "Name of this experiment")
+    ("templateName", po::value<std::string>()->required(),
+      "Name of the template folder")
     ("tm", po::value<std::string>()->required(),
       "File describing the Tape Machine we will train")
     ("bd", po::value<std::string>()->required(),
@@ -47,7 +49,7 @@ po::options_description getOptionsDescription()
     ("nbiter,n", po::value<int>()->default_value(5),
       "Number of training epochs (iterations)")
     ("iterationSize", po::value<int>()->default_value(-1),
-      "The number of examples for each iteration. -1 means the whole training set.")
+      "The number of examples for each iteration. -1 means the whole training set")
     ("lr", po::value<float>()->default_value(0.001),
       "Learning rate of the optimizer")
     ("seed,s", po::value<int>()->default_value(100),
@@ -118,6 +120,82 @@ po::variables_map checkOptions(po::options_description & od, int argc, char ** a
   return vm;
 }
 
+/// @brief Set all the usefull paths relative to expPath
+void updatePaths()
+{
+  const char * MACAON_DIR = std::getenv("MACAON_DIR");
+  std::string slash = "/";
+  ProgramParameters::langPath = MACAON_DIR + slash + ProgramParameters::lang + slash;
+  ProgramParameters::expPath = ProgramParameters::langPath + "bin/" + ProgramParameters::expName + slash;
+  ProgramParameters::templatePath = ProgramParameters::langPath + ProgramParameters::templateName + slash;
+  ProgramParameters::tmFilename = ProgramParameters::expPath + ProgramParameters::tmName;
+  ProgramParameters::bdFilename = ProgramParameters::expPath + ProgramParameters::bdName;
+  ProgramParameters::mcdFilename = ProgramParameters::expPath + ProgramParameters::mcdName;
+  ProgramParameters::trainFilename = ProgramParameters::expPath + ProgramParameters::trainName;
+  ProgramParameters::devFilename = ProgramParameters::expPath + ProgramParameters::devName;
+}
+
+/// @brief Create the folder containing the current experiment from the template frolder
+void createExpPath()
+{
+std::string decode = "\
+#! /bin/bash\n\
+\n\
+if [ \"$#\" -lt 2 ]; then\n\
+ echo \"Usage : $0 input mcd\"\n\
+ exit\n\
+fi\n\
+\n\
+INPUT=$1\n\
+MCD=$2\n\
+\n\
+shift\n\
+shift\n\
+ARGS=\"\"\n\
+for arg in \"$@\"\n\
+do\n\
+  ARGS=\"$ARGS $arg\"\n\
+done\n\
+\n\
+macaon_decode --lang $LANG --tm machine.tm --bd test.bd -I $INPUT --mcd $MCD --expName " + ProgramParameters::expName + "$ARGS";
+
+  if (system(("rm -r " + ProgramParameters::expPath + " 2> /dev/null").c_str())){}
+  if (system(("mkdir " + ProgramParameters::expPath).c_str())){}
+  if (system(("cp -r " + ProgramParameters::templatePath + "* " + ProgramParameters::expPath + ".").c_str())){}
+  if (system(("echo \'" + decode + "\' > " + ProgramParameters::expPath + "decode.sh").c_str())){}
+  if (system(("chmod +x " + ProgramParameters::expPath + "decode.sh").c_str())){}
+  if (system(("ln -f -s " + ProgramParameters::expPath + "decode.sh " + ProgramParameters::langPath + "bin/maca_tm_" + ProgramParameters::expName).c_str())){}
+}
+
+/// @brief Train a model according to all the ProgramParameters
+void launchTraining()
+{
+  TransitionMachine transitionMachine(true);
+
+  BD trainBD(ProgramParameters::bdFilename, ProgramParameters::mcdFilename);
+  Config trainConfig(trainBD);
+  trainConfig.readInput(ProgramParameters::trainFilename);
+
+  std::unique_ptr<BD> devBD;
+  std::unique_ptr<Config> devConfig;
+
+  std::unique_ptr<Trainer> trainer;
+
+  if(ProgramParameters::devFilename.empty())
+  {
+    trainer.reset(new Trainer(transitionMachine, trainBD, trainConfig));
+  }
+  else
+  {
+    devBD.reset(new BD(ProgramParameters::bdFilename, ProgramParameters::mcdFilename));
+    devConfig.reset(new Config(*devBD.get()));
+    devConfig->readInput(ProgramParameters::devFilename);
+    trainer.reset(new Trainer(transitionMachine, trainBD, trainConfig, devBD.get(), devConfig.get()));
+  }
+
+  trainer->train();
+}
+
 /// @brief Train a TransitionMachine to predict and add information to a structured input file, by using annotated examples.
 ///
 /// @param argc The number of arguments given to this program.
@@ -131,6 +209,7 @@ int main(int argc, char * argv[])
   po::variables_map vm = checkOptions(od, argc, argv);
 
   ProgramParameters::expName = vm["expName"].as<std::string>();
+  ProgramParameters::templateName = vm["templateName"].as<std::string>();
   ProgramParameters::tmName = vm["tm"].as<std::string>();
   ProgramParameters::bdName = vm["bd"].as<std::string>();
   ProgramParameters::mcdName = vm["mcd"].as<std::string>();
@@ -153,40 +232,13 @@ int main(int argc, char * argv[])
   ProgramParameters::showFeatureRepresentation = vm["showFeatureRepresentation"].as<bool>();
   ProgramParameters::iterationSize = vm["iterationSize"].as<int>();
 
-  const char * MACAON_DIR = std::getenv("MACAON_DIR");
-  std::string slash = "/";
-  ProgramParameters::expPath = MACAON_DIR + slash + ProgramParameters::lang + slash + "bin/" + ProgramParameters::expName + slash;
-
-  ProgramParameters::tmFilename = ProgramParameters::expPath + ProgramParameters::tmName;
-  ProgramParameters::bdFilename = ProgramParameters::expPath + ProgramParameters::bdName;
-  ProgramParameters::mcdFilename = ProgramParameters::expPath + ProgramParameters::mcdName;
-  ProgramParameters::trainFilename = ProgramParameters::expPath + ProgramParameters::trainName;
-  ProgramParameters::devFilename = ProgramParameters::expPath + ProgramParameters::devName;
-
-  TransitionMachine transitionMachine(true);
-
-  BD trainBD(ProgramParameters::bdFilename, ProgramParameters::mcdFilename);
-  Config trainConfig(trainBD);
-  trainConfig.readInput(ProgramParameters::trainFilename);
-
-  std::unique_ptr<BD> devBD;
-  std::unique_ptr<Config> devConfig;
-
-  std::unique_ptr<Trainer> trainer;
-
-  if(ProgramParameters::devFilename.empty())
+  for (int i = 0; i < 10; i++)
   {
-    trainer.reset(new Trainer(transitionMachine, trainBD, trainConfig));
+    ProgramParameters::expName += "_" + std::to_string(i);
+    updatePaths();
+    createExpPath();
+    launchTraining();
   }
-  else
-  {
-    devBD.reset(new BD(ProgramParameters::bdFilename, ProgramParameters::mcdFilename));
-    devConfig.reset(new Config(*devBD.get()));
-    devConfig->readInput(ProgramParameters::devFilename);
-    trainer.reset(new Trainer(transitionMachine, trainBD, trainConfig, devBD.get(), devConfig.get()));
-  }
-
-  trainer->train();
 
   return 0;
 }