00001
00002 #include "multilayerffnn.h"
00003 #include "controller_misc.h"
00004
00005 using namespace matrix;
00006 using namespace std;
00007
00008
00009 void MultiLayerFFNN::init(unsigned int inputDim, unsigned int outputDim) {
00010 assert(!initialised && layers.size() > 0);
00011 int last = layers.size() - 1;
00012 layers[last].size = outputDim;
00013
00014 Matrix w(layers[0].size, inputDim);
00015 w+=w.map(random_minusone_to_one) * 0.05;
00016 weights.push_back(w);
00017 bias.push_back(Matrix(layers[0].size, 1));
00018 for(unsigned int i = 1; i < layers.size(); i++) {
00019 Matrix w(layers[i].size, layers[i-1].size);
00020 w+=w.map(random_minusone_to_one) * 0.05;
00021 weights.push_back(w);
00022 bias.push_back(Matrix(layers[i].size, 1));
00023 }
00024
00025 initialised = true;
00026 }
00027
00028
00029 const Matrix MultiLayerFFNN::process (const Matrix& input) const {
00030 assert(initialised);
00031 assert(weights.size() == layers.size());
00032 assert(bias.size() == layers.size());
00033
00034 Matrix y = (weights[0] * input + bias[0]).map(layers[0].actfun);
00035 for(unsigned int i = 1; i < layers.size(); i++) {
00036 y = (weights[i] * y + bias[i]).map(layers[i].actfun);
00037 }
00038 return y;
00039 }
00040
00041
00042 const Matrix MultiLayerFFNN::learn (const Matrix& input,
00043 const Matrix& nom_output,
00044 double learnRateFactor) {
00045 assert(initialised);
00046 assert(initialised);
00047 assert(weights.size() == layers.size());
00048 assert(bias.size() == layers.size());
00049
00050 int layernum = layers.size();
00051 double epsilon = eps*learnRateFactor;
00052
00053
00054 vector<Matrix> ys;
00055 vector<Matrix> zs;
00056 ys.resize(layernum);
00057 zs.resize(layernum);
00058 zs[0] = weights[0] * input + bias[0];
00059 ys[0] = zs[0].map(layers[0].actfun);
00060 for(int i = 1; i < layernum; i++) {
00061 zs[i] = weights[i] * ys[i-1] + bias[i];
00062 ys[i] = zs[i].map(layers[i].actfun);
00063 }
00064
00065
00066 Matrix delta;
00067 for( int i = layernum-1; i >= 0; i--) {
00068 const Matrix& xsi = ( i == layernum-1 )
00069 ? nom_output - ys[layernum-1]
00070 : (weights[i+1]^T) * delta;
00071
00072 if(i!=0){
00073 const Matrix& g_prime = zs[i].map(layers[i].dactfun);
00074 delta = xsi.multrowwise(g_prime);
00075 weights[i] += delta * (ys[i-1]^T) * epsilon;
00076 bias[i] += delta * epsilon * layers[i].factor_bias;
00077 }else{
00078 weights[i] += xsi * (input^T) * epsilon;
00079 bias[i] += xsi * epsilon * layers[i].factor_bias;
00080 }
00081 }
00082
00083 return ys[layernum-1];
00084 }
00085
00086 void MultiLayerFFNN::damp(double damping){
00087 unsigned int len = weights.size();
00088 for(unsigned int i = 0; i < len; i++) {
00089 weights[i] *= (1-damping);
00090 bias[i] *= (1-damping);
00091 }
00092 }