home *** CD-ROM | disk | FTP | other *** search
/ World of Shareware - Software Farm 2 / wosw_2.zip / wosw_2 / CPROG / AI-90-10.ZIP / NETWORK.CPP < prev    next >
C/C++ Source or Header  |  1990-10-01  |  10KB  |  337 lines

  1. #include "neural.hpp"
  2. #include <conio.h>
  3. #include <stdlib.h>
  4. #include <math.h>
  5. #include <fstream.h>
  6.   
  7.   
  8. void Network::adjustWeights(void)
  9. {
  10.     for(int atCnxn = 0; atCnxn < nCnxns; atCnxn++)
  11.         cnxn[atCnxn].adjust();
  12. }
  13.  
  14. void Network::allForward(void)
  15. {
  16.     CLEAR_SCREEN();
  17.     CURSOR_GOTO(1,1);
  18.     for(atPattern = 0; atPattern < nPatterns; atPattern++)
  19.     {
  20.         forwardPass();
  21.         displayDiff();
  22.     }
  23. }
  24.  
  25. void Network::backwardProp(void)
  26. {
  27.     calcOutputError();
  28.     calcMiddleError();
  29.     adjustWeights();
  30. }
  31.   
  32. void Network::calcMiddleError(void)
  33. {
  34.     //This would need to be reworked for a multi-middle layer network
  35.     for(int atMidNeurode = 0; atMidNeurode < nInLayer[1]; atMidNeurode++)
  36.     {
  37.         float weightedSumOfErrors = 0;
  38.         int offset = nInLayer[0] * nInLayer[1] + nInLayer[2] * atMidNeurode;
  39.         for(int atHighNeurode = 0; atHighNeurode < nInLayer[OUTLAYER]; atHighNeurode++)
  40.             weightedSumOfErrors += cnxn[offset + atHighNeurode].n2->error * cnxn[offset + atHighNeurode].weight;
  41.         neuron[1][atMidNeurode]->derivTransfer(weightedSumOfErrors);
  42.     }
  43. }
  44.   
  45.  
  46. void Network::calcOutputError(void)
  47. {
  48.     thisPatternError = 0;
  49.     for(int atNeurode = 0; atNeurode < nInLayer[OUTLAYER]; atNeurode++)
  50.     {
  51.         float diff = pat[atPattern].out[atNeurode] - neuron[OUTLAYER][atNeurode]->output;
  52.         //You may just pass diff to calcLocalError for "classic" backprop
  53.         //Or you can square it for "Quadratic" error func
  54.         //Or you can cube it for "Cubic" error func.
  55.         neuron[OUTLAYER][atNeurode]->derivTransfer(diff);
  56.         if(diff < 0)
  57.         {
  58.             if(diff < -acceptableError)
  59.                 thisPatternError -= diff;
  60.         }else{
  61.             if (diff > acceptableError)
  62.             thisPatternError += diff;
  63.         }
  64.     }
  65.     if(thisPatternError > acceptableError)
  66.         totalError += thisPatternError;
  67. }
  68.  
  69. bool Network::atEpochEnd(void){
  70.     if(atPattern == nPatterns - 1){
  71.         atPattern = 0;
  72.         ++iteration;
  73.         return true;
  74.     }else{
  75.         atPattern++;
  76.         return false;
  77.     }
  78. }
  79.   
  80.   
  81. void Network::display(void)
  82. {
  83.     cout<<"Network iteration "<<iteration<<" Total error: "<<totalError<<"\n";
  84.     int cnxnNumber = 0;
  85.     for(int atLayer = 0; atLayer < nLayers; atLayer++)
  86.     {
  87.         cout<<"Layer "<<atLayer<<"\n";
  88.         for(int atNeuron = 0; atNeuron < nInLayer[atLayer]; atNeuron++)
  89.         {
  90.             cout<<"\tNeuron["<<atNeuron<<"] Input: "<<neuron[atLayer][atNeuron]->input<<" Output: "<<neuron[atLayer][atNeuron]->output<<" Error: "<<neuron[atLayer][atNeuron]->error<<"\n";
  91.             if(atLayer != OUTLAYER)
  92.             {
  93.                 for(int atHighNeuron = 0; atHighNeuron < nInLayer[atLayer+1];atHighNeuron++)
  94.                 {
  95.                     cout<<"\t\t cnxn["<<cnxnNumber<<"] Weight: "<<cnxn[cnxnNumber].weight<<" Delta: "<<cnxn[cnxnNumber].delta<<'\n';
  96.                     cnxnNumber++;
  97.                 }
  98.             }
  99.         }
  100.     }
  101. }
  102.   
  103. void Network::displayDiff(void)
  104. {
  105. #ifdef DISPLAY_YES
  106.    SET_TEXT_ATTR(WHITE);
  107.    DOS_PRINT("Pattern[%d] Error: %f\n\r", atPattern, thisPatternError);
  108.    DOS_PRINT("Desired: ");
  109.    for(int i = 0; i < outDepth * outWidth; i++)
  110.      DOS_PRINT("%6.3f  ", (float) pat[atPattern].out[i]);
  111.    DOS_PRINT("\n\r");
  112.    DOS_PRINT("Actual:  ");
  113.    for( i = 0; i < outDepth * outWidth; i++)
  114.    {
  115.         float err = pat[atPattern].out[i] - neuron[OUTLAYER][i]->output;
  116.         if(err < 0)
  117.             err *= -1;
  118.         if(err > acceptableError)
  119.             SET_TEXT_ATTR(RED);
  120.         else
  121.             SET_TEXT_ATTR(GREEN);
  122.    DOS_PRINT("%6.3f  ",neuron[OUTLAYER][i]->output);
  123.    }
  124.    DOS_PRINT("\n\r");
  125.    SET_TEXT_ATTR(WHITE);
  126. #endif
  127. }
  128.   
  129. void Network::displayTotalError(void)
  130. {
  131.     cout<<"Iteration: "<<iteration<<" Total error: "<<totalError<<"\n";
  132. }
  133.  
  134. void Network::displayPerformance(unsigned long elapsedTime)
  135. {
  136.    cout<<"Iterations: "<<iteration<<" Elapsed time: "<<elapsedTime<<"\n";
  137.    float CPI = (float) nCnxns * (float) nPatterns * (float) iteration / (float) elapsedTime;
  138.    cout.precision(3);
  139.    cout<<" Connections per second: "<<CPI<<"\n";
  140. }
  141.   
  142. void Network::forwardPass(void)
  143. {
  144.     // Zero all inputs
  145.     for(int atLayer = 0; atLayer < nLayers; atLayer++)
  146.     {
  147.         for(int atNeuron = 0; atNeuron < nInLayer[atLayer]; atNeuron++)
  148.             neuron[atLayer][atNeuron]->input = 0.0;
  149.     }
  150.     //First, put the input pattern directly into the input neuron's output
  151.     //queues.
  152.     for(int atNeuron = 0; atNeuron < nInLayer[0]; atNeuron++)
  153.         neuron[0][atNeuron]->output = pat[atPattern].in[atNeuron];
  154.  
  155.      //Then, for each layer, feedforward
  156.      int cnxnNumber = 0;
  157.      int offset = 0;
  158.      for(atLayer = 1; atLayer <= OUTLAYER; atLayer++)
  159.      {
  160.         int nCons = nInLayer[atLayer] * nInLayer[atLayer - 1];
  161.         for(cnxnNumber = offset; cnxnNumber < nCons + offset; cnxnNumber++)
  162.             cnxn[cnxnNumber].feedForward();
  163.         offset += nCons;
  164.         for(atNeuron = 0; atNeuron < nInLayer[atLayer]; atNeuron++)
  165.             neuron[atLayer][atNeuron]->transfer();
  166.     }
  167. }
  168.   
  169. Network::Network(void)
  170. {
  171.     nLayers = 0;
  172.     atPattern = 0;
  173.     iteration = 0;
  174.     totalError = 0;
  175. }
  176.   
  177. Network::Network(int nL, int* layerSize)
  178. {
  179.     nLayers = nL;
  180.     nInLayer = new int[nLayers];
  181.     if(!nInLayer)
  182.     {
  183.         cerr<<"Error during memory allocation of nInLayer array!\n";
  184.         return;
  185.     }
  186.     nNeurons = nCnxns = 0;
  187.     for(int i = 0; i < nLayers; i++)
  188.     {
  189.         nInLayer[i] = layerSize[i];
  190.         if(i > 0)
  191.             nCnxns += nInLayer[i] * nInLayer[i - 1];
  192.         nNeurons += nInLayer[i];
  193.     }
  194.     atPattern = 0;
  195.     cnxn = new Connection[nCnxns];
  196.     if(!cnxn)
  197.     {
  198.         cerr<<"Error during memory allocation of connections!\n";
  199.         return;
  200.     }
  201.     for(int atLayer = 0; atLayer < nLayers; atLayer++)
  202.     {
  203.         for(int atNeuron = 0; atNeuron < nInLayer[atLayer]; atNeuron++)
  204.         {
  205.             neuron[atLayer][atNeuron] = new Neuron;
  206.             if(!neuron[atLayer][atNeuron])
  207.             {
  208.                 cerr<<"Error during memory allocation of neurons.\n"
  209.                 <<nNeurons<<" requested at "<<sizeof(Neuron)<<" bytes.\n";
  210.                 return;
  211.             }
  212.         }
  213.     }
  214. }
  215.   
  216. bool Network::trained(void)
  217. {
  218.     if(totalError < acceptableError)
  219.         return true;
  220.     else
  221.         return false;
  222. }
  223.  
  224. bool Network::trainingFile(char* fileName)
  225. {
  226.     ifstream dataFile(fileName);
  227.     if(!dataFile)
  228.     {
  229.         cerr<<"Error opening file "<<fileName<<"\n";
  230.         return(false);
  231.     }
  232.     dataFile>>"nLayers: ";
  233.      dataFile>>nLayers;
  234.     nInLayer = new int[nLayers];
  235.     if(!nInLayer)
  236.     {
  237.         cerr<<"Error during memory allocation for nInLayer[]!\n";
  238.         return(false);
  239.     }
  240.     nNeurons = nCnxns = 0;
  241.     for(int atLayer = 0; atLayer < nLayers; atLayer++)
  242.     {
  243.         dataFile>>nInLayer[atLayer];
  244.         if(atLayer > 0)
  245.             nCnxns += nInLayer[atLayer] * nInLayer[atLayer - 1];
  246.         nNeurons += nInLayer[atLayer];
  247.     }
  248.     cnxn = new Connection[nCnxns];
  249.     if(!cnxn)
  250.     {
  251.         cerr<<"Error during allocation of "<<nCnxns<<" connections\n";
  252.         return(false);
  253.     }
  254.     for(atLayer = 0; atLayer < nLayers; atLayer++)
  255.     {
  256.         for(int atNeuron = 0; atNeuron < nInLayer[atLayer]; atNeuron++)
  257.         {
  258.             neuron[atLayer][atNeuron] = new Neuron;
  259.             if(!neuron[atLayer][atNeuron])
  260.             {
  261.                 cerr<<"Error during memory allocation of neurons.\n"
  262.                 <<nNeurons<<" requested at "<<sizeof(Neuron)<<" bytes.\n";
  263.                 return(false);
  264.             }
  265.         }
  266.     }
  267.     float learningConstant, momentum, samadCoefficient;
  268.     dataFile>>"acceptableError:">>acceptableError;
  269.     dataFile>>"learningConstant:">>learningConstant;
  270.     dataFile>>"Momentum:">>momentum;
  271.     dataFile>>"samadCoefficient:">>samadCoefficient;
  272.     int atCnxn = 0;
  273.     for( atLayer = 0; atLayer < nLayers - 1; atLayer++)
  274.     {
  275.         for(int atLowNeuron = 0; atLowNeuron < nInLayer[atLayer]; atLowNeuron++)
  276.         {
  277.             for(int atHighNeuron = 0; atHighNeuron < nInLayer[atLayer + 1]; atHighNeuron++)
  278.             {
  279.                 cnxn[atCnxn].set(neuron[atLayer][atLowNeuron],neuron[atLayer + 1][atHighNeuron]);
  280.                 cnxn[atCnxn].setRandom(learningConstant, momentum, samadCoefficient);
  281.                 ++atCnxn;
  282.             }
  283.         }
  284.     }
  285.  
  286.     dataFile>>"nPatterns:">>nPatterns;
  287.     dataFile>>"width:">>inWidth;
  288.     dataFile>>"depth:">>inDepth;
  289.     dataFile>>"outputWidth:">>outWidth;
  290.     dataFile>>"outputDepth:">>outDepth;
  291.     pat = new Pattern[nPatterns];
  292.     if(!pat)
  293.     {
  294.         cerr<<"Error during memory allocation for patterns\n";
  295.         return(false);
  296.     }
  297.     for(int i = 0; i < nPatterns; i++)
  298.         if(!pat[i].getMem(inWidth * inDepth, outWidth * outDepth))
  299.             return(false);
  300.     if(!pat)
  301.     {
  302.         cerr<<"Error during allocation of memory for patterns!\n";
  303.         return(false);
  304.     }
  305.     int temp;
  306.     for(int atPattern = 0; atPattern < nPatterns; atPattern++)
  307.     {
  308.         for(int i = 0; i < inWidth * inDepth; i++)
  309.         {
  310.             dataFile>>temp;
  311.             if(temp == 1)
  312.                 pat[atPattern].in[i] = 1 - acceptableError;
  313.             else
  314.                 pat[atPattern].in[i] = acceptableError;
  315.         }
  316.         for( i = 0; i < outWidth * outDepth; i++)
  317.         {
  318.             dataFile>>temp;
  319.             if(temp == 1)
  320.                 pat[atPattern].out[i] = 1.0;
  321.             else
  322.                 pat[atPattern].out[i] = 0;
  323.         }
  324.     }
  325.     dataFile.close();
  326.     atPattern = 0;
  327.     totalError = 0;
  328.     return true;
  329. }
  330.  
  331. void Network::zeroTotalError(void)
  332. {
  333.     totalError = 0.0;
  334. }
  335.   
  336.   
  337.