📄 bpnetmulti.cpp
字号:
#include <iostream.h>
#include <stdio.h>
#include <math.h>
#include <conio.h>
#include <stdlib.h>
int nSamplesNum = 0; //样本数量
int nNodesOfInput = 0; //样本维数,等同于输入层的神经元的个数
int nNodesOfHide = 0; //隐层神经元的个数
int nNodesOfOutput = 0; //输出层神经元的个数
//
double **pDataSource = NULL; //输入的训练数据
double **pDataDesti = NULL; //输入的目标数据
//关于隐层的定义
double **pOutOfHide = NULL; //隐层的输出
//关于输出层的定义
double **pOutOfOutput = NULL; //输出层的输出
//阀值
double *pThrOfOutput = NULL; //输出层的阀值
double *pThrOfHide = NULL; //隐层的阀值
double *pOldThrOfOutput = NULL; //上次输出层的阀值
double *POldThrOfHide = NULL;
//权值的定义
double **pPowHi2In = NULL; //输入层到隐层的权值
double **pPowOu2Hi = NULL; //隐层到输入层的权值
double **pOldPowHi2In = NULL;
double **pOldPowOu2Hi = NULL;
//学习率
double LearnOu2Hi = 0; //输出层至隐层的学习效率
double LearnHi2In = 0; //隐层至输入层的学习效率
//误差
double Pre_Error = 0; //预期误差
double Sum_Error = 0; //每次的总体误差
double Old_Sum_Error = 0;
long int Study = 0; //学习次数
//
double alpha; //动量因子,改进型bp算法使用
FILE *fp;
//
void GetData();
void InitializeNet();
void TrainNet();
void Input_Source(int m);
void Input_Desti(int m);
void Input_Hide();
void Hide_Output();
void Error_Output_Hide(int m);
void Error_Hide_Input(int m);
double Delta_K_L_P( int k,int l,int p );
double Delta_J_K_P(int j,int k,int p);
void Delta_Output_Hide();
void Delta_Hide_Input();
double Error_Sum();
void main ()
{
int i,j,k;
i=j=k=0;
nNodesOfInput = 9;
nNodesOfOutput = 9;
// nNodesOfHide = int((nNodesOfInput+nNodesOfOutput)/2.0+0.5);
nNodesOfHide = 16;
nSamplesNum = 9;
//
Pre_Error = 0.0000001;
// LearnHi2In = 0.9*nSamplesNum;
// LearnOu2Hi = 0.9*nSamplesNum;
LearnHi2In = 0.9;
LearnOu2Hi = 0.9;
alpha = 0.5;
Study = 0;
Sum_Error = 0;
//申请内存
//数据
pDataSource = new double *[nSamplesNum];
for ( i=0;i<nSamplesNum;i++ )
{
pDataSource[i] = new double [nNodesOfInput];
}
pDataDesti = new double *[nSamplesNum];
for ( i=0;i<nSamplesNum;i++ )
{
pDataDesti[i] = new double [nNodesOfOutput];
}
//关于隐层的定义
pOutOfHide = new double *[nSamplesNum];
for ( i=0;i<nSamplesNum;i++ )
{
pOutOfHide[i] = new double [nNodesOfHide];
}
//关于输出层的定义
pOutOfOutput = new double *[nSamplesNum];
for ( i=0;i<nSamplesNum;i++ )
{
pOutOfOutput[i] = new double [nNodesOfOutput];
}
//阀值
pThrOfHide = new double [nNodesOfHide];
POldThrOfHide = new double [nNodesOfHide];
pThrOfOutput = new double [nNodesOfOutput];
pOldThrOfOutput = new double [nNodesOfOutput];
//权值
pPowHi2In = new double *[nNodesOfHide];
for ( i= 0;i<nNodesOfHide;i++ )
{
pPowHi2In[i] = new double [nNodesOfInput];
}
pOldPowHi2In = new double *[nNodesOfHide];
for ( i= 0;i<nNodesOfHide;i++ )
{
pOldPowHi2In[i] = new double [nNodesOfInput];
}
pPowOu2Hi = new double *[nNodesOfOutput];
for ( i=0;i<nNodesOfOutput;i++ )
{
pPowOu2Hi[i] = new double [nNodesOfHide];
}
pOldPowOu2Hi = new double *[nNodesOfOutput];
for ( i=0;i<nNodesOfOutput;i++ )
{
pOldPowOu2Hi[i] = new double [nNodesOfHide];
}
//
GetData();
InitializeNet();
TrainNet();
//释放内存
//数据
for ( i=0;i<nSamplesNum;i++)
{
delete [] pDataSource[i];
}
delete []pDataSource;
for ( i=0;i<nSamplesNum;i++)
{
delete [] pDataDesti[i];
}
delete []pDataDesti;
//关于隐层的定义
for ( i=0;i<nSamplesNum;i++)
{
delete [] pOutOfHide[i];
}
delete []pOutOfHide;
//关于输出层的定义
for ( i=0;i<nSamplesNum;i++)
{
delete [] pOutOfOutput[i];
}
delete []pOutOfOutput;
//阀值
delete []pThrOfHide;
delete []POldThrOfHide;
delete []pThrOfOutput;
delete []pOldThrOfOutput;
//权值
for ( i=0;i<nNodesOfHide;i++)
{
delete [] pPowHi2In[i];
}
delete []pPowHi2In;
for ( i=0;i<nNodesOfHide;i++)
{
delete [] pOldPowHi2In[i];
}
delete []pOldPowHi2In;
for ( i=0;i<nNodesOfOutput;i++ )
{
delete [] pPowOu2Hi[i];
}
delete []pPowOu2Hi;
for ( i=0;i<nNodesOfOutput;i++ )
{
delete [] pOldPowOu2Hi[i];
}
delete []pOldPowOu2Hi;
}
void TrainNet()
{
bool Flag_IsOK = 0; //判断是否达到要求
double Sum_Error_bak1 = 0.;
double Sum_Error_bak2 = 0.;
do
{
Input_Hide();
Hide_Output();
Old_Sum_Error = Sum_Error;
Sum_Error = Error_Sum();
Study++;
if(Study%100 ==0 )
{
printf("Study = %d, Sum_Error = %lf\n",Study,Sum_Error);
}
if ( Study > 20000000 )
{
printf("The program is ended by itself because of error!\nThe learning times is surpassed!\n");
break ;
}
if ( Sum_Error<= Pre_Error )
{
Flag_IsOK = 1;
}
else
{
Delta_Output_Hide();
Delta_Hide_Input();
}
//动态修正学习率
if ((Sum_Error == Sum_Error_bak1)&&(Sum_Error_bak1 == Sum_Error_bak2))
{
LearnHi2In = 0.8*LearnHi2In;
LearnOu2Hi = 0.8*LearnOu2Hi;
}
Sum_Error_bak2 = Sum_Error_bak1;
Sum_Error_bak1 = Sum_Error;
} while( Flag_IsOK ==0 );
printf("Study = %d, Sum_Error = %lf ,Pre_Error = %lf\n",Study,Sum_Error,Pre_Error );
if((fp=fopen("result.txt","w"))==NULL)
{
printf("Cannot open file 'result.txt'!\n strike any key exit! \n");
getch();
exit(1);
}
fprintf( fp,"Study = %d, Sum_Error = %lf ,Pre_Error = %lf\n",Study,Sum_Error,Pre_Error );
fclose( fp );
if((fp=fopen("Hide_Input.txt","w"))==NULL)
{
printf("Cannot open file 'Hide_Input.txt'!\n strike any key exit! \n");
getch();
exit(1);
}
int i,j;
fprintf( fp,"pPowHi2In\n" );
for ( i=0;i<nNodesOfHide;i++ )
{
for ( j=0;j<nNodesOfInput;j++ )
{
fprintf( fp,"%5.4lf\t",pPowHi2In[i][j] );
}
fprintf( fp,"\n");
}
fprintf( fp,"\n");
fprintf( fp,"\n");
fprintf( fp,"pThrOfHide\n" );
for ( i=0;i<nNodesOfHide;i++ )
{
fprintf( fp,"%5.4lf\t",pThrOfHide[i] );
}
fprintf( fp,"\n");
fprintf( fp,"\n");
fclose( fp );
if((fp=fopen("Output_Hide.txt","w"))==NULL)
{
printf("Cannot open file 'Output_Hide.txt'!\n strike any key exit! \n");
getch();
exit(1);
}
fprintf( fp,"pPowOu2Hi\n" );
for ( i=0;i<nNodesOfOutput;i++ )
{
for ( j=0;j<nNodesOfHide;j++ )
{
fprintf( fp,"%5.4lf\t",pPowOu2Hi[i][j] );
}
fprintf( fp,"\n");
}
fprintf( fp,"\n");
fprintf( fp,"\n");
fprintf( fp,"pThrOfOutput\n" );
for ( i=0;i<nNodesOfOutput;i++ )
{
fprintf( fp,"%5.4lf\t",pThrOfOutput[i] );
}
fprintf( fp,"\n");
fprintf( fp,"\n");
fclose( fp );
}
double Error_Sum()
{
int m,i;
double total_err = 0;
double err = 0;
for ( m=0;m<nSamplesNum;m++ )
{
err = 0;
for ( i=0;i<nNodesOfOutput;i++ )
{
err += pow((pDataDesti[m][i] - pOutOfOutput[m][i]),2);
}
total_err += err;
}
total_err /=2;
// total_err /=nSamplesNum;
return total_err;
}
void Delta_Hide_Input()
{
int i,j,k,p;
double temp = 0;
for ( j=0;j<nNodesOfHide;j++ ) //隐层
{
for ( i=0;i<nNodesOfInput;i++ ) //输入层
{
//计算wji
temp = 0;
for ( p=0;p<nSamplesNum;p++ )
{
for ( k=0;k<nNodesOfOutput;k++ )
{
temp += ((pDataDesti[p][k]-pOutOfOutput[p][k])*pOutOfOutput[p][k]*(1.0-pOutOfOutput[p][k]))
*pPowOu2Hi[k][j]*pOutOfHide[p][j]*(1.0-pOutOfHide[p][j])*pDataSource[p][i];
}
}
// temp /= nSamplesNum;
pPowHi2In[j][i] += (alpha*(pPowHi2In[j][i]-pOldPowHi2In[j][i]))+ (LearnHi2In*temp);
pOldPowHi2In[j][i] = pPowHi2In[j][i];
}
}
for ( j=0;j<nNodesOfHide;j++ ) //隐层
{
//计算j
temp = 0;
for ( p=0;p<nSamplesNum;p++ )
{
for ( k=0;k<nNodesOfOutput;k++ )
{
temp += ((pDataDesti[p][k]-pOutOfOutput[p][k])*pOutOfOutput[p][k]*(1.0-pOutOfOutput[p][k]))
*pPowOu2Hi[k][j]*pOutOfHide[p][j]*(1.0-pOutOfHide[p][j]);
}
}
// temp /= nSamplesNum;
pThrOfHide[j] -= (LearnHi2In*(pThrOfHide[j]-POldThrOfHide[j])+LearnHi2In*temp);
POldThrOfHide[j] = pThrOfHide[j];
}
}
double Delta_K_L_P( int k,int l,int p )
{
double temp = 0;
temp = (pDataDesti[p][l]-pOutOfOutput[p][l])*pOutOfOutput[p][l]*(1-pOutOfOutput[p][l]);
return temp;
}
void Delta_Output_Hide()
{
int k,j,p;
double temp = 0;
for ( k=0;k<nNodesOfOutput;k++ ) //输出层
{
for ( j=0;j<nNodesOfHide;j++ ) //隐层
{
temp = 0;
for ( p=0;p<nSamplesNum;p++ )
{
temp += (pDataDesti[p][k]-pOutOfOutput[p][k])*pOutOfOutput[p][k]*(1.0-pOutOfOutput[p][k])*pOutOfHide[p][j];
}
// temp /= nSamplesNum;
pPowOu2Hi[k][j] += (alpha*(pPowOu2Hi[k][j]-pOldPowOu2Hi[k][j]))+ (LearnOu2Hi*temp);
pOldPowOu2Hi[k][j] = pPowOu2Hi[k][j];
}
}
for ( k=0;k<nNodesOfOutput;k++ )
{
temp = 0;
for ( p=0;p<nSamplesNum;p++ )
{
temp += (pDataDesti[p][k]-pOutOfOutput[p][k])*pOutOfOutput[p][k]*(1.0-pOutOfOutput[p][k]);
}
// temp /= nSamplesNum;
pThrOfOutput[k] -= (LearnOu2Hi*(pThrOfOutput[k]-pOldThrOfOutput[k])+LearnOu2Hi*temp);
pOldThrOfOutput[k] = pThrOfOutput[k];
}
}
double Delta_J_K_P(int j,int k,int p)
{
double temp = 0;
for ( int l=0;l<nNodesOfOutput;l++ )
{
temp += Delta_K_L_P(k,l,p)*pOutOfHide[p][k]*(1-pOutOfHide[p][k]);
}
return temp;
}
void Hide_Output()
{
int k,j,p;
//
for( p=0;p<nSamplesNum;p++) //样本
{
for ( k=0;k<nNodesOfOutput;k++ )
{
pOutOfOutput[p][k] = 0;
for ( j=0;j<nNodesOfHide;j++ )
{
pOutOfOutput[p][k] += pPowOu2Hi[k][j]*pOutOfHide[p][j];
}
pOutOfOutput[p][k] -= pThrOfOutput[k];
pOutOfOutput[p][k] = 1.0 /( 1.0+exp( -pOutOfOutput[p][k] ) );
}
}
}
void Input_Hide()
{
int i,j,p;
//
for( p=0;p<nSamplesNum;p++) //样本
{
for ( j=0;j<nNodesOfHide;j++ )
{
pOutOfHide[p][j] = 0;
for ( i=0;i<nNodesOfInput;i++ )
{
pOutOfHide[p][j] += pPowHi2In[j][i]*pDataSource[p][i];
}
pOutOfHide[p][j] -= pThrOfHide[j];
pOutOfHide[p][j] = 1.0 /( 1.0+exp( -pOutOfHide[p][j] ) );
}
}
}
void InitializeNet()
{
int i,j,k;
i = j = k =0;
for ( j=0;j<nNodesOfHide;j++ )
{
for ( i=0;i<nNodesOfInput;i++ )
{
pPowHi2In[j][i] = ((double(rand())/RAND_MAX)*2-1);
pOldPowHi2In[j][i] = pPowHi2In[j][i];
}
}
for ( k=0;k<nNodesOfOutput;k++)
{
for ( j=0;j<nNodesOfHide;j++)
{
pPowOu2Hi[k][j] = ((double(rand())/RAND_MAX)*2-1);
pOldPowOu2Hi[k][j] = pPowOu2Hi[k][j];
}
}
for ( i=0;i<nNodesOfHide;i++ )
{
pThrOfHide[i] = ((double(rand())/RAND_MAX)*2-1);
POldThrOfHide[i] = pThrOfHide[i];
}
for ( i=0;i<nNodesOfOutput;i++ )
{
pThrOfOutput[i] = ((double(rand())/RAND_MAX)*2-1);
pOldThrOfOutput[i] = pThrOfOutput[i];
}
printf("InitializeNet over !\n");
}
void GetData()
{
/*读取训练样本*/
int i,j,k;
double datr;
datr = 0;
i = j = k =0;
if((fp=fopen("datas1.txt","r"))==NULL)
{
printf("Cannot open file 'datas1.txt'!\n strike any key exit! \n");
getch();
exit(1);
}
k = 0;
i = j =0;
while(fscanf(fp,"%lf",&datr)!=EOF)
{
if ( k<nSamplesNum*nNodesOfInput)
{
pDataSource[i][j] = datr;
j++;
if ( j==nNodesOfInput)
{
j = 0;
i++;
}
k++;
}
else
{
if ( k == nSamplesNum*nNodesOfInput)
{
i = j =0;
}
pDataDesti[i][j] = datr;
j++;
if ( j==nNodesOfOutput)
{
j = 0;
i++;
}
k++;
}
}
fclose(fp);
printf("\nThere are [%d] datats that have been loaded successfully!\n",k);
return ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -