//*******************************************************************************
// 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