Skip to content
Snippets Groups Projects
Commit 0da7cec7 authored by Franck Dary's avatar Franck Dary
Browse files

Added a skeleton for a GeneticAlgorithm class

parent 0f838ba7
Branches
No related tags found
No related merge requests found
#ifndef GENETICALGORITHM__H
#define GENETICALGORITHM__H
#include <dynet/nodes.h>
#include <dynet/dynet.h>
#include <dynet/training.h>
#include <dynet/timing.h>
#include <dynet/expr.h>
#include <dynet/io.h>
#include <string>
#include "NeuralNetwork.hpp"
#include "FeatureModel.hpp"
class GeneticAlgorithm : public NeuralNetwork
{
private :
/// @brief An individual is a MLP
class Individual
{
private :
/// @brief The Layers of the MLP.
std::vector<Layer> layers;
/// @brief The parameters corresponding to the layers of the MLP.
std::vector< std::vector<dynet::Parameter> > parameters;
public :
/// @brief Create a new individual for the population.
///
/// @param topology The topology the underlying MLP will take.
/// @param model The Collection of parameters of the GeneticAlgorithm.
/// @param nbInputs The size of the input layer of the MLP.
/// @param nbOutputs The size of the output layer of the MLP.
Individual(const std::string & topology, dynet::ParameterCollection & model, int nbInputs, int nbOutputs);
};
private :
/// @brief Load this GeneticAlgorithm from a file.
///
/// @param filename The name of the file where the GeneticAlgorithm is stored.
void load(const std::string & filename);
public :
/// @brief Create a new untrained GeneticAlgorithm from scratch.
GeneticAlgorithm();
/// @brief Create and load an already trained GeneticAlgorithm from a file.
///
/// @param filename The file where the GeneticAlgorithm is stored.
GeneticAlgorithm(const std::string & filename);
/// @brief initialize a new untrained GeneticAlgorithm from a desired topology.
///
/// @param nbInputs The size of the input.
/// @param topology Description of the GeneticAlgorithm.
/// @param nbOutputs The size of the output.
void init(int nbInputs, const std::string & topology, int nbOutputs) override;
/// @brief Give a score to each possible class, given an input.
///
/// @param fd The input to use.
///
/// @return A vector containing one score per possible class.
std::vector<float> predict(FeatureModel::FeatureDescription & fd) override;
/// @brief Update the parameters according to the given gold class.
///
/// @param fd The input to use.
/// @param gold The gold class of this input.
///
/// @return The loss.
float update(FeatureModel::FeatureDescription & fd, int gold) override;
/// @brief Save the GeneticAlgorithm to a file.
///
/// @param filename The file to write the GeneticAlgorithm to.
void save(const std::string & filename) override;
/// @brief Print the topology of the GeneticAlgorithm.
///
/// @param output Where the topology will be printed.
void printTopology(FILE * output) override;
};
#endif
......@@ -15,62 +15,6 @@
/// Once trained, it can also be used to predict the class of a certain input.
class MLP : public NeuralNetwork
{
public :
/// @brief Activation function for a MLP Layer.
enum Activation
{
SIGMOID,
TANH,
RELU,
ELU,
LINEAR,
SPARSEMAX,
CUBE,
SOFTMAX
};
/// @brief Get the string corresponding to an Activation.
///
/// @param a The activation.
///
/// @return The string corresponding to a.
static std::string activation2str(Activation a);
/// @brief Get the Activation corresponding to a string.
///
/// @param s The string.
///
/// @return The Activation corresponding to s. If s is unknown, the program abort.
static Activation str2activation(std::string s);
/// @brief A simple struct that represents a MLP Layer.
struct Layer
{
/// @brief Number of input neurons of this Layer.
int input_dim;
/// @brief Number of output neurons of this Layer.
int output_dim;
/// @brief The dropout rate to apply to this Layer when training.
float dropout_rate;
/// @brief The activation function for this Layer.
Activation activation;
/// @brief Construct a new Layer
///
/// @param input_dim
/// @param output_dim
/// @param dropout_rate
/// @param activation
Layer(int input_dim, int output_dim,
float dropout_rate, Activation activation);
/// @brief Print a description of this Layer.
///
/// @param file Where to print the output.
void print(FILE * file);
};
private :
/// @brief The Layers of the MLP.
......@@ -96,10 +40,6 @@ class MLP : public NeuralNetwork
void addLayerToModel(Layer & layer);
/// @brief Abort the program if the layers are not compatible.
void checkLayersCompatibility();
/// @brief Set dynet and srand() seeds.
///
/// @return The DynetParams containing the set seed.
dynet::DynetParams & getDefaultParams();
/// @brief Compute the image of input x by the Multi Layer Perceptron.
///
/// @param cg The current computation graph.
......@@ -107,13 +47,6 @@ class MLP : public NeuralNetwork
///
/// @return The result (values of the output Layer) of the computation of x by the Multi Layer Perceptron.
dynet::Expression run(dynet::ComputationGraph & cg, dynet::Expression x);
/// @brief Compute the image of an expression by an activation function.
///
/// @param h The expression we want the image of.
/// @param f The activation function.
///
/// @return f(h)
inline dynet::Expression activate(dynet::Expression h, Activation f);
/// @brief Print the parameters.
///
/// @param output Where the parameters will be printed to.
......@@ -146,10 +79,6 @@ class MLP : public NeuralNetwork
/// This function will use loadStruct and loadParameters.
/// @param filename The file from which the MLP will be loaded.
void load(const std::string & filename);
/// @brief Initialize the dynet library.
///
/// Must be called only once, and before any call to dynet functions.
void initDynet();
/// @brief Get the loss expression
///
/// @param output Output from the neural network
......@@ -170,7 +99,7 @@ class MLP : public NeuralNetwork
/// @param nbInputs The size of the input layer of the MLP.
/// @param topology Description of each hidden Layer of the MLP.
/// @param nbOutputs The size of the output layer of the MLP.
void init(int nbInputs, const std::string & topology, int nbOutputs);
void init(int nbInputs, const std::string & topology, int nbOutputs) override;
/// @brief Construct a new MLP for training.
MLP();
/// @brief Read and construct a trained MLP from a file.
......
......@@ -14,6 +14,62 @@ class NeuralNetwork
{
protected :
/// @brief Activation function for a Layer.
enum Activation
{
SIGMOID,
TANH,
RELU,
ELU,
LINEAR,
SPARSEMAX,
CUBE,
SOFTMAX
};
/// @brief Get the string corresponding to an Activation.
///
/// @param a The activation.
///
/// @return The string corresponding to a.
static std::string activation2str(Activation a);
/// @brief Get the Activation corresponding to a string.
///
/// @param s The string.
///
/// @return The Activation corresponding to s. If s is unknown, the program abort.
static Activation str2activation(std::string s);
/// @brief A simple struct that represents a Layer.
struct Layer
{
/// @brief Number of input neurons of this Layer.
int input_dim;
/// @brief Number of output neurons of this Layer.
int output_dim;
/// @brief The dropout rate to apply to this Layer when training.
float dropout_rate;
/// @brief The activation function for this Layer.
Activation activation;
/// @brief Construct a new Layer
///
/// @param input_dim
/// @param output_dim
/// @param dropout_rate
/// @param activation
Layer(int input_dim, int output_dim,
float dropout_rate, Activation activation);
/// @brief Print a description of this Layer.
///
/// @param file Where to print the output.
void print(FILE * file);
};
protected :
/// @brief The seed that will be used by RNG (srand and dynet)
static int randomSeed;
......@@ -32,6 +88,21 @@ class NeuralNetwork
///
/// @return A dynet Expression of value fv that can be used as an input in the NeuralNetwork
dynet::Expression featValue2Expression(dynet::ComputationGraph & cg, const FeatureModel::FeatureValue & fv);
/// @brief Set dynet and srand() seeds.
///
/// @return The DynetParams containing the set seed.
dynet::DynetParams & getDefaultParams();
/// @brief Initialize the dynet library.
///
/// Must be called only once, and before any call to dynet functions.
void initDynet();
/// @brief Compute the image of an expression by an activation function.
///
/// @param h The expression we want the image of.
/// @param f The activation function.
///
/// @return f(h)
dynet::Expression activate(dynet::Expression h, Activation f);
public :
......
#include "GeneticAlgorithm.hpp"
#include "ProgramParameters.hpp"
GeneticAlgorithm::GeneticAlgorithm()
{
randomSeed = ProgramParameters::seed;
initDynet();
}
GeneticAlgorithm::GeneticAlgorithm(const std::string & filename)
{
randomSeed = ProgramParameters::seed;
initDynet();
load(filename);
}
void GeneticAlgorithm::init(int nbInputs, const std::string & topology, int nbOutputs)
{
fprintf(stderr, "init of genetic\n");
}
std::vector<float> GeneticAlgorithm::predict(FeatureModel::FeatureDescription & fd)
{
}
float GeneticAlgorithm::update(FeatureModel::FeatureDescription & fd, int gold)
{
}
void GeneticAlgorithm::save(const std::string & filename)
{
}
void GeneticAlgorithm::printTopology(FILE * output)
{
}
void GeneticAlgorithm::load(const std::string & filename)
{
}
GeneticAlgorithm::Individual::Individual(const std::string & topology, dynet::ParameterCollection & model, int nbInputs, int nbOutputs)
{
std::string topo = topology;
std::replace(topo.begin(), topo.end(), '(', ' ');
std::replace(topo.begin(), topo.end(), ')', ' ');
auto groups = split(topo);
for (auto group : groups)
{
if(group.empty())
continue;
std::replace(group.begin(), group.end(), ',', ' ');
auto layer = split(group);
if (layer.size() != 2)
{
fprintf(stderr, "ERROR (%s) : invalid topology \'%s\'. Aborting.\n", ERRINFO, topology.c_str());
exit(1);
}
int input = layers.empty() ? nbInputs : layers.back().output_dim;
int output = std::stoi(layer[0]);
layers.emplace_back(input, output, 0, str2activation(layer[1]));
}
layers.emplace_back(layers.back().output_dim, nbOutputs, 0.0, Activation::LINEAR);
if(layers.empty())
{
fprintf(stderr, "ERROR (%s) : constructed mlp with 0 layers. Aborting.\n", ERRINFO);
exit(1);
}
for(unsigned int i = 0; i < layers.size()-1; i++)
if(layers[i].output_dim != layers[i+1].input_dim)
{
fprintf(stderr, "ERROR (%s) : constructed mlp with incompatible layers. Aborting.\n", ERRINFO);
exit(1);
}
for (auto & layer : layers)
{
dynet::Parameter W = model.add_parameters({(unsigned)layer.output_dim, (unsigned)layer.input_dim});
dynet::Parameter b = model.add_parameters({(unsigned)layer.output_dim});
parameters.push_back({W,b});
}
}
#include "MLP.hpp"
std::string MLP::activation2str(Activation a)
{
switch(a)
{
case LINEAR :
return "LINEAR";
break;
case RELU :
return "RELU";
break;
case ELU :
return "ELU";
break;
case CUBE :
return "CUBE";
break;
case SIGMOID :
return "SIGMOID";
break;
case TANH :
return "TANH";
break;
case SOFTMAX :
return "SOFTMAX";
break;
case SPARSEMAX :
return "SPARSEMAX";
break;
default :
break;
}
return "UNKNOWN";
}
MLP::Activation MLP::str2activation(std::string s)
{
if(s == "LINEAR")
return LINEAR;
else if(s == "RELU")
return RELU;
else if(s == "ELU")
return ELU;
else if(s == "CUBE")
return CUBE;
else if(s == "SIGMOID")
return SIGMOID;
else if(s == "TANH")
return TANH;
else if(s == "SOFTMAX")
return SOFTMAX;
else if(s == "SPARSEMAX")
return SPARSEMAX;
else
{
fprintf(stderr, "ERROR (%s) : invalid activation \'%s\'. Aborting\n",ERRINFO, s.c_str());
exit(1);
}
return LINEAR;
}
void MLP::initDynet()
{
if(dynetIsInit)
return;
dynetIsInit = true;
dynet::initialize(getDefaultParams());
}
MLP::MLP()
{
randomSeed = ProgramParameters::seed;
......@@ -162,15 +91,6 @@ void MLP::checkLayersCompatibility()
}
}
MLP::Layer::Layer(int input_dim, int output_dim,
float dropout_rate, Activation activation)
{
this->input_dim = input_dim;
this->output_dim = output_dim;
this->dropout_rate = dropout_rate;
this->activation = activation;
}
std::vector<float> MLP::predict(FeatureModel::FeatureDescription & fd)
{
bool currentDropoutActive = dropoutActive;
......@@ -284,16 +204,6 @@ dynet::Expression MLP::errorCorrectionLoss(dynet::ComputationGraph & cg, dynet::
return dynet::sum(lossExpr);
}
dynet::DynetParams & MLP::getDefaultParams()
{
static dynet::DynetParams params;
params.random_seed = randomSeed;
std::srand(params.random_seed);
return params;
}
dynet::Expression MLP::run(dynet::ComputationGraph & cg, dynet::Expression x)
{
static std::vector< std::pair<std::string,dynet::Expression> > exprForDebug;
......@@ -378,38 +288,6 @@ dynet::Expression MLP::run(dynet::ComputationGraph & cg, dynet::Expression x)
return h_cur;
}
inline dynet::Expression MLP::activate(dynet::Expression h, Activation f)
{
switch(f)
{
case LINEAR :
return h;
break;
case RELU :
return rectify(h);
break;
case ELU :
return elu(h);
break;
case SIGMOID :
return logistic(h);
break;
case TANH :
return tanh(h);
break;
case SOFTMAX :
return softmax(h);
break;
default :
break;
}
fprintf(stderr, "ERROR (%s) : Activation not implemented \'%s\'. Aborting.\n", ERRINFO, activation2str(f).c_str());
exit(1);
return h;
}
void MLP::printParameters(FILE * output)
{
fprintf(output, "Parameters : NOT IMPLEMENTED\n");
......
......@@ -44,3 +44,125 @@ dynet::Expression NeuralNetwork::featValue2Expression(dynet::ComputationGraph &
return dynet::concatenate(expressions);
}
dynet::DynetParams & NeuralNetwork::getDefaultParams()
{
static dynet::DynetParams params;
params.random_seed = randomSeed;
std::srand(params.random_seed);
return params;
}
void NeuralNetwork::initDynet()
{
if(dynetIsInit)
return;
dynetIsInit = true;
dynet::initialize(getDefaultParams());
}
std::string NeuralNetwork::activation2str(Activation a)
{
switch(a)
{
case LINEAR :
return "LINEAR";
break;
case RELU :
return "RELU";
break;
case ELU :
return "ELU";
break;
case CUBE :
return "CUBE";
break;
case SIGMOID :
return "SIGMOID";
break;
case TANH :
return "TANH";
break;
case SOFTMAX :
return "SOFTMAX";
break;
case SPARSEMAX :
return "SPARSEMAX";
break;
default :
break;
}
return "UNKNOWN";
}
NeuralNetwork::Activation NeuralNetwork::str2activation(std::string s)
{
if(s == "LINEAR")
return LINEAR;
else if(s == "RELU")
return RELU;
else if(s == "ELU")
return ELU;
else if(s == "CUBE")
return CUBE;
else if(s == "SIGMOID")
return SIGMOID;
else if(s == "TANH")
return TANH;
else if(s == "SOFTMAX")
return SOFTMAX;
else if(s == "SPARSEMAX")
return SPARSEMAX;
else
{
fprintf(stderr, "ERROR (%s) : invalid activation \'%s\'. Aborting\n",ERRINFO, s.c_str());
exit(1);
}
return LINEAR;
}
NeuralNetwork::Layer::Layer(int input_dim, int output_dim,
float dropout_rate, Activation activation)
{
this->input_dim = input_dim;
this->output_dim = output_dim;
this->dropout_rate = dropout_rate;
this->activation = activation;
}
dynet::Expression NeuralNetwork::activate(dynet::Expression h, Activation f)
{
switch(f)
{
case LINEAR :
return h;
break;
case RELU :
return rectify(h);
break;
case ELU :
return elu(h);
break;
case SIGMOID :
return logistic(h);
break;
case TANH :
return tanh(h);
break;
case SOFTMAX :
return softmax(h);
break;
default :
break;
}
fprintf(stderr, "ERROR (%s) : Activation not implemented \'%s\'. Aborting.\n", ERRINFO, activation2str(f).c_str());
exit(1);
return h;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment