/////////////////////////////////////////////////////////////// // // // nnet.cpp - model neural network // // // // version: 1.0 // // Language: Visual C++, ver 5.0 // // Platform: Micron Dual Pentium Pro 200 // // Windows NT 4.0, service pack 3 // // Application: ELE591/791 Example // // Author: Jim Fawcett // // CST 2-187, (315) 443-3948 // // fawcett@neptune.syr.edu // // // /////////////////////////////////////////////////////////////// #include #include #include #include #include "bneuron.h" #include "layer.h" #include "nnet.h" using namespace std; //----< construction from layers >----------------------------- nnet::nnet(layer &hidden, layer &output) : _hidden(hidden), _output(output) { } //----< compute network outputs >------------------------------ void nnet::outputs(const vec &vin, vec &vout) { // create temporary vector storage once and reuse static vec tempOut(_hidden.size()); static vec tempIn(_hidden.size()+1); // evaluate hidden later outputs _hidden.outputs(vin,tempOut); // evaluate output layer outputs // - input vector has bias plus one elem for each hidden neuron tempIn[0] = 1; // bias int i; for(i=0; i------------------ void nnet::randWts(double min, double max, bool newSeed) { _hidden.randWts(min,max,newSeed); _output.randWts(min,max,newSeed); } //----< update weights via backpropagation >------------------- void nnet::updateWts(vec &error) { const double eta = -0.25; // output layer weights int k; // output node index for(k=0; k<_output.size(); k++) { _output[k].weights() += (eta*error[k]*_output[k].outDeriv())*(_output[k].inputs()); } // hidden layer weights int j; // hidden node index for(j=0; j<_hidden.size(); j++) { double sum = 0; for(k=0; k<_output.size(); k++) { sum += (error[k]*_output[k].outDeriv())* (_output[k].weight(j) ); } _hidden[j].weights() += (eta*sum*_hidden[j].outDeriv())*(_hidden[j].inputs()); } } //----< send norms of weights to log file >-------------------- void nnet::logWts(ostream &outLog, ostream &hidLog) { int i; outLog << "--output norms: "; for(i=0; i<_output.size(); i++) outLog << setw(12) << _output[0].weights().norm(); outLog << endl; hidLog << "--hidden norms: "; for(i=0; i<_hidden.size(); i++) hidLog << setw(12) << _hidden[i].weights().norm(); hidLog << endl; } // //----< test stub >-------------------------------------------- #ifdef TEST_NNET void main() { cout << " Testing Neural Network (1:5:1): \n" << " ================================ \n\n"; // build layer with 5 nodes each having 2 inputs sneuron sn(2); layer hlayer(sn,5); hlayer.randWts(-0.2,0.2,true); lneuron ln(6); layer olayer(ln,1); olayer.randWts(-0.2,0.2,true); nnet test(hlayer,olayer); vec input(2); input[0] = 1; // bias input[1] = 2; // from previous layer vec output(1); vec error(1); int i; for(i=0; i<20; i++) { test.outputs(input,output); error[0] = output[0] - input[1]; cout << "--Error: " << setw(12) << error[0] << '\n'; test.updateWts(error); test.logWts(cout,cout); } cout << "\n Output vector is:"; output.display(cout); cout << endl; } #endif