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


#include "../include/RadialBasisNetwork.h" 
#include "../include/Exception.h" 
#include "../include/Matrix.h" 
#include "../include/File.h" 
 
using namespace std; 
 
namespace annie 
{ 
RadialBasisNetwork::RadialBasisNetwork(int inputs, int centers, int outputs) : Network(inputs,outputs) 
{ 
	int i,j; 
	_inputLayer = new InputLayer(0,inputs); 
 
	_nCenters = centers; 
	_centerLayer = new Layer(1); 
	for (i=0;i<_nCenters;i++) 
	{ 
		CenterNeuron *c = new CenterNeuron(Layer::MAX_LAYER_SIZE*1+i,inputs); 
		for (j=0;jconnect(&_inputLayer->getNeuron(j)); 
		_centerLayer->addNeuron(c); 
	} 
 
    _outputLayer = new Layer(2); 
	for (i=0;isetActivationFunction(identity,didentity); 
		for (j=0;jconnect(&_centerLayer->getNeuron(j)); 
		_outputLayer->addNeuron(n); 
	} 
} 
 
RadialBasisNetwork::RadialBasisNetwork(RadialBasisNetwork &src) : Network(src) 
{ 
	int i,j,lbl; 
	int inputs = src._inputLayer->getSize(); 
	int centers = src._centerLayer->getSize(); 
	int outputs = src._outputLayer->getSize(); 
	_inputLayer = new InputLayer(src._inputLayer->getLabel(),src._inputLayer->getSize()); 
 
	_nCenters = src._nCenters; 
	lbl = src._centerLayer->getLabel(); 
	_centerLayer = new Layer(lbl); 
	for (i=0;igetNeuron(i); 
		c->setCenter(cSrc.getCenter()); 
		for (j=0;jconnect(&_inputLayer->getNeuron(j)); 
		_centerLayer->addNeuron(c);		 
	} 
 
	lbl = src._outputLayer->getLabel(); 
	_outputLayer = new Layer(lbl); 
	for (i=0;igetNeuron(i); 
		n->setBias(nSrc.getBias()); 
		n->setActivationFunction(identity,didentity); 
		for (j=0;jaddNeuron(n); 
	} 
} 
 
RadialBasisNetwork::RadialBasisNetwork(const char *filename) : Network(0,0) 
{ 
	File file; 
	int i,j; 
	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 = new InputLayer(0,_nInputs); 
		} 
		else if (!s.compare("OUTPUTS")) 
		{ 
			_nOutputs=file.readInt(); 
		    _outputLayer = new Layer(2); 
			for (i=0;isetActivationFunction(identity,didentity); 
				_outputLayer->addNeuron(n); 
			} 
		} 
		else if (!s.compare("CENTERS")) 
		{ 
			_nCenters = file.readInt(); 
			_centerLayer = new Layer(1); 
			for (i=0;iaddNeuron(n); 
			} 
		} 
		else if (!s.compare("CENTER_POINTS")) 
		{ 
			for (i=0;igetNeuron(i); 
				VECTOR center; 
				for (j=0;jgetNeuron(i); 
				if (file.readChar()=='t') 
					o.setBias(file.readDouble()); 
				else 
					o.removeBias(); 
			} 
		} 
		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); 
			setMetaData(metaData); 
		} 
		else if (!s.compare("Connections")) 
		{ 
			//Connect inputs to centers 
			for (i=0;igetNeuron(i); 
				for (j=0;jgetNeuron(j)); 
			} 
			 
			//Connect centers to outputs 
			for (i=0;igetNeuron(i); 
				for (j=0;jgetNeuron(j),file.readDouble()); 
			} 
		} 
		else 
			cerr<getNeuron(i)).getCenter(); 
	} 
	catch (Exception &e) 
	{ 
		string error(getClassName()); 
		error = error + "::getCenter() - " + e.what(); 
		throw Exception(error); 
	} 
	return answer; 
} 
 
//CenterNeuron& 
//RadialBasisNetwork::getCenterNeuron(int i) 
//{ 
//	try 
//	{ 
//		return (CenterNeuron&)(_centerLayer->getNeuron(i)); 
//	} 
//	catch (Exception &e) 
//	{ 
//		string error(getClassName()); 
//		error = error + "::getCenterNeuron() - " + e.what(); 
//		throw Exception(error); 
//	} 
//} 
 
VECTOR 
RadialBasisNetwork::getOutput(VECTOR &input) 
{ 
	try 
	{ 
		_inputLayer->setInput(input); 
		return _outputLayer->getOutput(); 
	} 
	catch(Exception e) 
	{ 
		string error(getClassName()); 
		error = error + "::getOutput() - "+e.what(); 
		throw Exception(error); 
	} 
} 
 
void 
RadialBasisNetwork::setCenter(int i, VECTOR ¢er) 
{ 
	try 
	{ 
		CenterNeuron &c = (CenterNeuron&)_centerLayer->getNeuron(i); 
		c.setCenter(center); 
	} 
	catch (Exception &e) 
	{ 
		string error(getClassName()); 
		error = error + "::setCenter() - " + e.what(); 
		throw Exception(e); 
	} 
} 
 
void 
RadialBasisNetwork::setCenter(int i, real *center) 
{ 
	try 
	{ 
		CenterNeuron &c = (CenterNeuron&)_centerLayer->getNeuron(i); 
		c.setCenter(center); 
	} 
	catch (Exception &e) 
	{ 
		string error(getClassName()); 
		error = error + "::setCenter() - " + e.what(); 
		throw Exception(e); 
	} 
} 
 
void 
RadialBasisNetwork::setWeight(int center, int output, real weight) 
{ 
	try 
	{ 
		CenterNeuron &c = (CenterNeuron&)_centerLayer->getNeuron(center); 
		SimpleNeuron &o = (SimpleNeuron&)_outputLayer->getNeuron(output); 
		o.connect(&c,weight); 
	} 
	catch (Exception &e) 
	{ 
		string error(getClassName()); 
		error = error + "::setWeight() - " + e.what(); 
		throw Exception(error); 
	} 
} 
 
real 
RadialBasisNetwork::getWeight(int center, int output) 
{ 
	try 
	{ 
		SimpleNeuron &o = (SimpleNeuron&)_outputLayer->getNeuron(output); 
		CenterNeuron &c = (CenterNeuron&)_centerLayer->getNeuron(center); 
		return o.getWeight(&c); 
	} 
	catch (Exception &e) 
	{ 
		string error(getClassName()); 
		error = error + "::getWeight() - " + e.what(); 
		throw Exception(error); 
	} 
} 
 
void 
RadialBasisNetwork::setBias(int i, real bias) 
{ 
	try 
	{ 
		SimpleNeuron &n = (SimpleNeuron&)(_outputLayer->getNeuron(i)); 
		n.setBias(bias); 
	} 
	catch (Exception &e) 
	{ 
		string error(getClassName()); 
		error = error + "::setBias() - " + e.what(); 
		throw Exception(e); 
	} 
} 
 
real 
RadialBasisNetwork::getBias(int i) 
{ 
	try 
	{ 
		SimpleNeuron &n = (SimpleNeuron&)(_outputLayer->getNeuron(i)); 
		return n.getBias(); 
	} 
	catch (Exception &e) 
	{ 
		string error(getClassName()); 
		error = error + "::setBias() - " + e.what(); 
		throw Exception(e); 
	} 
} 
 
VECTOR 
RadialBasisNetwork::getOutput(real *input) 
{	return Network::getOutput(input);	} 
 
const char * 
RadialBasisNetwork::getClassName() 
{	return "RadialBasisNetwork";	} 
 
int 
RadialBasisNetwork::getCenterCount() 
{	return _nCenters;	} 
 
void 
RadialBasisNetwork::setCenterActivationFunction(ActivationFunction f,ActivationFunction df) 
{ 
	int i; 
	for (i=0;igetNeuron(i); 
		c.setActivationFunction(f,df); 
	} 
} 
 
void 
RadialBasisNetwork::removeBias(int i) 
{ 
	try 
	{ 
		SimpleNeuron &o = (SimpleNeuron&)_outputLayer->getNeuron(i); 
		o.removeBias(); 
	} 
	catch (Exception &e) 
	{ 
		string error(getClassName()); 
		error = error + "::removeBias() - " + e.what(); 
		throw Exception(error); 
	} 
} 
 
void 
RadialBasisNetwork::trainWeights(TrainingSet &T) 
{ 
	if (T.getInputSize() != getInputCount()) 
	{ 
		string error(getClassName()); 
		error = error + "::trainWeights() - Invalid TrainingSet provided."; 
		throw Exception(error); 
	} 
 
	int output; 
	int i,j; 
	int p = T.getSize();		//number of training patters 
	int h = getCenterCount();	//number of centers 
	VECTOR in,y; 
	 
	//do for each output 
	for (output=0; outputgetNeuron(output); 
		if (hasBias = outNrn.hasBias()) 
			effectiveH++; 
 
		//setup matrices 
		Matrix *Y = new Matrix(p, 1); 
		Matrix *W = NULL; 
		Matrix *V = new Matrix(p, effectiveH); 
		Matrix *VT = NULL; 
		if (p!=effectiveH) 
			VT = new Matrix(effectiveH ,p); 
 
		for (i=0;ielementAt(i,j) = _centerLayer->getNeuron(j).getOutput(); 
				if (VT) 
					VT->elementAt(j,i) = V->elementAt(i,j); 
			} 
			if (hasBias) 
			{ 
				V->elementAt(i,j) = 1.0; 
				if (VT) 
					VT->elementAt(j,i) = 1.0; 
			} 
			Y->elementAt(i,0) = y[output]; 
		} // for i=[0..p) 
		 
		if (VT) 
		{ 
			Matrix *VTVinv, *VTY; 
			try 
			{ 
				Matrix *VTV; 
				VTV = VT->multiply(V); 
				VTVinv = VTV->inverse(); 
				delete VTV; 
			} 
			catch (Exception &e) 
			{ 
				string error(getClassName()); 
				error = error + "::trainWeights() - " + e.what(); 
				throw Exception(error); 
			} 
			VTY = VT->multiply(Y); 
			W = VTVinv->multiply(VTY); 
			delete VTVinv; 
			delete VTY; 
		} // if VT 
		else 
		{ 
			Matrix *Vinv; 
			try 
			{ 
				Vinv = V->inverse(); 
			} 
			catch (Exception &e) 
			{ 
				string error(getClassName()); 
				error = error + "::trainWeights() - " + e.what(); 
				throw Exception(error); 
			} 
			W = Vinv->multiply(Y); 
			delete Vinv; 
		} 
			 
		//set the weights 
		for (j=0;jelementAt(j,0)); 
		if (hasBias) 
			outNrn.setBias(W->elementAt(j,0)); 
 
		//cleanup 
		delete Y; 
		delete W; 
		delete V; 
		if (VT) 
			delete VT; 
	} // for (output = 1...total outputs) 
} 
 
void 
RadialBasisNetwork::save(const char *filename) 
{ 
	ofstream s; 
	int i,j; 
	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 "<getNeuron(i); 
		VECTOR center = c.getCenter(); 
		VECTOR::iterator it; 
		for (it = center.begin(); it!=center.end(); it++) 
			s<<(*it)<<" "; 
		s<getNeuron(i); 
		if (o.hasBias()) 
			s<<"t "<getNeuron(jj).toString()<getNeuron(jj).toString()<setInput(in); 
//			//First the weights 
//			for (output=0;outputgetNeuron(output); 
//				o.setDesiredOutput(out[output]); 
//				o.calculateNewWeights(learningRate); 
//			} // for (output = 1...total outputs) 
// 
//			//Now the centers 
//			for (i=0;igetNeuron(i); 
//				c.calculateNewCenter(learningRate); 
//			} 
// 
//			//Updates have been calculated, now make them 
//			for (i=0;igetNeuron(i); 
//				c.update(); 
//			} 
//			for (output=0;outputgetNeuron(output); 
//				o.update(); 
//			} // for (output = 1...total outputs) 
// 
//		} // while (!T.epochOver()) 
//	} // for epochs... 
//} 
 
}; //namespace annie