📄 bp5.cpp
字号:
#include<iostream.h>
#include<math.h>
float sigmoid(float x)
{
float y;
y=1/(1+exp(-1*x));
return y;
}
float myfunction(float x)
{
float y;
// y=x;
y=0.5+0.3*(sin(2*x));
// y=x*x;
// y=exp(-1*x);
// y=-1*x*(x*x-3.2*x+1.7*1.7)*(x-3)/2;
// y=1/x;
return y;
}
void main()
{
int i, p, pt, pp, j, count=0;
int midnumber;//隐层节点数
float **x0;//第0层(输入层)的两个输入
float **y0;//第0层(输入层)的两个输出
float **x1, **y1;//第一层各节点的输入输出
float *x2, *y2;//输出层的输入输出
float **w0, *w1;//两个权矩阵
float *samplex, *sampley;//训练样本对
float *testx, *testy;//推广测试样本对
float *erreach, err, enderr=0.001;//每个样本误差,总误差,期望误差
float **delta0, **delta1;//误差修正向量
float **sumdelta0, *sumdelta1;//总修正量
float **predelta0, *predelta1;//上一次修正量
float step = 0.3;//步长
float moti = 0.2;//动量项因子
cout<<"请输入隐层节点数: ";
cin>>midnumber;
cout<<endl<<"用于训练的样本个数为: ";
cin>>p;
samplex = new float[p];
sampley = new float[p];
erreach = new float[p];
x0=new float*[p];
for(pp=0;pp<p;pp++)
x0[pp]=new float[2];
y0=new float*[p];
for(pp=0;pp<p;pp++)
y0[pp]=new float[2];
x1=new float*[p];
for(pp=0;pp<p;pp++)
x1[pp]=new float[midnumber+1];
y1=new float*[p];
for(pp=0;pp<p;pp++)
y1[pp]=new float[midnumber+1];
x2=new float[p];
y2=new float[p];
w0=new float*[2];
for(i=0;i<2;i++)
w0[i] = new float[midnumber];
w1=new float[midnumber+1];
delta1=new float*[p];
for(pp=0;pp<p;pp++)
delta1[pp]=new float[1];
delta0=new float*[p];
for(pp=0;pp<p;pp++)
delta0[pp]=new float[midnumber+1];
sumdelta0 = new float*[2];
for(i=0;i<2;i++)
sumdelta0[i] = new float[midnumber+1];
sumdelta1 = new float[midnumber+1];
predelta0 = new float*[2];
for(i=0;i<2;i++)
predelta0[i] = new float[midnumber+1];
predelta1 = new float[midnumber+1];
for(i=0;i<2;i++)
for(j=1;j<=midnumber;j++)
predelta0[i][j]=0;
for(j=0;j<=midnumber;j++)
predelta1[j]=0;
////test: 初始化样本及权矩阵////
for(pp=0;pp<p;pp++)
{
samplex[pp]=0.1+0.9*float(pp)/float(p);
sampley[pp]=myfunction(samplex[pp]);
}
/* samplex[p-6]=0.93;
samplex[p-5]=0.95;
samplex[p-4]=0.96;
samplex[p-3]=0.97;
samplex[p-2]=0.98;
samplex[p-1]=0.99;
for(pp=p-6;pp<p;pp++)
{
sampley[pp]=myfunction(samplex[pp]);
}
*/ for(i=0;i<2;i++)
for(j=1;j<=midnumber;j++)
w0[i][j]=0.05;//double(rand())/32767*2-1;//
for(j=0;j<=midnumber;j++)
w1[j]=0.01;//double(rand())/32767*2-1;//
////test: 初始化样本及权矩阵////
//计算各层输入输出
for(pp=0;pp<p;pp++)
{
x0[pp][0]=1;
x0[pp][1]=samplex[pp];
for(i=0;i<2;i++)
y0[pp][i]=x0[pp][i];
x1[pp][0]=1;
y1[pp][0]=1;
for(j=1;j<=midnumber;j++)
{
x1[pp][j]=y0[pp][0]*w0[0][j]+y0[pp][1]*w0[1][j];
y1[pp][j]=sigmoid(x1[pp][j]);
}
x2[pp]=0;
for(j=0;j<=midnumber;j++)
x2[pp]=x2[pp]+y1[pp][j]*w1[j];
y2[pp]=sigmoid(x2[pp]);
erreach[pp] = (y2[pp]-sampley[pp])*(y2[pp]-sampley[pp])/2;
}
//计算p个样本总误差
err = 0;
for(pp=0;pp<p;pp++)
err = err + erreach[pp];
cout<<"初始误差:"<<err<<endl;
while(err>enderr)
// for(count=0;count<10;)
{
count++;
//计算误差修正向量
for(pp=0;pp<p;pp++)
{
for(j=0;j<1;j++)
delta1[pp][j] = (y2[pp]-sampley[pp])*y2[pp]*(1-y2[pp]);
for(j=1;j<=midnumber;j++)
delta0[pp][j] = y1[pp][j]*(1-y1[pp][j])*delta1[pp][0]*w1[j];
}
//初始化各修正值为0
for(i=0;i<2;i++)
for(j=0;j<=midnumber;j++)
sumdelta0[i][j] = 0;
for(i=0;i<=midnumber+1;i++)
sumdelta1[i] = 0;
//w1[j]的修正值
for(j=0;j<=midnumber;j++)
for(pp=0;pp<p;pp++)
sumdelta1[j] = sumdelta1[j] + (delta1[pp][0]*y1[pp][j]);
//w0[0][j]的修正值
for(j=1;j<=midnumber;j++)
for(pp=0;pp<p;pp++)
sumdelta0[0][j] = sumdelta0[0][j]+(delta0[pp][j]*x0[pp][0]);
//w0[1][j]的修正值
for(j=1;j<=midnumber;j++)
for(pp=0;pp<p;pp++)
sumdelta0[1][j] = sumdelta0[1][j]+(delta0[pp][j]*x0[pp][1]);
//修改w1
for(j=0;j<=midnumber;j++)
w1[j] = w1[j] - step*sumdelta1[j];//-moti*predelta1[j];
//修改w0[0][j]
for(j=1;j<=midnumber;j++)
w0[0][j] = w0[0][j] - step*sumdelta0[0][j];//-moti*predelta0[0][j];
//修改w0[0][j]
for(j=1;j<=midnumber;j++)
w0[1][j] = w0[1][j] - step*sumdelta0[1][j];//-moti*predelta0[1][j];
//重新计算各层输入输出
for(pp=0;pp<p;pp++)
{
x0[pp][0]=1;
x0[pp][1]=samplex[pp];
for(i=0;i<2;i++)
y0[pp][i]=x0[pp][i];
x1[pp][0]=1;
y1[pp][0]=1;
for(j=1;j<=midnumber;j++)
{
x1[pp][j]=y0[pp][0]*w0[0][j]+y0[pp][1]*w0[1][j];
y1[pp][j]=sigmoid(x1[pp][j]);
}
x2[pp]=0;
for(j=0;j<=midnumber;j++)
x2[pp]=x2[pp]+y1[pp][j]*w1[j];
y2[pp]=sigmoid(x2[pp]);
erreach[pp] = (y2[pp]-sampley[pp])*(y2[pp]-sampley[pp])/2;
}
//计算p个样本总误差
err = 0;
for(pp=0;pp<p;pp++)
err = err + erreach[pp];
// cout<<err<<" ";
for(i=0;i<2;i++)
for(j=1;j<=midnumber;j++)
predelta0[i][j]=sumdelta0[i][j];
for(j=0;j<=midnumber;j++)
predelta1[j]=sumdelta1[j];
////test w1,w2////
/* cout<<"权值矩阵: "<<endl<<"w0: "<<endl;
for(i=0;i<2;i++)
{
cout<<"w0(0,"<<j<<"): ";
for(j=1;j<=midnumber;j++)
cout<<w0[i][j]<<", ";
cout<<endl;
}
cout<<"w1: "<<endl;
for(j=0;j<=midnumber;j++)
{
cout<<"w1("<<j<<",0): "<<w1[j]<<endl;
}
*/
}
cout<<endl<<"迭代次数为: "<<count<<endl;
//输出权值矩阵
cout<<"权值矩阵: "<<endl<<"w0: "<<endl;
for(i=0;i<2;i++)
{
cout<<"w0(0,"<<j<<"): ";
for(j=1;j<=midnumber;j++)
cout<<w0[i][j]<<", ";
cout<<endl;
}
cout<<"w1: "<<endl;
for(j=0;j<=midnumber;j++)
{
cout<<"w1("<<j<<",0): "<<w1[j]<<endl;
}
cout<<"终止误差:"<<err<<endl;
cout<<"(sampley,y2): "<<endl;
for(pp=0;pp<p;pp++)
cout<<"("<<samplex[pp]<<sampley[pp]<<", "<<y2[pp]<<") ";
cout<<endl;
//推广测试
cout<<endl<<"请输入用于推广测试的样本个数(注意要少于训练样本个数): ";
cin>>pt;
testx = new float[pt];
testy = new float[pt];
for(pp=0;pp<pt;pp++)
{
testx[pp]=0.2+float(pp)/float(2*pt);
testy[pp]=myfunction(testx[pp]);
}
//计算各层输入输出
for(pp=0;pp<p;pp++)
{
x0[pp][0]=1;
x0[pp][1]=testx[pp];
for(i=0;i<2;i++)
y0[pp][i]=x0[pp][i];
x1[pp][0]=1;
y1[pp][0]=1;
for(j=1;j<=midnumber;j++)
{
x1[pp][j]=y0[pp][0]*w0[0][j]+y0[pp][1]*w0[1][j];
y1[pp][j]=sigmoid(x1[pp][j]);
}
x2[pp]=0;
for(j=0;j<=midnumber;j++)
x2[pp]=x2[pp]+y1[pp][j]*w1[j];
y2[pp]=sigmoid(x2[pp]);
erreach[pp] = (y2[pp]-testy[pp])*(y2[pp]-testy[pp])/2;
}
cout<<"样本输入输出为:"<<endl;
for(pp=0;pp<pt;pp++)
cout<<"("<<testx[pp]<<", "<<testy[pp]<<", "<<y2[pp]<<") ";
//计算p个样本总误差
err = 0;
for(pp=0;pp<pt;pp++)
err = err + erreach[pp];
cout<<"推广测试的误差:"<<err<<endl;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -