00001 #ifndef _FEEDFORWARDNN_H
00002 #define _FEEDFORWARDNN_H
00003
00004 #include "../Controller.h"
00005 #include "../../utils/Matrix.h"
00006 #include "../GenotypeDecoder.h"
00007 #include <valarray>
00008 #include <vector>
00009 #include <ishtar/settings.h>
00010
00015 namespace Teem
00016 {
00020 class FeedForwardNeuralNetwork : public Controller
00021 {
00022 public:
00024 FeedForwardNeuralNetwork(size_t inputCount, size_t outputCount, const std::string &root);
00026 virtual ~FeedForwardNeuralNetwork() { }
00027
00028
00030 virtual void setInput(unsigned index, double val);
00032 virtual double getInput(unsigned index) const { assert(index < inputCount); return input[index]; }
00034 virtual unsigned getInputCount() const { return inputCount; }
00036 virtual double getOutput(unsigned index);
00038 virtual void step();
00039
00041 size_t layerNum() { return layerCount; }
00043 size_t layerSize(size_t layer) { return layerSizes[layer]; }
00045 size_t inputNum() { return inputCount; }
00047 size_t outputNum() { return outputCount; }
00048
00051 void setWeight(size_t toLayer, size_t from, size_t to, double w) { weights[toLayer](from, to) = w; }
00053 double getWeight(size_t toLayer, size_t from, size_t to) const { return weights[toLayer](from, to); }
00054
00056 void setBiasWeight(size_t toLayer, size_t to, double w) { biasWeights[toLayer][to] = w; }
00058 double getBiasWeight(size_t toLayer, size_t to) const { return biasWeights[toLayer][to]; }
00059
00061 virtual void randomize(double from, double to);
00062
00063 protected:
00064
00069 typedef double (*ActivationFunction)(double x, double b);
00070
00071 class ActivationFunctor;
00072
00073 size_t inputCount;
00074 size_t outputCount;
00075 size_t layerCount;
00076 Ishtar::Variable<unsigned> hiddenLayerCount;
00077 std::vector<size_t> layerSizes;
00078 Ishtar::Variable<double> biasValue;
00079 Ishtar::Variable<std::string> activationFunction;
00080 Ishtar::Variable<double> activationFunctionParameter;
00081
00082 std::vector<Matrix<double> > weights;
00083 std::vector<std::valarray<double> > biasWeights;
00084 std::vector<std::valarray<double> > activations;
00085 std::vector<std::valarray<double> > outputs;
00086 std::valarray<double> input;
00087 ActivationFunction forwardActFunc;
00088
00090 static double TanhForwardActivationFunction(double x, double b)
00091 {
00092 return tanh(x * b);
00093 }
00094 };
00095
00098 class FeedForwardNeuralNetwork::ActivationFunctor
00099 {
00100 protected:
00101 ActivationFunction function;
00102 double b;
00103 std::valarray<double>& result;
00104 size_t pos;
00105
00106 public:
00108 ActivationFunctor(ActivationFunction func, std::valarray<double> &res, double b)
00109 : result(res)
00110 {
00111 this->function = func;
00112 this->pos = 0;
00113 this->b = b;
00114 }
00115
00117 void operator()(double x)
00118 {
00119 result[pos++] = function(x, b);
00120 }
00121 };
00122
00123
00125 class RecurrentFeedForwardNeuralNetwork : public FeedForwardNeuralNetwork
00126 {
00127 public:
00129 RecurrentFeedForwardNeuralNetwork(size_t inputCount, size_t outputCount, const std::string &root);
00131 virtual ~RecurrentFeedForwardNeuralNetwork() { }
00132
00134 virtual void step();
00136 virtual void randomize(double from, double to);
00137
00139 void setRecursiveWeight(size_t layer, size_t from, size_t to, double w) { recursiveWeights[layer](from, to) = w; }
00141 double getRecursiveWeight(size_t layer, size_t from, size_t to) const { return recursiveWeights[layer](from, to); }
00143 bool isLayerRecursive(size_t layer) { return layerRecursive[layer]; }
00144
00145 protected:
00146
00147 Ishtar::Variable<bool> outputLayerRecursive;
00148 std::vector<Matrix<double> > recursiveWeights;
00149 std::vector<bool> layerRecursive;
00150 };
00151
00152
00166 class BackPropFeedForwardNeuralNetwork : public FeedForwardNeuralNetwork
00167 {
00168 public:
00170 BackPropFeedForwardNeuralNetwork(size_t inputCount, size_t outputCount, const std::string &root);
00172 virtual ~BackPropFeedForwardNeuralNetwork() { }
00173
00175 virtual void stepBackward();
00176
00178 void setError(size_t index, double val)
00179 {
00180 assert(index < error.size());
00181 error[index] = val;
00182 }
00183
00185 void setLearningRate(double rate) { learningRate = rate; }
00187 double getLearningRate() { return learningRate; }
00188
00189 protected:
00190
00191 Ishtar::Variable<double> learningRate;
00192 std::valarray<double> error;
00193 ActivationFunction backwardActFunc;
00194 std::vector<std::valarray<double> > deltas;
00195
00197 static double TanhBackwardActivationFunction(double x, double b)
00198 {
00199 double t = tanh(x * b);
00200 return b * (1.0 - t * t);
00201 }
00202 };
00203
00204
00210 class FeedForwardNeuralNetworkGenotypeDecoder : public GenotypeDecoder
00211 {
00212 public:
00214 FeedForwardNeuralNetworkGenotypeDecoder(const std::string &root);
00216 virtual ~FeedForwardNeuralNetworkGenotypeDecoder() { }
00217
00219 virtual Genome* createGenome();
00220
00222 virtual Controller* decode(Genome *genome);
00223
00224 protected:
00225
00226 Ishtar::Variable<unsigned> hiddenLayerCount;
00227 std::vector<size_t> hiddenLayerSizes;
00228 Ishtar::Variable<bool> useBackProp;
00229 Ishtar::Variable<bool> useRecursion;
00230 Ishtar::Variable<double> weightRange;
00231 std::vector<bool> layerRecursive;
00232 };
00233 }
00234
00235 #endif