⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 neuralnet.cpp

📁 神经网络的结构实现
💻 CPP
字号:
#include "NeuralNet.h"
#include <math.h>

const int NeuralNet::max_iterator=1000;

bool NeuralNet::LoadData(ifstream &fin)			//load the train samples data
//file format
//0: dimension d_output
//...
{
	int m(0),n(0);
	
	if(!fin)return false;
	int i;
	string str;
	
	while(!fin.eof()) 
	{ 
		getline(fin,str);//get the number of the samples

		if (str.size() == 0)//blank
		{
			continue;
		}
		m++;
		int k=0;
		
		if(1 == m)	// the first line: get the dimension of input and the dimension of output
		{
			for(i=0;i<str.size();i++)
			{
				string t_str="";
				while(str[i] != ' '&& str[i] != '\n' && i<str.size())
				{
					t_str+=str[i];
					i++;
				}
				k++;
				
				if( 1==k)
				{
					dimension = atof(t_str.c_str());
					if(dimension != num_input)
					{
						cout<<"input dimension error!";
						return false;
					}
				}
				else if(2 == k)
				{
					d_output = atof(t_str.c_str());
					if(d_output != num_output)
					{
						cout<<"output dimension error!";
						return false;
					}
				}
				else
				{
					
				}
			}
			
		}
		else
		{	
			PR_unit* unit = new PR_unit();
			
			for(i=0;i<str.size();i++)
			{
				string t_str="";
				while(str[i] != ' '&& str[i] != '\n' && i<str.size())
				{
					t_str+=str[i];
					i++;
				}
				k++;
				
				
				if( k <= dimension)
				{	
					unit->unit.push_back(atof(t_str.c_str()));
				}
				else
				{
					unit->dest.push_back( atof(t_str.c_str()) );
				}
				
			}
			samples.push_back(unit);
		}
		
		
	}
	num_samples = m;

	dest = new PR_unit(d_output);
	return true;
}

void NeuralNet::InitialWeight()
{
	srand((unsigned int)time((time_t *)NULL));
	for (int m =1;m<layers.size();m++)
	{
		for (int i=0;i<layers[m]->num;i++)
		{
			for (int j=0;j<(*layers[m])[i]->weight.size();j++)
			{
				double value = (double)rand() / ((double)RAND_MAX + 1);
				SetWeight(m,i,j,value);
			}
		}
	}
}
double NeuralNet::GetWeight(int m,int i,int j)	//get the j weight of the i cell in m layer
{
	return (*layers[m])[i]->GetWeight(j);
}
void NeuralNet::SetWeight(int m,int i,int j,double value)		//set the j weight of the i cell in m layer
{
	(*layers[m])[i]->SetWeight(j,value);
}
double NeuralNet::GetLastWeight(int m,int i,int j)	//get the j weight of the i cell in m layer
{
	return (*layers[m])[i]->GetLastWeight(j);
}
double NeuralNet::GetOutput(int m,int i)			//get the i output in m layer
{
	return (*layers[m])[i]->GetValue();
}
void NeuralNet::PrintStruct()
{
	for (int i=layers.size()-1;i>=0;i--)
	{	
		cout<<"layer"<<i<<":\t(";
		for (int j=0;j< layers[i]->num;j++)
		{
			cout<<(*layers[i])[j]->name;
			if((*layers[i])[j]->hidden)
			{
				cout<<"_";
			}
			if ((*layers[i])[j]->input.size() > 0)
			{
				cout<<"->";
				for (int k=0;k<(*layers[i])[j]->input.size();k++)
				{
					cout<<(*layers[i])[j]->input[k]->name;

					if ((*layers[i])[j]->input[k]->hidden)
					{
						cout<<"_";
					}
				}
			}
			if(j < layers[i]->num -1)
			{
				cout<<",";
			}
		}
		cout<<")"<<endl;
	}
}
void NeuralNet::PrintSamples()
{
	cout<<"\nSamples:"<<endl;
	for(int i=0;i<samples.size();i++)
	{
		cout<<i<<":\t";
		samples[i]->Print();
		cout<<endl;
	}
}

void NeuralNet::PrintWeight()
{
	cout<<"\nW:"<<endl;
	for (int m =layers.size()-1;m >=0;m--)
	{
		cout<<"layer"<<m<<":";
		for (int i=0;i<layers[m]->num;i++)
		{
			if(0 == m)
			{
				cout<<"↑ ";
			}
			else
			{
				cout<<"(";
				for (int j=0;j<(*layers[m])[i]->weight.size();j++)
				{
					cout<<GetWeight(m,i,j)<<" ";
				}
				cout<<")";
			}
			
		}
		cout<<endl;
	}
}
void NeuralNet::ChooseSample(PR_unit *unit)
{
	int i;
	for (i=0;i<layers[0]->num-1;i++)	//sub a hidden node
	{
		(*layers[0])[i]->value	= (*unit)[i];
	}
	for (i=0;i<d_output;i++)
	{
		dest->unit[i] = unit->dest[i];
		//double dd = (*dest)[i];
	}
}
void NeuralNet::CalcOutput()
{
	for (int m =1;m<layers.size();m++)
	{
		for (int i=0;i<layers[m]->num;i++)
		{
			(*layers[m])[i]->UpdateOutput();
		}
	}
}
void NeuralNet::PrintOutput()
{
	cout<<"\nOutput:"<<endl;
	for (int m =layers.size()-1;m >=0;m--)
	{
		cout<<"layer"<<m<<":";
		for (int i=0;i<layers[m]->num;i++)
		{
			cout<<GetOutput(m,i)<<" ";
		}
		cout<<endl;
	}
}

