diff --git a/maca_common/include/ProgramParameters.hpp b/maca_common/include/ProgramParameters.hpp index fe1efb06c1638be860ec40ee1304c01e6d38667c..27f321a9ce92d6dcd99d02ef8ff392f377efa159 100644 --- a/maca_common/include/ProgramParameters.hpp +++ b/maca_common/include/ProgramParameters.hpp @@ -60,6 +60,7 @@ struct ProgramParameters static bool onlyPrefixes; static std::map<std::string,std::string> featureModelByClassifier; static int nbErrorsToShow; + static int nbIndividuals; private : diff --git a/maca_common/src/ProgramParameters.cpp b/maca_common/src/ProgramParameters.cpp index 64d01ac8f768c9a1643bd656613a0175f9e9fe22..30d96ff32ff679a348c496371eee4bdcce085f38 100644 --- a/maca_common/src/ProgramParameters.cpp +++ b/maca_common/src/ProgramParameters.cpp @@ -54,3 +54,5 @@ int ProgramParameters::batchSize; std::string ProgramParameters::loss; std::map<std::string,std::string> ProgramParameters::featureModelByClassifier; int ProgramParameters::nbErrorsToShow; +int ProgramParameters::nbIndividuals; + diff --git a/neural_network/src/GeneticAlgorithm.cpp b/neural_network/src/GeneticAlgorithm.cpp index 9c858c8d548390a44721c4492bda9fa500f8a64f..036a438c28ff09af303ab5ac2a08f1284492816d 100644 --- a/neural_network/src/GeneticAlgorithm.cpp +++ b/neural_network/src/GeneticAlgorithm.cpp @@ -39,7 +39,26 @@ void GeneticAlgorithm::init(int nbInputs, const std::string & topology, int nbOu std::vector<float> GeneticAlgorithm::predict(FeatureModel::FeatureDescription & fd) { - return generation[0]->mlp.predict(fd); + int toAsk = ProgramParameters::nbIndividuals; + + if (toAsk < 0 || toAsk > (int)generation.size()) + { + fprintf(stderr, "ERROR (%s) : trying to save \'%d\' individuals out of a population of \'%lu\'. Aborting.\n", ERRINFO, toAsk, generation.size()); + exit(1); + } + + auto prediction = generation[0]->mlp.predict(fd); + for (int i = 1; i < toAsk; i++) + { + auto otherPrediction = generation[i]->mlp.predict(fd); + for (unsigned int j = 0; j < prediction.size(); j++) + prediction[j] += otherPrediction[j]; + } + + for (unsigned int j = 0; j < prediction.size(); j++) + prediction[j] /= toAsk; + + return prediction; } float GeneticAlgorithm::update(FeatureModel::FeatureDescription & fd, int gold) @@ -115,11 +134,24 @@ float GeneticAlgorithm::update(FeatureModel::FeatureDescription & fd, int gold) void GeneticAlgorithm::save(const std::string & filename) { + int toSave = ProgramParameters::nbIndividuals; + + if (toSave < 0 || toSave > (int)generation.size()) + { + fprintf(stderr, "ERROR (%s) : trying to save \'%d\' individuals out of a population of \'%lu\'. Aborting.\n", ERRINFO, toSave, generation.size()); + exit(1); + } + File * file = new File(filename, "w"); - fprintf(file->getDescriptor(), "%u\n", generation[0]->id); + for (int i = 0; i < toSave; i++) + fprintf(file->getDescriptor(), "%u\n", generation[i]->id); delete file; - generation[0]->mlp.saveStruct(filename); - generation[0]->mlp.saveParameters(filename); + + for (int i = 0; i < toSave; i++) + { + generation[i]->mlp.saveStruct(filename); + generation[i]->mlp.saveParameters(filename); + } } void GeneticAlgorithm::printTopology(FILE * output) @@ -137,18 +169,28 @@ void GeneticAlgorithm::printTopology(FILE * output) void GeneticAlgorithm::load(const std::string & filename) { + std::vector<int> ids; File * file = new File(filename, "r"); - unsigned int bestId; - if (fscanf(file->getDescriptor(), "%u\n", &bestId) != 1) + unsigned int id; + while (fscanf(file->getDescriptor(), "%u\n", &id) == 1) + ids.emplace_back(id); + delete file; + + if (ids.empty()) { - fprintf(stderr, "ERROR (%s) : expected best id when reading file \'%s\'. Aborting.\n", ERRINFO, filename.c_str()); + fprintf(stderr, "ERROR (%s) : Missing MLP\''s ids in file \'%s\'. Aborting.\n", ERRINFO, filename.c_str()); exit(1); } - delete file; - generation.emplace_back(new Individual(bestId)); - generation[0]->mlp.loadStruct(model, filename, 0); - generation[0]->mlp.loadParameters(model, filename); + ProgramParameters::nbIndividuals = ids.size(); + + for (auto & id : ids) + { + generation.emplace_back(new Individual(id)); + + generation.back()->mlp.loadStruct(model, filename, generation.size()-1); + generation.back()->mlp.loadParameters(model, filename); + } } GeneticAlgorithm::Individual::Individual(dynet::ParameterCollection & model, int nbInputs, const std::string & topology, int nbOutputs) : mlp("MLP_" + std::to_string(idCount)) @@ -244,7 +286,7 @@ void GeneticAlgorithm::Individual::mutate(float probability) for (unsigned int k = 0; k < nbValues; k++) if (choiceWithProbability(probability)) - thisValues[k] = getRandomValueInRange(1); + thisValues[k] = getRandomValueInRange(3); } } diff --git a/trainer/src/macaon_train.cpp b/trainer/src/macaon_train.cpp index 3b89f2bb7c1cc615c2cc7272ffc89383e9be4c61..b863493487a0f108486e92ba7500431e41e56b81 100644 --- a/trainer/src/macaon_train.cpp +++ b/trainer/src/macaon_train.cpp @@ -99,7 +99,12 @@ po::options_description getOptionsDescription() ("bias", po::value<float>()->default_value(1e-8), "bias parameter for the Amsgtad or Adam or Adagrad optimizer"); - desc.add(req).add(opt).add(oracle).add(ams); + po::options_description ga("Genetic algorithm related options"); + ga.add_options() + ("nbIndividuals", po::value<int>()->default_value(5), + "Number of individuals that will be used to take decisions"); + + desc.add(req).add(opt).add(oracle).add(ams).add(ga); return desc; } @@ -273,6 +278,7 @@ int main(int argc, char * argv[]) ProgramParameters::beta1 = vm["b1"].as<float>(); ProgramParameters::beta2 = vm["b2"].as<float>(); ProgramParameters::bias = vm["bias"].as<float>(); + ProgramParameters::nbIndividuals = vm["nbIndividuals"].as<int>(); ProgramParameters::optimizer = vm["optimizer"].as<std::string>(); ProgramParameters::dicts = vm["dicts"].as<std::string>(); ProgramParameters::loss = vm["loss"].as<std::string>();