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) );
290 d.
describeReal(
"momentum" ).
limits( 0.0, 1.0 ).
help(
"The momentum rate; if zero momentum will be disabled" );