92.

c++ neural networks and fuzzy logic C++ Neural Networks and Fuzzy Logic
by Valluru B. Rao
M&T Books, IDG Books Worldwide, Inc.
ISBN: 1558515526   Pub Date: 06/01/95
  

Previous Table of Contents Next


Listing 13.2 Layer.cpp file updated to include noise and momentum

 // layer.cpp          V.Rao, H.Rao // added momentum and noise // compile for floating point hardware if available #include <stdio.h> #include <iostream.h> #include <stdlib.h> #include <math.h> #include <time.h> #include "layer.h" inline float squash(float input) // squashing function // use sigmoid — can customize to something // else if desired; can add a bias term too // { if (input < -50)        return 0.0; else   if (input > 50)               return 1.0;        else return (float)(1/(1+exp(-(double)input))); } inline float randomweight(unsigned init) { int num; // random number generator // will return a floating point // value between -1 and 1 if (init==1)  // seed the generator        srand ((unsigned)time(NULL)); num=rand() % 100; return 2*(float(num/100.00))-1; } // the next function is needed for Turbo C++ // and Borland C++ to link in the appropriate // functions for fscanf floating point formats: static void force_fpf() {        float x, *y;        y=&x;        x=*y; } // --------------------- //                            input layer //--------------------- input_layer::input_layer(int i, int o) { num_inputs=i; num_outputs=o; outputs = new float[num_outputs]; orig_outputs = new float[num_outputs]; if ((outputs==0)||(orig_outputs==0))         {         cout << "not enough memory\n";         cout << "choose a smaller architecture\n";         exit(1);         } noise_factor=0; } input_layer::~input_layer() { delete [num_outputs] outputs; delete [num_outputs] orig_outputs; } void input_layer::calc_out() { //add noise to inputs // randomweight returns a random number // between -1 and 1 int i; for (i=0; i<num_outputs; i++)        outputs[i] =orig_outputs[i]*               (1+noise_factor*randomweight(0)); } void input_layer::set_NF(float noise_fact) { noise_factor=noise_fact; } // --------------------- //                            output layer //--------------------- output_layer::output_layer(int ins, int outs) { int i, j, k; num_inputs=ins; num_outputs=outs; weights = new float[num_inputs*num_outputs]; output_errors = new float[num_outputs]; back_errors = new float[num_inputs]; outputs = new float[num_outputs]; expected_values = new float[num_outputs]; cum_deltas = new float[num_inputs*num_outputs]; past_deltas = new float[num_inputs*num_outputs]; if ((weights==0)||(output_errors==0)||(back_errors==0)        ||(outputs==0)||(expected_values==0)        ||(past_deltas==0)||(cum_deltas==0))        {        cout << "not enough memory\n";        cout << "choose a smaller architecture\n";        exit(1);        } // zero cum_deltas and past_deltas matrix for (i=0; i< num_inputs; i++)        {        k=i*num_outputs;        for (j=0; j< num_outputs; j++)               {               cum_deltas[k+j]=0;               past_deltas[k+j]=0;               }        } } output_layer::~output_layer() { // some compilers may require the array // size in the delete statement; those // conforming to Ansi C++ will not delete [num_outputs*num_inputs] weights; delete [num_outputs] output_errors; delete [num_inputs] back_errors; delete [num_outputs] outputs; delete [num_outputs*num_inputs] past_deltas; delete [num_outputs*num_inputs] cum_deltas; } void output_layer::calc_out() { int i,j,k; float accumulator=0.0; for (j=0; j<num_outputs; j++)        {        for (i=0; i<num_inputs; i++)               {               k=i*num_outputs;               if (weights[k+j]*weights[k+j] > 1000000.0)                      {                       cout << "weights are blowing up\n";                       cout << "try a smaller learning constant\n";                       cout << "e.g. beta=0.02    aborting...\n";                       exit(1);                      }               outputs[j]=weights[k+j]*(*(inputs+i));               accumulator+=outputs[j];               }        // use the sigmoid squash function        outputs[j]=squash(accumulator);        accumulator=0;        } } void output_layer::calc_error(float & error) { int i, j, k; float accumulator=0; float total_error=0; for (j=0; j<num_outputs; j++)     {                   output_errors[j] = expected_values[j]-outputs[j];                   total_error+=output_errors[j];                   } error=total_error; for (i=0; i<num_inputs; i++) { k=i*num_outputs; for (j=0; j<num_outputs; j++)        {                back_errors[i]=                       weights[k+j]*output_errors[j];                accumulator+=back_errors[i];                }        back_errors[i]=accumulator;        accumulator=0;        // now multiply by derivative of        // sigmoid squashing function, which is        // just the input*(1-input)        back_errors[i]*=(*(inputs+i))*(1-(*(inputs+i)));        } } void output_layer::randomize_weights() { int i, j, k; const unsigned first_time=1; const unsigned not_first_time=0; float discard; discard=randomweight(first_time); for (i=0; i< num_inputs; i++)        {        k=i*num_outputs;        for (j=0; j< num_outputs; j++)               weights[k+j]=randomweight(not_first_time);        } } void output_layer::update_weights(const float beta,                                      const float alpha) { int i, j, k; float delta; // learning law: weight_change = //             beta*output_error*input + alpha*past_delta for (i=0; i< num_inputs; i++)        {        k=i*num_outputs;        for (j=0; j< num_outputs; j++)               {               delta=beta*output_errors[j]*(*(inputs+i))                      +alpha*past_deltas[k+j];               weights[k+j] += delta;               cum_deltas[k+j]+=delta; // current cycle               }        } } void output_layer::update_momentum() { // This function is called when a // new cycle begins; the past_deltas // pointer is swapped with the // cum_deltas pointer. Then the contents // pointed to by the cum_deltas pointer // is zeroed out. int i, j, k; float * temp; // swap temp = past_deltas; past_deltas=cum_deltas; cum_deltas=temp; // zero cum_deltas matrix // for new cycle for (i=0; i< num_inputs; i++)        {        k=i*num_outputs;        for (j=0; j< num_outputs; j++)               cum_deltas[k+j]=0;        } } void output_layer::list_weights() { int i, j, k; for (i=0; i< num_inputs; i++)        {        k=i*num_outputs;        for (j=0; j< num_outputs; j++)               cout << "weight["<<i<<","<<                          j<<"] is: "<<weights[k+j];        } } void output_layer::list_errors() { int i, j; for (i=0; i< num_inputs; i++)        cout << "backerror["<<i<<                   "] is : "<<back_errors[i]<<"\n"; for (j=0; j< num_outputs; j++)        cout << "outputerrors["<<j<<                             "] is: "<<output_errors[j]<<"\n"; } void output_layer::write_weights(int layer_no,                FILE * weights_file_ptr) { int i, j, k; // assume file is already open and ready for // writing // prepend the layer_no to all lines of data // format: //             layer_no   weight[0,0] weight[0,1] ... //             layer_no   weight[1,0] weight[1,1] ... //             ... for (i=0; i< num_inputs; i++)        {        fprintf(weights_file_ptr,"%i ",layer_no);        k=i*num_outputs;     for (j=0; j< num_outputs; j++)        {        fprintf(weights_file_ptr,"%f ",                       weights[k+j]);        }     fprintf(weights_file_ptr,"\n");     } } void output_layer::read_weights(int layer_no,                FILE * weights_file_ptr) { int i, j, k; // assume file is already open and ready for // reading // look for the prepended layer_no // format: //             layer_no       weight[0,0] weight[0,1] ... //             layer_no       weight[1,0] weight[1,1] ... //             ... while (1)         {         fscanf(weights_file_ptr,"%i";,&j);         if ((j==layer_no)|| (feof(weights_file_ptr)))                break;         else                {                while (fgetc(weights_file_ptr) != `\n')                       {;}// get rest of line                }         } if (!(feof(weights_file_ptr)))         {         // continue getting first line         i=0;         for (j=0; j< num_outputs; j++)                           {                           fscanf(weights_file_ptr,"%f",                                          &weights[j]); // i*num_outputs                                                           = 0      }         fscanf(weights_file_ptr,"\n");         // now get the other lines         for (i=1; i< num_inputs; i++)                {                fscanf(weights_file_ptr,                ”%i”,&layer_no);         k=i*num_outputs;         for (j=0; j< num_outputs; j++)         {         fscanf(weights_file_ptr,”%f”,                &weights[k+j]);                }     }     fscanf(weights_file_ptr,”\n”);     } else cout << “end of file reached\n”; } void output_layer::list_outputs() { int j; for (j=0; j< num_outputs; j++)         {         cout << “outputs[“<<j                <<”] is: “<<outputs[j]<<”\n”;         } } // ————————————————————- //                           middle layer //————————————————————— middle_layer::middle_layer(int i, int o):         output_layer(i,o) { } middle_layer::~middle_layer() { delete [num_outputs*num_inputs] weights; delete [num_outputs] output_errors; delete [num_inputs] back_errors; delete [num_outputs] outputs; } void middle_layer::calc_error() { int i, j, k; float accumulator=0; for (i=0; i<num_inputs; i++)         {         k=i*num_outputs;         for (j=0; j<num_outputs; j++)                {                back_errors[i]=                       weights[k+j]*(*(output_errors+j));                accumulator+=back_errors[i];                }         back_errors[i]=accumulator;         accumulator=0;         // now multiply by derivative of         // sigmoid squashing function, which is         // just the input*(1-input)         back_errors[i]*=(*(inputs+i))*(1-(*(inputs+i)));         } } network::network() { position=0L; } network::~network() { int i,j,k; i=layer_ptr[0]->num_outputs;// inputs j=layer_ptr[number_of_layers-1]->num_outputs; //outputs k=MAX_VECTORS; delete [(i+j)*k]buffer; } void network::set_training(const unsigned & value) { training=value; } unsigned network::get_training_value() { return training; } void network::get_layer_info() { int i; //————————————————————— // //      Get layer sizes for the network // // ————————————————————- cout << “ Please enter in the number of layers for your net work.\n”; cout << “ You can have a minimum of 3 to a maximum of 5. \n”; cout << “ 3 implies 1 hidden layer; 5 implies 3 hidden layers : \n\n”; cin >> number_of_layers; cout << “ Enter in the layer sizes separated by spaces.\n”; cout << “ For a network with 3 neurons in the input layer,\n”; cout << “ 2 neurons in a hidden layer, and 4 neurons in the\n”; cout << “ output layer, you would enter: 3 2 4 .\n”; cout << “ You can have up to 3 hidden layers,for five maximum entries :\n\n”; for (i=0; i<number_of_layers; i++)         {         cin >> layer_size[i];         } // ——————————————————————————— // size of layers: //    input_layer            layer_size[0] //    output_layer           layer_size[number_of_layers-1] //    middle_layers          layer_size[1] //    optional: layer_size[number_of_layers-3] //    optional: layer_size[number_of_layers-2] //———————————————————————————- } void network::set_up_network() { int i,j,k; //———————————————————————————- // Construct the layers // //———————————————————————————- layer_ptr[0] = new input_layer(0,layer_size[0]); for (i=0;i<(number_of_layers-1);i++)         {         layer_ptr[i+1] =         new middle_layer(layer_size[i],layer_size[i+1]);         } layer_ptr[number_of_layers-1] = new output_layer(layer_size[number_of_layers-2], layer_size[number_of_ layers-1]); for (i=0;i<(number_of_layers-1);i++)         {         if (layer_ptr[i] == 0)                {                cout << “insufficient memory\n”;                cout << “use a smaller architecture\n”;                exit(1);                }         } //———————————————————————————- // Connect the layers // //———————————————————————————- // set inputs to previous layer outputs for all layers, //             except the input layer for (i=1; i< number_of_layers; i++)         layer_ptr[i]->inputs = layer_ptr[i-1]->outputs; // for back_propagation, set output_errors to next layer //             back_errors for all layers except the output //             layer and input layer for (i=1; i< number_of_layers -1; i++)         ((output_layer *)layer_ptr[i])->output_errors =                ((output_layer *)layer_ptr[i+1])->back_errors; // define the IObuffer that caches data from // the datafile i=layer_ptr[0]->num_outputs;// inputs j=layer_ptr[number_of_layers-1]->num_outputs; //outputs k=MAX_VECTORS; buffer=new         float[(i+j)*k]; if (buffer==0)         {         cout << “insufficient memory for buffer\n”;         exit(1);         } } void network::randomize_weights() { int i; for (i=1; i<number_of_layers; i++)         ((output_layer *)layer_ptr[i])                 ->randomize_weights(); } void network::update_weights(const float beta, const float alpha) { int i; for (i=1; i<number_of_layers; i++)         ((output_layer *)layer_ptr[i])                ->update_weights(beta,alpha); } void network::update_momentum() { int i; for (i=1; i<number_of_layers; i++)         ((output_layer *)layer_ptr[i])                ->update_momentum(); } void network::write_weights(FILE * weights_file_ptr) { int i; for (i=1; i<number_of_layers; i++)         ((output_layer *)layer_ptr[i])                ->write_weights(i,weights_file_ptr); } void network::read_weights(FILE * weights_file_ptr) { int i; for (i=1; i<number_of_layers; i++)         ((output_layer *)layer_ptr[i])                ->read_weights(i,weights_file_ptr); } void network::list_weights() { int i; for (i=1; i<number_of_layers; i++)         {         cout << “layer number : “ <<i<< “\n”;         ((output_layer *)layer_ptr[i])                ->list_weights();         } } void network::list_outputs() { int i; for (i=1; i<number_of_layers; i++)         {         cout << “layer number : “ <<i<< “\n”;         ((output_layer *)layer_ptr[i])                ->list_outputs();         } } void network::write_outputs(FILE *outfile) { int i, ins, outs; ins=layer_ptr[0]->num_outputs; outs=layer_ptr[number_of_layers-1]->num_outputs; float temp; fprintf(outfile,”for input vector:\n”); for (i=0; i<ins; i++)         {         temp=layer_ptr[0]->outputs[i];         fprintf(outfile,”%f  “,temp);         } fprintf(outfile,”\noutput vector is:\n”); for (i=0; i<outs; i++)         {         temp=layer_ptr[number_of_layers-1]->         outputs[i];         fprintf(outfile,”%f  “,temp);         } if (training==1) { fprintf(outfile,”\nexpected output vector is:\n”); for (i=0; i<outs; i++)         {         temp=((output_layer *)(layer_ptr[number_of_layers-1]))->         expected_values[i];         fprintf(outfile,”%f  “,temp);         } } fprintf(outfile,”\n———————————\n”); } void network::list_errors() { int i; for (i=1; i<number_of_layers; i++)         {         cout << “layer number : “ <<i<< “\n”;         ((output_layer *)layer_ptr[i])                ->list_errors();         } } int network::fill_IObuffer(FILE * inputfile) { // this routine fills memory with // an array of input, output vectors // up to a maximum capacity of // MAX_INPUT_VECTORS_IN_ARRAY // the return value is the number of read // vectors int i, k, count, veclength; int ins, outs; ins=layer_ptr[0]->num_outputs; outs=layer_ptr[number_of_layers-1]->num_outputs; if (training==1)         veclength=ins+outs; else         veclength=ins; count=0; while  ((count<MAX_VECTORS)&&                (!feof(inputfile)))         {         k=count*(veclength);         for (i=0; i<veclength; i++)                {                fscanf(inputfile,”%f”,&buffer[k+i]);                }         fscanf(inputfile,”\n”);         count++;         } if (!(ferror(inputfile)))         return count; else return -1; // error condition } void network::set_up_pattern(int buffer_index) { // read one vector into the network int i, k; int ins, outs; ins=layer_ptr[0]->num_outputs; outs=layer_ptr[number_of_layers-1]->num_outputs; if (training==1)         k=buffer_index*(ins+outs); else         k=buffer_index*ins; for (i=0; i<ins; i++)         ((input_layer*)layer_ptr[0])                       ->orig_outputs[i]=buffer[k+i]; if (training==1) {         for (i=0; i<outs; i++)                ((output_layer *)layer_ptr[number_of_layers-1])->                       expected_values[i]=buffer[k+i+ins]; } } void network::forward_prop() { int i; for (i=0; i<number_of_layers; i++)         {         layer_ptr[i]->calc_out(); //polymorphic                                // function         } } void network::backward_prop(float & toterror) { int i; // error for the output layer ((output_layer*)layer_ptr[number_of_layers-1])->                       calc_error(toterror); // error for the middle layer(s) for (i=number_of_layers-2; i>0; i—)         {         ((middle_layer*)layer_ptr[i])->                       calc_error();         } } void network::set_NF(float noise_fact) { ((input_layer*)layer_ptr[0])->set_NF(noise_fact); } 


Previous Table of Contents Next

Copyright © IDG Books Worldwide, Inc.



C++ Neural Networks and Fuzzy Logic
C++ Neural Networks and Fuzzy Logic
ISBN: 1558515526
EAN: 2147483647
Year: 1995
Pages: 139

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net