//******************************************************************************* // CSC 143 Computer Programming II Spring 1999 Instructor: Keith Hughes // // Homework 3 // File : \\Venus\katy\CIS143\Homework3\AdalineNetwork\NeuralNet.cpp // // Purpose : Inplementation file for class NeuralNet. // // Author : Hsin-yi F. Berg // Date : 5/9/1999 Sun. // Last Update: 5/28/1999 Fri. // Update Note: Implementation for NeuralNet class has been moved here // from Layer.h. //******************************************************************************* #include "NeuralNet.h" #include <iostream.h> #include <assert.h> // weight of the link, defined in base.h extern const double WEIGHT; /* Static member initialization and function definitions for class NeuralNet */ int NeuralNet::id_count = 0; /* NeuralNet::NeuralNet() Default constructor for an NeuralNet. NeuralNet is created empty. */ NeuralNet::NeuralNet() { id = id_count++; numNeuronLayer = 0; neuronLayers = NULL; linkLayers = NULL; } /* NeuralNet::NeuralNet() Copy constructor for an NeuralNet. */ NeuralNet::NeuralNet(const NeuralNet &otherNeuralNet) { // call private utility clone(otherNeuralNet); } /* NeuralNet::~NeuralNet() Destructor for an NeuralNet. */ NeuralNet::~NeuralNet() { // call private utility destroy(); } /* NeuralNet::SetHowManyNeuronLayers(int size) Set how many neuron layers there are in the NeuralNet. Cannot set the number of Neuron Layers to 0. The number of LinkLayers will automatically be set to "size - 1". */ void NeuralNet::SetHowManyNeuronLayers(int size) { assert(size != 0); // cannot set 0 Layer assert(numNeuronLayer == 0);// This function can only be called once numNeuronLayer = size; // allocate an array of NeuranLayers with "size" elements neuronLayers = new NeuronLayer[numNeuronLayer]; assert(neuronLayers); // allocate an array of LinkLayers with "size - 1" elements linkLayers = new LinkLayer[numNeuronLayer - 1]; assert(linkLayers); } /* NeuralNet::SetSizeOfNeuronLayer(int whichLayer, int size) Set how many neurons a paticular NeuronLayer contains. Cannot set the number of Neurons to 0. */ void NeuralNet::SetSizeOfNeuronLayer( int whichLayer, int size ) { assert(size != 0); // cannot set the size of Layer to 0 // This function can only get called once assert(neuronLayers[whichLayer].GetNumNeuron() == 0); // there should be at least one Layer in the NeuralNet. // also check if the Layer asking for exists (not out of bound). assert(numNeuronLayer > 0 && whichLayer < numNeuronLayer); // allocate Neurons in the specific NeuronLayer neuronLayers[whichLayer].SetHowManyNeurons(size); // size of links each LinkLayer contains is "size * size" for fully // connected network, so we don't need to set it. // Links in LinkLayers will be allocated in the InterConnect function } /* void NeuralNet::SetInputValue(int whichNeuron, double Value) Set the value of a specific Neuron in input NeuronLayer. */ void NeuralNet::SetInputValue( int whichNeuron, double value ) { // neuronLayers[0] is the input Layer. // there should be at least one Neuron in the input Layer // also check if the Neuron asking for exists (not out of bound). int sizeOfInputLayer = neuronLayers[0].GetNumNeuron(); assert( sizeOfInputLayer > 0 && whichNeuron < sizeOfInputLayer); // We only need to set the value of the input Layer neuronLayers[0].SetNeuronValue(whichNeuron, value); } /* double NeuralNet::GetOutputValue(int whichNeuron) Get the value of a specific Neuron in the output NeuronLayer */ double NeuralNet::GetOutputValue(int whichNeuron) const { // NeuronLayers[numNeuronLayer - 1] is the output Layer // there should be at least one Neuron in the output Layer // also check if the Neuron asking for exists (not out of bound). int sizeOfOutputLayer = neuronLayers[numNeuronLayer - 1].GetNumNeuron(); assert( sizeOfOutputLayer > 0 && whichNeuron < sizeOfOutputLayer); // We only care about the value in the output Layer return neuronLayers[numNeuronLayer - 1].GetNeuronValue(whichNeuron); } /* void NeuralNet::Print(ostream &out) const Print out the internal state of the NeuralNet to client supplied ostream */ void NeuralNet::Print(ostream &out) const { if(numNeuronLayer == 0) out << "\tNeuron Network is empty." << endl; // Print out all the NeuronLayers for(int i = 0; i < numNeuronLayer; i ++) neuronLayers[i].Print(out); // Print out all the LinkLayers for(i = 0; i < numNeuronLayer - 1; i++) linkLayers[i].Print(out); } /* void NeuralNet::Fire(void) Fire the whole NeuralNet layer by layer. */ void NeuralNet::Fire(void) { // Fire each and every Layer for(int i = 1; i < numNeuronLayer; i++) neuronLayers[i].Fire(); } /* void NeuralNet::InterConnect(void) Create a fully connected Network - Eevery neuron in one NeuronLayer is connected to every neuron in adjecent NeuronLayer through the link Layer in between. */ void NeuralNet::InterConnect(void) { // Go through all the NeuronLayer and LinkLayer for(int n = 0; n < numNeuronLayer - 1; n++) { // sizein is the size of the previous layer int sizein = neuronLayers[n].GetNumNeuron(); // sizeout is the size of the next layer int sizeout = neuronLayers[n+1].GetNumNeuron(); // allocate right amount of Links in each linkLayer // size of LinkLayer between two NeuronLayers is sizein * sizeout linkLayers[n].SetHowManyLinks(sizein * sizeout); // for each Link of the LinkLayer, connect one Neuron in // the previous NeuronLayer and one Neuron in the next NeuronLayer // until every Neuron in the previous NeuronLayer is connected with // the next NeuronLayer for(int i = 0; i < sizein; i++) for(int j = 0; j < sizeout; j++) Connect(neuronLayers[n].GetNeurons()[i], neuronLayers[n+1].GetNeurons()[j], linkLayers[n].GetLinks()[i * sizeout + j], WEIGHT); // the usage of "i*sizeout+j" is a way to treat the link array // as a two-dimentional array } } /* NeuralNet &NeuralNet::operator=(const NeuralNet &otherNeuralNet) Assignment operator for this NeuralNet. */ NeuralNet &NeuralNet::operator=(const NeuralNet &otherNeuralNet) { // Cannot assign ourself to ourself. if (this != &otherNeuralNet) { // destroy old stuff (if we had any) destroy(); // check if the old stuff is really gone assert(neuronLayers == NULL && linkLayers == NULL); clone(otherNeuralNet); } // Give back a reference to ourselves (so we can say a = b = c) // in other words - allow cascading return *this; } /* void NeuralNet::clone(const NeuralNet &otherNeuralNet) Private Utility: Deep copy of otherNeuralNet. This NeuralNet must be cleaned up before calling clone. */ void NeuralNet::clone(const NeuralNet &otherNeuralNet) { // make sure this NeuralNet has been cleaned up assert(neuronLayers == NULL && linkLayers == NULL); // allocate same numbers of NeuronLayers SetHowManyNeuronLayers(otherNeuralNet.numNeuronLayer); // allocate same numbers of Neurons of each layer for(int i = 0; i < numNeuronLayer; i++) SetSizeOfNeuronLayer(i, otherNeuralNet.neuronLayers[i].GetNumNeuron()); // connect the layers, which will allocate same number of LinkLayers and links InterConnect(); // set the weight of each link to WEIGHT // SetLinkWeight will set the weight of all Links in a LinkLayer to a certain weight for(i = 0; i < numNeuronLayer - 1; i++) { linkLayers[i].SetLinkWeight(WEIGHT); } } /* void NeuralNet::destroy(void) Private Utility: Clean up this NeuralNet. Deallocate all dynamic memory, reinitialize members */ void NeuralNet::destroy(void) { // clean up all layers if(neuronLayers != NULL) delete[] neuronLayers; if(linkLayers != NULL) delete[] linkLayers; // Since this may be called by things other than a destructor, // reinitialize the members. numNeuronLayer = 0; neuronLayers = NULL; linkLayers = NULL; } /* void NeuralNet::Connect(Neuron &input_Neuron, Neuron &output_Neuron, Link &link, double weight) Private Utility: Connecting a link to its input and output neurons with a specific weight. */ void NeuralNet::Connect( Neuron &input_Neuron, Neuron &output_Neuron, Link &link, double weight ) { input_Neuron.AddOutput(link); output_Neuron.AddInput(link); link.SetNeurons(input_Neuron, output_Neuron); link.SetWeight(weight); } /* void NeuralNet::ReadFromFile(istream& in) Read data into an empty (newly created) NeuralNet instance from file specified by "in". */ void NeuralNet::ReadFromFile(istream& in) { // make sure this NeuralNet is empty when it calls this function assert(numNeuronLayer == 0); // read in how many NeuronLayers there are in the NeuralNet int inNumNeuronLayer = 0; in >> inNumNeuronLayer; // allocate right amount of NeuronLayers according // to inNumNeuronLayer SetHowManyNeuronLayers(inNumNeuronLayer); // now, get the sizes of each NeuronLayer and allocate the right // amount of Neurons for each NeuronLayer int inNumNeuron = 0; for(int i = 0; i < numNeuronLayer; i++) { in >> inNumNeuron; SetSizeOfNeuronLayer(i, inNumNeuron); } // interconnect will allocate right amount of LinkLayers and Links // and build a fully connected network. InterConnect(); // loop through all the NeuronLayers, call the ReadFromFile // function within each NeuronLayer to read in the NeuronLayer // information for(i = 0; i < numNeuronLayer; i++) neuronLayers[i].ReadFromFile(in); // loop through all the LinkLayers, call the ReadFromFile // function within each LinkLayer to update the weight information for(i = 0; i < numNeuronLayer - 1; i++) linkLayers[i].ReadFromFile(in); } /* void NeuralNet::WriteToFile(ostream& out) Write data of this NeuralNet instance to file specified by "out" */ void NeuralNet::WriteToFile(ostream& out) { // first write out how many NeuronLayer there are in the network out << numNeuronLayer << " "; // then write out the number of Neurons in each NeuronLayer for(int i = 0; i < numNeuronLayer; i++) out << neuronLayers[i].GetNumNeuron() << " "; // loop through all the NeuronLayers, call the WriteToFile // function within each NeuronLayer to write out the NeuronLayer // information for(i = 0; i < numNeuronLayer; i++) neuronLayers[i].WriteToFile(out); // loop through all the LinkLayers, call the WriteToFile // function within each LinkLayer to write out the weight // information for(i = 0; i < numNeuronLayer - 1; i++) linkLayers[i].WriteToFile(out); }
Back Top