www.pudn.com > 基于VC的神经网络开发程序包(源码).rar > MultiLayerNetwork.cpp


#include "../include/MultiLayerNetwork.h" 
#include "../include/Exception.h" 
#include "../include/SimpleNeuron.h" 
#include "../include/File.h" 
 
#include  
 
using namespace std; 
namespace annie 
{ 
 
MultiLayerNetwork::MultiLayerNetwork(int inputs) : Network(inputs,0) 
{ 
	_nLayers = 0; 
	InputLayer *inputLayer = new InputLayer(0,inputs); 
	_layers.push_back(inputLayer); 
} 
 
MultiLayerNetwork::MultiLayerNetwork(MultiLayerNetwork &src) : Network(src) 
{ 
	throw Exception("MultiLayerNetwork::MultiLayerNetwork() - Copy constructor not yet implemented."); 
} 
 
MultiLayerNetwork::MultiLayerNetwork(const char *filename) : Network(0,0) 
{	 
	_nLayers = 0; 
	File file; 
	try 
	{ 
		file.open(filename); 
	} 
	catch (Exception &e) 
	{ 
		string error(getClassName()); 
		error = error + "::" + getClassName() + "() - " + e.what(); 
		throw Exception(error); 
	} 
 
	string s; 
	s=file.readWord(); 
	if (s.compare(getClassName())!=0) 
	{ 
		string error(getClassName()); 
		error = error + "::" + getClassName() + "() - File supplied is not about this type of network."; 
		throw Exception(error); 
	} 
 
	int maxLayerSize = Layer::MAX_LAYER_SIZE; 
	while (!file.eof()) 
	{ 
		s=file.readWord(); 
		if (!s.compare("INPUTS")) 
		{ 
			_nInputs=file.readInt(); 
			InputLayer *inputLayer=new InputLayer(0,_nInputs); 
			_layers.push_back(inputLayer); 
		} 
		else if (!s.compare("OUTPUTS")) 
			_nOutputs=file.readInt(); 
		else if (!s.compare("MAX_LAYER_SIZE")) 
			maxLayerSize=file.readInt(); 
		else if (!s.compare("SIZE")) 
			addLayer(file.readInt()); 
		else if (!s.compare("Biases")) 
		{ 
			vector < Layer * >::iterator l; 
			for (l=_layers.begin()+1;l!=_layers.end();l++) 
			{ 
				Layer *layer = (Layer *)(*l); 
				for (int j=0;jgetSize();j++) 
				{ 
					if (file.eof()) 
						break; 
					SimpleNeuron &n = (SimpleNeuron&)layer->getNeuron(j); 
					n.setBias(file.readDouble()); 
				} 
			} 
		} 
		else if (!s.compare("BEGIN_META_DATA")) 
		{ 
			static const basic_string ::size_type npos = (basic_string ::size_type)-1; 
			string end("END_META_DATA"); 
			string metaData; 
			s = file.readLine(); 
			while (s.find(end,0)==npos) 
			{ 
				metaData = metaData + s + "\n"; 
				s = file.readLine(); 
			} 
			if (metaData.length()>0) 
				metaData.erase(metaData.length()-1); //getting rid of the last "\n" 
			setMetaData(metaData); 
		} 
		else if (!s.compare("Connections")) 
			break; 
		else 
			cerr<=nLayers || layer2>nLayers) 
		{ 
			string error(getClassName()); 
			error = error + "::" + getClassName() + "() - Error in file. Label of neuron corresponds to an invalid layer."; 
			throw Exception(error); 
		} 
		if (layer2-layer1!=1) 
		{ 
			string error(getClassName()); 
			error = error + "::" + getClassName() + "() - Error in file. Connection not betwen ith and (i+1)th layer."; 
			throw Exception(error); 
		} 
		 
		fromLayer=_layers[layer1]; 
		toLayer=_layers[layer2]; 
		 
		if (neuron1>=fromLayer->getSize() || neuron2>=toLayer->getSize()) 
		{ 
			string error(getClassName()); 
			error = error + "::" + getClassName() + "() - Error in file. There aren't that many neurons in the layer."; 
			throw Exception(error); 
		} 
		connect(layer1,neuron1,neuron2,wt); 
	} // while (!file.eof()) 
	file.close(); 
} 
 
MultiLayerNetwork::~MultiLayerNetwork() 
{ 
	vector::iterator it; 
	while (!_layers.empty()) 
	{ 
		it = _layers.begin(); 
		Layer *l = (Layer *)(*it); 
		delete l; 
		it = _layers.erase(it); 
	} 
} 
 
int 
MultiLayerNetwork::getLayerCount() 
{	return _nLayers;	} 
 
VECTOR 
MultiLayerNetwork::getOutput(real *input) 
{	return Network::getOutput(input);	} 
 
VECTOR 
MultiLayerNetwork::getOutput(VECTOR &input) 
{ 
	if (getLayerCount()==0) 
	{ 
		string error(getClassName()); 
		error = error + "::getOutput() - There is no output layer"; 
		throw Exception(error); 
	} 
	_inputLayer()->setInput(input); 
	try 
	{ 
		return _outputLayer()->getOutput(); 
	} 
	catch (Exception &e) 
	{ 
		string error(getClassName()); 
		error = error + "::getOutput() - " + e.what(); 
		throw Exception(e); 
	} 
} 
 
