?? mybp.cpp
字號:
// mybp.cpp : Defines the entry point for the console application.//
#include "stdafx.h"
#include <iostream.h>
#include <iomanip.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <time.h>
#define N 5//樣本的訓練個數
#define IN 4//輸入層神經元數目
#define HN 1//隱層神經元數目
#define ON 5//輸出層神經元數目
class bpnet
{
public:
bpnet();
virtual ~bpnet();
Setbp();
bp_learning(int m);
bp_testing();
private:
double P[N][IN];//單個樣本輸入數據
double T[N][ON];//單個樣本輸出數據
double W[IN][HN];//輸入層至隱層權值
double V[HN][ON];//隱層至輸出層權值
double X[HN];//隱層的輸入
double Y[ON];//輸出層的輸入
double H[HN];//隱層的輸出
double O[ON];//輸出層的輸出
double sita[HN];//隱層的閾值
double gama[ON];//輸出層的閾值
double err_m[N];//第m個樣本的總誤差
double d_err[ON];//輸出層神經元的一般化誤差
double e_err[HN];//隱層各神經元的一般化誤差
double alpha;//輸出層至隱層的學習效率
double beta;//隱層至輸入層學習效率
double Pre_error;//預定誤差
double inputp[N][IN];
double inputt[N][ON];
double alphaset;
double betaset;
double Testing[IN];
};
bpnet::bpnet()
{
int i,j;
//隱層權、閾值初始化//
cout<<"隱層初始化權值是:"<<endl;
srand((unsigned)(time(NULL)));
for (i=0;i<IN;i++)
{
for (j=0;j<HN;j++)
{
W[i][j]=(float)(rand())/(32767);//隱層權值初始化
printf("W[%d][%d]=%f\n",i,j,W[i][j]);
}
}
cout<<"隱層的初始化閾值是:"<<endl;
for (j=0;j<HN;j++)
{
sita[j]=(float)(rand())/RAND_MAX;//隱層閾值初始化
printf("sita[%d]=%f\n",j,sita[j]);
}
//輸出層權、閾值初始化//
cout<<"輸出層的初始化權值是:"<<endl;
for (int k=0;k<HN;k++)
{
for (int m=0;m<ON;m++)
{
V[k][m]=(float)(rand())/(32767);//輸出層權值初始化
printf("V[%d][%d]=%f\n",k,m,V[k][m]);
}
}
cout<<"輸出層的初始化閾值是:"<<endl;
for (int m=0;m<ON;m++)
{
gama[m]=(float)(rand())/RAND_MAX;//輸出層閾值初始化
printf("gama[%d]=%f\n",m,gama[m]);
}
}
bpnet::Setbp()
{
cout<<"請輸入訓練神經網絡的輸入樣本:"<<endl;
for (int i=0;i<N;i++)
{
printf("第%d組輸入樣本是:\n",i+1);
{
for(int j=0;j<IN;j++)
cin>>inputp[i][j];
}
}
cout<<"請輸入訓練神經網絡的輸出樣本:"<<endl;
for (i=0;i<N;i++)
{
printf("第%d組輸出樣本是:\n",i+1);
{
for(int k=0;k<ON;k++)
cin>>inputt[i][k];
}
}
for (i=0;i<N;i++)
{
for(int j=0;j<IN;j++)
P[i][j]=inputp[i][j];
for (int k=0;k<ON;k++)
T[i][k]=inputt[i][k];
}
cout<<"請輸入輸出層到隱含層學習效率: "<<endl<<"alpha=";
cin>>alphaset;
if(alphaset>1)
{
cout<<"請輸入0-1之間的數!"<<endl;
cin>>alphaset;
}
alpha=alphaset;
cout<<"請輸入隱含層到輸入層學習效率:"<<endl<<"beta=";
cin>>betaset;
if(betaset>1)
{
cout<<"請輸入0-1之間的數!"<<endl;
cin>>betaset;
}
beta=betaset;
}
//////////////////
//bp網絡訓練//////
//////////////////
bpnet::bp_learning(int m)
{
double sigma=0.0;
printf("隱層的輸入X[HN]和輸出H[HN]分別為:\n");
for(m=0;m<N;m++)
{
for(int i=0;i<IN;i++)
for(int j=0;j<HN;j++)
{
sigma+=P[m][i]*W[i][j];//求隱層內積
X[j]=sigma-sita[j];//求隱層輸入
H[j]=1.0/(1.0+exp(-X[j]));//求隱層輸出
cout<<"X["<<j<<"]="<<setw(10)<<X[j]<<" ";
//printf("X[%d]=%f ",j,X[j]);
cout<<"H["<<j<<"]="<<setw(10)<<H[j]<<endl;
//printf("H[%d]=%f\n",j,H[j]);
}
}
printf("輸出層的輸入Y[ON]和輸出O[ON]分別為:\n");
for (int k=0;k<ON;k++)
{
for (int j=0;j<HN;j++)
{
sigma+=H[j]*V[j][k];//求輸出層內積
Y[k]=sigma-gama[k];//求輸出層凈輸入
O[k]=1.0/(1.0+exp(-Y[k]));//求輸出層輸出
cout<<"Y["<<k<<"]="<<setw(10)<<Y[k]<<" ";
//printf("Y[%d]=%f ",k,Y[k]);
cout<<"O["<<k<<"]="<<setw(10)<<O[k]<<endl;
//printf("O[%d]=%f\n",k,O[k]);
}
}
double abs_err[ON];//每個樣本的絕對誤差都是從0開始的
double sqr_err=0;//每個樣本的平方誤差計算都是從0開始的
for (k=0;k<ON;k++)
{
abs_err[k]=T[m][k]-O[k]; //求第m個樣本下的第k個神經元的絕對誤差
sqr_err+=(abs_err[k])*(abs_err[k]);//求第m個樣本下輸出層的平方誤差
d_err[k]=abs_err[k]*O[k]*(1.0-O[k]);//輸出層各神經元的一般化誤差
}
err_m[m]=sqr_err/2;//第m個樣本下輸出層的誤差/2=第m個樣本的誤差
cout<<"第m個樣本的誤差為:"<<err_m[m]<<endl;
for (int j=0;j<HN;j++)
{
for (int k=0;k<ON;k++)
{
sigma=d_err[k]*V[k][j];
}
e_err[j]=sigma*H[j]*(1-H[j]);//隱層各神經元的一般化誤差
}
cout<<"調整后輸出層的閾值gama[ON]和權值V[HN][ON]分別是:"<<endl;
for (k=0;k<ON;k++)
{
gama[k]+=alpha*d_err[k];//輸出層至隱層的權值調整
printf("gama[%d]=%f\n",k,gama[k]);
}
for(k=0;k<ON;k++)
for (int j=0;j<HN;j++)
{
V[j][k]+=alpha*d_err[k]*H[j];//輸出層至隱層的閾值調整
printf("V[%d][%d]=%f\n",j,k,V[j][k]);
}
cout<<"調整后隱層的閾值sita[HN]和權值W[IN][HN]分別是:"<<endl;
for(j=0;j<HN;j++)
{
sita[j]+=beta*e_err[j];//隱層至輸入層的閾值調整
printf("sita[%d]=%f\n",j,sita[j]);
}
for(j=0;j<HN;j++)
for (int i=0;i<IN;i++)
{
for(m=0;m<N;m++)
W[i][j]+=beta*e_err[j]*P[m][i];//隱層至輸入層的權值調整
printf("W[%d][%d]=%f\n",i,j,W[i][j]);
}
double total_err=0;
for (m=0;m<N;m++)
total_err+=err_m[m];//每個樣本的均方誤差加起來就成了全局誤差
cout<<"全局誤差是:"<<total_err<<endl;
}
////////////////////////
///bp網絡性能驗證///////
////////////////////////
bpnet::bp_testing()
{
cout<<"下面進行神經網絡性能的驗證!"<<endl;
cout<<"請輸入驗證神經網絡的樣本:"<<endl;
for (int i=0;i<IN;i++)
{
cin>>Testing[i];
}
double sigma=0.0;
for(i=0;i<IN;i++)
for(int j=0;j<HN;j++)
{
sigma+=Testing[i]*W[i][j];//求隱層內積
X[j]=sigma-sita[j];//求隱層輸入
H[j]=1.0/(1.0+exp(-X[j]));//求隱層輸出
}
printf("輸出層輸出為:\n");
for (int k=0;k<ON;k++)
{
for (int j=0;j<HN;j++)
{
sigma+=H[j]*V[j][k];//求輸出層內積
Y[k]=sigma-gama[k];//求輸出層凈輸入
O[k]=1.0/(1.0+exp(-Y[k]));//求輸出層輸出
cout<<"O["<<k<<"]="<<setw(20)<<O[k]<<endl;
//printf("O[%d]=%f\n",k,O[k]);
}
}
}
bpnet::~bpnet()
{
}
main(int argc, char* argv[])
{
bpnet MY;
MY.Setbp();
double total_err=0.0;
double Pre_error;
cout<<"請輸入預定誤差:"<<endl;
cin>>Pre_error;
int study=0;
if(total_err<Pre_error)
{
for (int m=0;m<N;m++)
{
MY.bp_learning(m);
++study;
} //全部樣本訓練完畢
}
cout<<"網絡已經學習了"<<study<<"次"<<endl;
MY.bp_testing();
char s;
cout<<"請隨便輸入一個字符,按回車退出程序!"<<endl;
cin>>s;
return 1;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -