// Copyright (C) 2001 Jean-Marc Valin #include "TrainingAlgo.h" #include "FFNet.h" #include #include "Vector.h" using namespace std; namespace FD { //@require FFNet //@implements FFNetTrain void TrainingDeltaBarDelta::train(FFNet *net, vector tin, vector tout, int iter, float learnRate, float increase, float decrease, int nbSets, bool rprop) { int i,j; double SSE; int k=1; int nbWeights = 0; cerr << "training\n"; const float *weights = net->getWeights(); const Vector > &layers=net->getLayers(); const Vector &topo = net->getTopo(); for (i=0;igetNbWeights(); } cerr << "found " << nbWeights << " weights\n"; Array alpha(nbWeights); Array wk(nbWeights); Array nextW(nbWeights); Array dEk(nbWeights); Array nextdE(nbWeights); Array tmpdE(nbWeights); double nextE; double tmpE; vec_copy(weights, &wk[0], nbWeights); for (i=0;icalcGradient(tin, tout, wk, dEk, SSE); while (iter--) { //float norm = dEk.norm(); float norm_1 = 1; if (!rprop) norm_1 = 1.0/tin.size();// / norm; if (rprop) { for (i=0;i0) dEk[i] = 1; else if (dEk[i]<0) dEk[i] = -1; else dEk[i] = 0; } } if (nbSets ==1) { for (i=0;icalcGradient(tin, tout, nextW, nextdE, nextE); } else { for (i=0;i remaining(tin.size()); for (i=0;i batchIn; vector batchOut; for (i=0;icalcGradient(batchIn, batchOut, nextW, tmpdE, tmpE); nextE+=tmpE; for (j=0;j SSE) { alpha *= decrease; //So that the "bad" iteration doesn't count iter++; cerr << "backing off\n"; /*for (i=0;i= 0) alpha[i] *= increase; else alpha[i] *= decrease; if (alpha[i] < 1e-58) alpha[i] = 1e-58; } //if (SSE/tin.size()/topo[topo.size()-1]<.08) break; cout << (SSE/tin.size()/topo[topo.size()-1]) << "\t" << tin.size() << endl; SSE=nextE; dEk = nextdE; wk = nextW; } net->setWeights(&wk[0]); //vec_copy(&wk[0], net->weights, nbWeights); } void TrainingSCG::train(FFNet *net, vector tin, vector tout, int iter, float sigma, float lambda) { int i,j; double SSE; int k=1; float lambda_init = lambda; float lambdaBar = 0; float sigmak; bool success = true; int nbWeights = 0; const float *weights = net->getWeights(); const Vector > &layers=net->getLayers(); const Vector &topo = net->getTopo(); for (i=0;igetNbWeights(); } cerr << "WARNING: This is still experimental" << endl; cerr << "found " << nbWeights << " weights\n"; Array pk(nbWeights); Array rk(nbWeights); Array sk(nbWeights); Array wk(nbWeights); Array dEk(nbWeights); Array dEp(nbWeights); Array nextdE(nbWeights); Array tmp(nbWeights); double nextE; float deltak; vec_copy(weights, &wk[0], nbWeights); net->calcGradient(tin, tout, wk, tmp, SSE); for (int i=0;icalcGradient(tin, tout, wk+pk*sigmak, tmp, dummy); for (int i=0;icalcGradient(tin, tout, wk+pk*ak, tmp, nextE); for (int i=0;i= 0) { wk += pk*ak; Array oldR = rk; SSE=nextE; rk = -nextdE; lambdaBar = 0; success = true; cout << SSE/tin.size()/topo[topo.size()-1] << "\t" << DK << "\t" << lambda << "\t" << norm << "\t" << ak << "\t" << endl; if (k%nbWeights == 0) { pk = rk; k++; lambda = lambda_init; lambdaBar = 0; cerr << "restarting\n"; continue; } else { float bk = (rk.norm2() - rk*oldR)/uk; pk = rk + pk * bk; } if (DK >= .75 && lambda > 1e-100) lambda *= .5; k++; } else { lambdaBar = lambda; success = false; } //8. increase scale if (DK < .25 && lambda < 1e200) lambda *= 4; //9. Have we found the minimum if (rk.norm() == 0) break; //k++; } net->setWeights(&wk[0]); } void TrainingQProp::train(FFNet *net, vector tin, vector tout, int iter, float learnRate) { int i,j; double SSE; int k=1; float increase=1.04; float decrease = .6; int nbWeights = 0; const float *weights = net->getWeights(); const Vector > &layers=net->getLayers(); const Vector &topo = net->getTopo(); for (i=0;igetNbWeights(); } cerr << "WARNING: This implementation of Quickprop doesn't work yet!" << endl; cerr << "found " << nbWeights << " weights\n"; //Array alpha(nbWeights); Array wk(nbWeights); Array nextW(nbWeights); Array dW(nbWeights,0); // Array dWq(nbWeights,0); Array prevdW(nbWeights,0); Array dE(nbWeights,0); Array nextdE(nbWeights,0); Array prevdE(nbWeights,0); //Array nextdE(nbWeights); double nextE; vec_copy(weights, &wk[0], nbWeights); //for (i=0;icalcGradient(tin, tout, wk, dE, SSE); while (iter--) { for (i=0;i 1e-8) dW[i] = -(dE[i]*prevdW[i])/norm; else dW[i] = 0; if ((dE[i]*prevdE[i]) <= 0) dW[i]-= learnRate*dE[i]; } for (i=0;icalcGradient(tin, tout, nextW, nextdE, nextE); while(nextE > SSE) { float alpha = learnRate; for (i=0;icalcGradient(tin, tout, nextW, nextdE, nextE); alpha *= .5; } //if (SSE/tin.size()/topo[topo.size()-1]<.08) break; cout << (SSE/tin.size()/topo[topo.size()-1]) << "\t" << tin.size() << endl; prevdW=dW; prevdE=dE; SSE=nextE; dE = nextdE; wk = nextW; //nextdE = dE; } net->setWeights(&wk[0]); //vec_copy(&wk[0], weights, nbWeights); } void TrainingWeightDeltaBarDelta::train(FFNet *net, vector tin, vector tout, vector learnWeights, int iter, float learnRate, float increase, float decrease) { int i,j; double SSE; int k=1; int nbWeights = 0; const float *weights = net->getWeights(); const Vector > &layers=net->getLayers(); const Vector &topo = net->getTopo(); for (i=0;igetNbWeights(); } cerr << "found " << nbWeights << " weights\n"; Array alpha(nbWeights); Array wk(nbWeights); Array nextW(nbWeights); Array dEk(nbWeights); Array nextdE(nbWeights); double nextE; vec_copy(weights, &wk[0], nbWeights); for (i=0;iweightedCalcGradient(tin, tout, learnWeights, wk, dEk, SSE); while (iter--) { float norm = dEk.norm(); float norm_1 = 1;// / norm; for (i=0;iweightedCalcGradient(tin, tout, learnWeights, nextW, nextdE, nextE); if (nextE > SSE) { alpha *= decrease; //So that the "bad" iteration doesn't count iter++; cerr << "backing off\n"; continue; } for (i=0;i= 0) alpha[i] *= increase; else alpha[i] *= decrease; if (alpha[i] < 1e-58) alpha[i] = 1e-58; } //if (SSE/tin.size()/topo[topo.size()-1]<.08) break; cout << (SSE/tin.size()/topo[topo.size()-1]) << "\t" << tin.size() << endl; SSE=nextE; dEk = nextdE; wk = nextW; } net->setWeights(&wk[0]); //vec_copy(&wk[0], net->weights, nbWeights); } }//namespace FD