void 
MultiLayerNetwork::addLayer(int size) 
{ 
	_nLayers++; 
	int i; 
	Layer *newLayer = new Layer(_nLayers); 
	for (i=0;iaddNeuron(new SimpleNeuron(_nLayers*Layer::MAX_LAYER_SIZE+i)); 
	_layers.push_back(newLayer); 
	_nOutputs = size; 
} 
 
void 
MultiLayerNetwork::connectLayer(int src) 
{ 
	Layer *srcLayer, *destLayer; 
	int dest = src + 1; 
	int srcSize, destSize; 
	int i,j; 
	if (src<0 || src>getLayerCount()-1) 
	{ 
		string error(getClassName()); 
		error = error + "::connectLayer() - Invalid source layer specified."; 
		throw Exception(error); 
	} 
 
	srcLayer = _layers[src]; 
	destLayer = _layers[dest]; 
	srcSize = srcLayer->getSize(); 
	destSize = destLayer->getSize(); 
	for (i=0;igetNeuron(i); 
		for (j=0;jgetNeuron(j)); 
	} 
} 
 
void 
MultiLayerNetwork::connect(int src, int srcNrn, int destNrn, real weight) 
{ 
	Layer *srcLayer, *destLayer; 
	int srcSize, destSize; 
	if (src<0 || src>getLayerCount()-1) 
	{ 
		string error(getClassName()); 
		error = error + "::connect() - Invalid source layer specified."; 
		throw Exception(error); 
	} 
	 
	srcLayer = _layers[src]; 
	destLayer = _layers[src+1]; 
	srcSize = srcLayer->getSize(); 
	destSize = destLayer->getSize(); 
	try 
	{ 
		SimpleNeuron &destination = (SimpleNeuron&)destLayer->getNeuron(destNrn); 
		destination.connect(&srcLayer->getNeuron(srcNrn),weight); 
	} 
	catch (Exception &e) 
	{ 
		string error(getClassName()); 
		error = error + "::connect() - " + e.what(); 
		throw Exception(e); 
	} 
} 
 
void 
MultiLayerNetwork::connect(int srcLayer, int srcNrn, int destNrn) 
{	connect(srcLayer,srcNrn,destNrn,random()); } 
 
void 
MultiLayerNetwork::setBias(int layer, int nrn, real bias) 
{ 
	if (layer<0 || layer>getLayerCount()) 
	{ 
		string error(getClassName()); 
		error = error + "::setBias() - Invalid layer specified."; 
		throw Exception(error); 
	} 
	try 
	{ 
		SimpleNeuron &n = (SimpleNeuron&)_layers[layer]->getNeuron(nrn); 
		n.setBias(bias); 
	} 
	catch (Exception &e) 
	{ 
		string error(getClassName()); 
		error = error + "::setBias() - " + e.what(); 
		throw Exception(e); 
	} 
} 
 
InputLayer * 
MultiLayerNetwork::_inputLayer() 
{	return (InputLayer*)_layers[0];	} 
 
Layer * 
MultiLayerNetwork::_outputLayer() 
{	return _layers[getLayerCount()];	} 
 
void 
MultiLayerNetwork::save(const char *filename) 
{ 
	ofstream s; 
	s.open(filename,ios::out); 
	if (!s) 
	{ 
		string error(getClassName()); 
		error = error + "::save() - Could not open file for writing."; 
		throw Exception(error); 
	} 
 
	s<<"ANNIE_FILE "<::iterator it; 
	int ctr; 
	for (ctr=0,it=_layers.begin()+1;it!=_layers.end();it++,ctr++) 
		s<<"SIZE "<<(*it)->getSize()<<" # of layer "< (label 2) of weight (weight)"<getSize()<<" lines follow"<getSize();i++) 
		{ 
			SimpleNeuron &n = (SimpleNeuron&)((*it)->getNeuron(i)); 
			s<getSize(); 
		for (ctr=0;ctrgetNeuron(ctr)); 
			vector labels; 
			vector weights; 
			int conns; 
			conns=nrn->getInputs(labels,weights); 
			for (int j=0;jgetLabel()<<","<setInput(input); 
				for (i=0;igetNeuron(i); 
					n.setDesiredOutput(desired[i]); 
				} 
				for (i=nLayers;i>0;i--) 
				{ 
					layerSize = _layers[i]->getSize(); 
					for (j=0; jgetNeuron(j); 
						n.calculateNewWeights(learningRate,momentum); 
					} 
				} //i = layers 
				for (i=1;i<=nLayers;i++) 
				{ 
					layerSize = _layers[i]->getSize(); 
					for (j=0;jgetNeuron(j); 
						n.update(); 
					} 
				} //i = layers 
			} // while T 
		} // epoch 
	} 
	catch (Exception &e) 
	{ 
		string error(getClassName()); 
		error = error + "::train() - " + e.what(); 
		throw Exception(error); 
	} 
} 
 
void 
MultiLayerNetwork::setActivationFunction(int layer, ActivationFunction f, ActivationFunction df) 
{ 
	if (layer <= 0 || layer > _nLayers) 
	{ 
		string error(getClassName()); 
		error = error + "::setActivationFunction() - Invalid layer provided"; 
		throw Exception(error); 
	} 
 
	int N = _layers[layer]->getSize(); 
	for (int i=0; igetNeuron(i); 
		n.setActivationFunction(f,df); 
	} 
} 
 
const char * 
MultiLayerNetwork::getClassName() 
{	return "MultiLayerNetwork";	} 
}; //namespace annie