Robotsystem from Robot Group Leipzig: multilayerffnn.cpp Source File

- Main Page
- Modules
- Namespaces
- Classes
- Files
- Directories
- Examples

- File List
- File Members

# 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 }