void NeuralNet::PrintDelta()
{
	cout<<"\nDelta:"<<endl;
	for (int m =layers.size()-1;m >0;m--)
	{
		cout<<"layer"<<m<<":";
		for (int i=0;i<layers[m]->num;i++)
		{
			if((*layers[m])[i]->hidden)
			{
				continue;
			}
			cout<<(*layers[m])[i]->delta<<" ";
		}
		cout<<endl;
	}
}
void NeuralNet::PrintError()
{
	cout<<"\nError:"<<error<<endl;
}

void NeuralNet::SaveWeightData()
{
	ofstream fout("weight.txt");
// 	if (!fout)
// 	{
// 		fout.open("weight.txt");
// 	}
	//cout<<"\nW:"<<endl;
	for (int m =layers.size()-1;m >0;m--)
	{
		//cout<<"layer"<<m<<":";
		for (int i=0;i<layers[m]->num;i++)
		{
			
				//cout<<"(";
				for (int j=0;j<(*layers[m])[i]->weight.size();j++)
				{
					fout<<GetWeight(m,i,j)<<" ";
				}
				//cout<<")";
			
			
		}
		fout<<endl;
	}
}

void NeuralNet::LoadWeightData()//ifstream &fin
{
	ifstream fin("weight.txt");
	double value;
	for (int m =layers.size()-1;m >0;m--)
	{
		for (int i=0;i<layers[m]->num;i++)
		{
				for (int j=0;j<(*layers[m])[i]->weight.size();j++)
				{
					fin>>value;
					SetWeight(m,i,j,value);
				}
		}
	}
}

double NeuralNet::CalcSampleError()
{
	double yi;
	
	double s_error = 0;
	int m = num_layer - 1;			//final layer
	for (int i=0;i<layers[m]->num;i++)
	{
		yi = (*layers[m])[i]->GetValue();
		s_error += ((*dest)[i] - yi) * ((*dest)[i] - yi);
	}
	s_error = sqrt(s_error);
	return s_error;
}
double NeuralNet::CalcError()
{
	error = 0;
	for(int i=0;i<samples.size();i++)
	{
		error += samples[i]->error * samples[i]->error;
	}
	error = sqrt(error);
	return error;
}
void PerceptionNet::Connect()
{
	for (int i=1;i<layers.size();i++)
	{
		for (int j=0;j< layers[i]->num;j++)
		{
			(*layers[i])[j]->Initial(layers[i-1]);
		}
	}
}


void BPNet::Connect()
{
	for (int i=1;i<layers.size();i++)
	{
		for (int j=0;j< layers[i]->num;j++)
		{
			(*layers[i])[j]->Initial(layers[i-1]);
		}
	}
}
void BPNet::UpdateWight()
{
	for (int m =layers.size()-1;m >0;m--)
	{
		for (int i=0;i<layers[m]->num;i++)
		{
			if((*layers[m])[i]->hidden)
			{
				continue;
			}
			for (int j=0;j<(*layers[m])[i]->weight.size();j++)
			{
				double lastdelta = GetWeight(m,i,j) - GetLastWeight(m,i,j);
				double ww = GetWeight(m,i,j) + yita * (*layers[m])[i]->delta * (*layers[m-1])[j]->GetValue() + alpha* lastdelta;
				SetWeight(m,i,j,ww);
			}
		}
	}
}
void BPNet::Train()
{
	//for (alpha = 0;alpha<=1;alpha+=0.1)
	//alpha=0.2;
	{
		LoadWeightData();
		int num_iter=0;
		do
		{
			//int i=0;
			//cout<<"/////////////////////////////////"<<endl;
			for (int i=0;i<samples.size();i++)
			{
				ChooseSample(samples[i]);
				CalcOutput();
				//PrintOutput();
				CalcDelta();
				//PrintDelta();
				UpdateWight();
				//PrintWeight();
				
				samples[i]->error = CalcSampleError();				
			}
			CalcError();
			//PrintError();
		}while(!(error < thresh_error) && !(num_iter++ > 100000));//max_iterator) );
		
		cout<<"/////////////////////////////////"<<endl;
		cout<<alpha<<endl;
		cout<<"Train end!!"<<endl;
		cout<<"Train time:"<<num_iter-1<<endl;
		cout<<"Error:"<<error<<endl;
		//PrintWeight();
	}
	//ofstream fout("weight.txt");
	//SaveWeightData();
}

void BPNet::CalcDelta()
{
	int m,i,j;
	double yi,dt;
	m = num_layer - 1;			//final layer
	for (i=0;i<layers[m]->num;i++)
	{
		yi = (*layers[m])[i]->GetValue();
		(*layers[m])[i]->delta = yi*(1-yi)*((*dest)[i] - yi);//use the sigmod function
		double dd = (*layers[m])[i]->delta;
	}
	for (m =num_layer-2;m>0;m--)
	{
		for (i=0;i<layers[m]->num;i++)	
		{
			//don't calc the hidden node
			if((*layers[m])[i]->hidden)
			{
				continue;
			}
			yi = (*layers[m])[i]->GetValue();
			for (dt=0,j=0;j<layers[m+1]->num;j++)
			{
				dt += GetWeight(m+1,j,i)*((*layers[m+1])[j]->delta);
			}
			(*layers[m])[i]->delta = yi*(1-yi)*dt;
			//double dd = (*layers[m])[i]->delta;
		}
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -