📄 neuralnet.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 + -