21 #include "matrixlinker.h"
23 #include "backpropagationalgo.h"
50 cluster_deltas_vec.clear();
55 for(
int i=0; i<(int)outs.size(); i++ ) {
56 addCluster( outs[i],
true );
59 for(
int i=0; i<(int)update_order.size(); i++ ) {
60 cluster_temp =
dynamic_cast<Cluster*
>(update_order[i]);
62 addCluster( cluster_temp,
false );
67 addLinker( linker_temp );
73 this->update_order = update_order;
78 if ( mapIndex.count( output ) == 0 ) {
81 int index = mapIndex[ output ];
82 cluster_deltas_vec[index].deltas_outputs = output->
outputs() - ti;
87 if ( mapIndex.count( cl ) == 0 ) {
88 qWarning() <<
"Cluster not present in BackPropagationAlgo";
89 return DoubleVector();
91 int index = mapIndex[ cl ];
92 return cluster_deltas_vec[index].deltas_outputs;
96 for (
int i=0; i<cluster_deltas_vec.size(); ++i ) {
97 for (
int j=0; j<cluster_deltas_vec[i].incoming_linkers_vec.size(); ++j ) {
99 cluster_deltas_vec[i].incoming_last_outputs[j].setZero();
100 cluster_deltas_vec[i].last_deltas_inputs.setZero();
106 void BackPropagationAlgo::propagDeltas() {
107 DoubleVector diff_vec;
108 for(
int i=0; i<(int)cluster_deltas_vec.size(); i++ ) {
109 cluster_deltas_vec[i].incoming_linkers_vec;
111 cluster_deltas_vec[i].deltas_inputs = cluster_deltas_vec[i].deltas_outputs;
112 Cluster* cl = cluster_deltas_vec[i].cluster;
114 diff_vec.resize( cluster_deltas_vec[i].deltas_inputs.size() );
116 cluster_deltas_vec[i].deltas_inputs = cluster_deltas_vec[i].deltas_inputs.cwiseProduct(diff_vec);
119 for(
int k=0; k<cluster_deltas_vec[i].incoming_linkers_vec.size( ); ++k ) {
120 MatrixLinker* link =
dynamic_cast<MatrixLinker*
>(cluster_deltas_vec[i].incoming_linkers_vec[k]);
121 if ( mapIndex.count(link->from()) == 0 ) {
125 int from_index = mapIndex[ link->from() ];
126 cluster_deltas_vec[from_index].deltas_outputs = link->matrix()*cluster_deltas_vec[i].deltas_inputs;
134 for (
int i=0; i<cluster_deltas_vec.size(); ++i ) {
135 if ( cluster_deltas_vec[i].isOutput )
continue;
136 cluster_deltas_vec[i].deltas_outputs.setZero();
141 for (
int i=0; i<cluster_deltas_vec.size(); ++i ) {
142 if ( cluster_deltas_vec[i].cluster != NULL) {
143 for(
unsigned int b=0; b<cluster_deltas_vec[i].cluster->numNeurons(); b++ ) {
144 cluster_deltas_vec[i].cluster->biases()[b] += -learn_rate*-cluster_deltas_vec[i].deltas_inputs[b];
148 for (
int j=0; j<cluster_deltas_vec[i].incoming_linkers_vec.size(); ++j ) {
149 if ( cluster_deltas_vec[i].incoming_linkers_vec[j] != NULL ) {
150 DoubleVector& outputs = cluster_deltas_vec[i].incoming_linkers_vec[j]->from()->outputs();
151 DoubleVector& inputs = cluster_deltas_vec[i].deltas_inputs;
152 DoubleMatrix& matrix = cluster_deltas_vec[i].incoming_linkers_vec[j]->matrix();
153 for (
int r=0; r<outputs.size(); r++ ) {
154 for (
int c=0; c<inputs.size(); c++ ) {
155 matrix(r,c) += -learn_rate * outputs[r] * inputs[c];
158 if ( !useMomentum )
continue;
160 outputs = cluster_deltas_vec[i].incoming_last_outputs[j];
161 inputs = cluster_deltas_vec[i].last_deltas_inputs;
162 matrix = cluster_deltas_vec[i].incoming_linkers_vec[j]->matrix();
163 for (
int r=0; r<outputs.size(); r++ ) {
164 for (
int c=0; c<inputs.size(); c++ ) {
165 matrix(r,c) += -learn_rate*momentumv * outputs[r] * inputs[c];
169 cluster_deltas_vec[i].incoming_last_outputs[j] = cluster_deltas_vec[i].incoming_linkers_vec[j]->from()->outputs();
170 cluster_deltas_vec[i].last_deltas_inputs = cluster_deltas_vec[i].deltas_inputs;
180 for(
int i=0; i<clins.size(); i++ ) {
181 clins[i]->inputs() = pat.
inputsOf( clins[i] );
187 for(
int i=0; i<clout.size(); i++ ) {
196 for(
int i=0; i<clins.size(); i++ ) {
197 clins[i]->inputs() = pat.
inputsOf( clins[i] );
204 int dim = (int)clout.size();
205 for(
int i=0; i<dim; i++ ) {
206 DoubleVector diff = clout[i]->outputs()-pat.
outputsOf( clout[i] );
207 mseacc += diff.dot(diff)/diff.size();
212 void BackPropagationAlgo::addCluster(
Cluster* cl,
bool isOut ) {
213 if( mapIndex.count( cl ) == 0 ) {
217 temp.isOutput = isOut;
218 temp.deltas_outputs.resize( size );
219 temp.deltas_inputs.resize( size );
220 temp.last_deltas_inputs.resize( size );
221 cluster_deltas_vec.push_back( temp );
222 mapIndex[cl] = cluster_deltas_vec.size()-1;
226 void BackPropagationAlgo::addLinker( Linker* link ) {
227 if ( mapIndex.count( link->to() ) == 0 ) {
229 int size = link->to()->numNeurons();
230 temp.cluster =
dynamic_cast<BiasedCluster*
>(link->to());
231 temp.isOutput =
false;
232 temp.deltas_outputs.resize( size );
233 temp.deltas_inputs.resize( size );
234 temp.last_deltas_inputs.resize( size );
235 temp.incoming_linkers_vec.push_back( dynamic_cast<MatrixLinker*>(link) );
236 temp.incoming_last_outputs.push_back( DoubleVector( link->from()->numNeurons() ) );
237 cluster_deltas_vec.push_back( temp );
238 mapIndex[temp.cluster] = cluster_deltas_vec.size()-1;
241 int tmp = mapIndex[link->to()];
242 cluster_deltas_vec[ tmp ].incoming_linkers_vec.push_back( dynamic_cast<MatrixLinker*>(link) );
243 cluster_deltas_vec[ tmp ].incoming_last_outputs.push_back( DoubleVector( link->from()->numNeurons() ) );
249 learn_rate = params.
getValue( prefix +
"rate" ).toDouble();
250 momentumv = params.
getValue( prefix +
"momentum" ).toDouble();
251 if ( momentumv == 0.0 ) {
256 QString str = params.
getValue( prefix +
"order" );
257 update_order.clear();
258 if ( !str.isEmpty() ) {
259 QStringList list = str.split(QRegExp(
"\\s+"), QString::SkipEmptyParts);
260 foreach( QString upl, list ) {
275 params.
createParameter( prefix,
"momentum", QString::number(momentumv) );
288 d.describeObject(
"neuralnet" ).type(
"NeuralNet" ).props(
IsMandatory ).help(
"The neural network to learn by backpropagation" );
289 d.describeReal(
"rate" ).limits( 0.0, 1.0 ).def( 0.2 ).help(
"The learning rate" );
290 d.describeReal(
"momentum" ).limits( 0.0, 1.0 ).help(
"The momentum rate; if zero momentum will be disabled" );
void stopRememberingGroupObjectAssociations()
TypeToCreate * getObjectFromParameter(QString param, bool alsoMatchParents=false, bool configure=true, bool forceObjectCreation=false)
void enableMomentum()
Enable the momentum.
~BackPropagationAlgo()
Destructor.
const DoubleVector & outputsOf(Cluster *) const
return stored information if exists, otherwise it return a zero vector
virtual double calculateMSE(const Pattern &)
Calculate the Mean Square Error respect to Pattern passed.
virtual void learn()
a single step of learning algorithm
void setTeachingInput(Cluster *output, const DoubleVector &ti)
Set the teaching input for Cluster passed.
In a BiasedCluster each neuron has an input, an output and a bias value.
virtual void save(ConfigurationParameters ¶ms, QString prefix)
Save the actual status of parameters into the ConfigurationParameters object passed.
BackPropagationAlgo()
Default Constructor.
virtual void save(ConfigurationParameters ¶ms, QString prefix)
Save the actual status of parameters into the ConfigurationParameters object passed.
DoubleVector & inputs()
Get the array of inputs.
const DoubleVector & inputsOf(Cluster *) const
return stored information if exists, otherwise it return a zero vector
ClusterList outputClusters() const
Returns the vector of Output Clusters contained.
virtual void neuralNetChanged()
Configure internal data for backpropagation on NeuralNet setted.
virtual void configure(ConfigurationParameters ¶ms, QString prefix)
Configures the object using a ConfigurationParameters object.
MatrixLinker Class define a full connection between two cluster.
void setUpdateOrder(const UpdatableList &update_order)
Set the order on which the error is backpropagated through the NeuralNet.
Define the common interface among Clusters.
static void describe(QString type)
Add to Factory::typeDescriptions() the descriptions of all parameters and subgroups.
void setNeuralNet(NeuralNet *net)
Set the NeuralNet to learn.
bool startObjectParameters(QString groupPath, QString typeName, ParameterSettable *object)
LearningAlgorithm object.
NeuralNet * neuralNet()
Return the NeuralNet setted.
The Neural Network Class.
static Descriptor addTypeDescription(QString type, QString shortHelp, QString longHelp=QString(""))
QString getValue(QString path, bool alsoMatchParents=false) const
OutputFunction * outFunction() const
Get the Output function.
TypeToCreate * getObjectFromGroup(QString group, bool configure=true, bool forceObjectCreation=false)
DoubleVector & outputs()
Get the array of outputs.
virtual bool derivate(const DoubleVector &inputs, const DoubleVector &outputs, DoubleVector &derivates) const
Compute the derivate of the function represent Given the input of neurons and the corresponding outp...
DoubleVector getError(Cluster *)
This method returns the deltas calculated by the Back-propagation Algorithm.
ClusterList inputClusters() const
Returns the vector of Input Clusters contained.
void startRememberingGroupObjectAssociations()
QString name() const
Return its name.
unsigned int numNeurons() const
Return the number of neurons (the length of input and output arrays)
void createParameter(QString groupPath, QString parameter)
This file contains the declaration of Neural Network Class.
This file contains the declaration of BiasedCluster class.