multilayerffnn.cpp

Go to the documentation of this file.
00001 
00002 #include "multilayerffnn.h"
00003 #include "controller_misc.h"
00004 
00005 using namespace matrix;
00006 using namespace std;
00007 
00008 /// initialisation of the network with the given number of input and output units
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; // adjust output dimension
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 /// passive processing of the input
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 /// performs learning and returns the network output before learning
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   // calculate outputs (y's) and activations (z's), which are necessary for activation'()
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   // calculate weight updates
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){ // all but first layer
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{ // first layer sees real input (linear)
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 }

Generated on Tue Apr 4 19:05:03 2006 for Robotsystem from Robot Group Leipzig by  doxygen 1.4.5