BP实验报告.docx
- 文档编号:18321586
- 上传时间:2023-08-15
- 格式:DOCX
- 页数:32
- 大小:61.05KB
BP实验报告.docx
《BP实验报告.docx》由会员分享,可在线阅读,更多相关《BP实验报告.docx(32页珍藏版)》请在冰点文库上搜索。
BP实验报告
BP实验报告
学生姓名程战战
专业/班级计算机91
学号09055006
所在学院电信学院
指导教师鲍军鹏
提交日期2012/6/15
1实验目的
用java语言实现BP网络,解决一个简单的曲线拟合(预测)问题。
要求训练数据不少于400个点,测试数据不少于100个点。
在神经网络训练过程中要记录下误差,最后画出整个学习过程中的网络误差变化曲线。
2实验原理
基本思想是:
样本集:
S={(X1,Y1),(X2,Y2),⋯,(Xs,Ys)}
逐一地根据样本集中的样本(Xk,Yk)计算出实际输出Ok及其误差E1,然后对各层神经元的权值W
(1),W
(2),⋯,W(L)各做一次调整,重复这个循环,直到∑Ep<ε(所有样本的误差之和)。
用输出层的误差调整输出层权矩阵,并用此误差估计输出层的直接前导层的误差,再用输出层前导层误差估计更前一层的误差。
如此获得所有其它各层的误差估计,并用这些估计实现对权矩阵的修改。
形成将输出端表现出的误差沿着与输入信号相反的方向逐级向输入端传递的过程。
基本过程是:
样本:
(输入向量,理想输出向量)
1、权初始化:
“小随机数”与饱和状态;“不同”的权值保证网络可以学。
2、向前传播阶段:
(1)从样本集中取一个样本(Xp,Yp),将Xp输入网络;
(2)计算相应的实际输出Op:
Op=FL(⋯(F2(F1(XpW
(1))W
(2))⋯)W(L))
3、向后传播阶段——误差传播阶段:
(1)计算实际输出Op与相应的理想输出Yp的差。
(2)按极小化误差的方式调整权矩阵。
(3)累计网络关于整个样本集的误差。
4、如果网络误差足够小,则停止训练。
否则重复第2、3步。
算法伪码:
样本:
(输入向量,理想输出向量)
1、权初始化:
“小随机数”与饱和状态;“不同”的权值保证网络可以学。
2、向前传播阶段:
(1)从样本集中取一个样本(Xp,Yp),将Xp输入网络;
(2)计算相应的实际输出Op:
Op=FL(⋯(F2(F1(XpW
(1))W
(2))⋯)W(L))
3、向后传播阶段——误差传播阶段:
(1)计算实际输出Op与相应的理想输出Yp的差。
(2)按极小化误差的方式调整权矩阵。
(3)累计网络关于整个样本集的误差。
4、如果网络误差足够小,则停止训练。
否则重复第2、3步。
本次实验采用的是三层感知器模型,如下图;其中有40个权值需要初始化,在这里,每个
权值都各不相同。
固定权固定权可调权
x1y1
x2
x3y2
输入层隐层输出层
3实验结果
其中,纵轴代表误差,横轴代表样本的次数。
可以看到,随着训练次数的增加,误差逐渐靠近x轴,逐渐减小。
4实验源代码
主程序:
//packageBackPropagation;
importjava.util.Vector;
publicclassBackPropagation{
double
leaning_rate
=0.7;
//
表示学习速率
double
min_error
=0.0001;
//
足够小的误差
double
weight
[];
//
用于存放生成的所有权值
Vector
vc1,vc2,vc3;//用于存放不同层的权值
double
ep[]=
new
double[400];
//用于存放每个训练样本的误差
double
ep2[]=
new
double
[100];
//用于存放每个学习样本的误差
Sample
sa=
newSample();
//学习样本的初始化
double
input
[]=
newdouble[4];
//用于存放输入层每个神经元总的输入
double
in_output
[]=
new
double
[4];
//用于存放输入层的输出结果
double
hidden_in
[]=
new
double
[3];
//用于存放隐层每个神经元总的输入
double
hidden_output
[]=
new
double
[3];//用于存放隐层的输出结果
double
o_in[]=
new
double
[2];
//用于存放输出层每个神经元总的输入
double
o_put
[]=
newdouble[2];
//用于存放输出层输出结果
BackPropagation(){
init_weight();
practice(400);
study(100);
}
public
boolean
isInarr(
double
arr[],
intn,doublea){//判断a是否在数组arr
的前n个元素中
int
temp=0;
for(int
i=0;i if (arr[i]==a){ temp=1; break; } } if(temp==1)returntrue;//如果在则返回true elsereturnfalse; } public voidinit_weight(){ // 初始化各层神经元的权值 int i,j=0,k; weight = new double [30]; for (i=0;i<30;i++){ weight [i]=Math. random (); while (isInarr( weight i, weight [i])){ //使初始化的各个权值各不相同 weight [i]=Math. random(); } } vc1 = newVector // 向量 vc2 = newVector vc3 = newVector (2); for (i=0;i<4;i++){ // 存放第一层的权值 Vector newVector for (k=0;k<3;k++){ vc11.add(weight[j++]); //末尾增加 double } vc1.add(vc11); //增加向量 } for (i=0;i<3;i++){//存放第二层的权值 Vector for(k=0;k<4;k++){ vc22.add(weight[j++]); } vc2.add(vc22); } for (i=0;i<2;i++){//存放第三层的权值 Vector for(k=0;k<3;k++){ vc33.add(weight[j++]); } vc3.add(vc33); } } publicvoidoutput(doubleaa[]){//根据输入向量aa产生最后的输出,三层的输出 doublex1,x2,x3; intj=0; x1=aa[0]; x2=aa[1]; x3=aa[2]; for(j=0;j<4;j++){//计算input[],in_output[]//三个输入乘以权值的相加 input[j]= x1*(((Vector x2*(((Vector (1)).doubleValue()+ x3*(((Vector (2)).doubleValue(); in_output[j]=1/(1+Math.pow(Math.E,-input[j]));//s形函数 in_output } for(j=0;j<3;j++){//计算hidden_in[],hidden_output[] hidden_in[j]= [0]*(((Vector in_output [1]*(((Vector vc2.get(j)).get (1)).doubleValue()+ in_output [2]*(((Vector vc2.get(j)).get (2)).doubleValue()+ in_output [3]*(((Vector hidden_output[j]=1/(1+Math.pow(Math.E,-hidden_in [j])); } for(j=0;j<2;j++){ o_in[j]= hidden_output[0]*(((Vector vc3.get(j)).get(0)).doubleValue()+ hidden_output [1]*(((Vector vc3.get(j)).get (1)).doubleValue()+ hidden_output o_put [2]*(((Vector (2)).doubleValue();[j]=1/(1+Math.pow(Math.E,-o_in[j])); } } publicdoublecalculate_ep(doubleoutput1[],intn){//根据第n个样本的实际输 出output1[]计算输出误差 doubleexpect[]=(double[]) (((Vector (1)); doubleep1; ep1= (Math.pow(output1[0]-expect[0],2)+Math.pow(output1[1]-expect[1],2))/2;//7-1 3公式 return ep1; } publicdouble[]adjust_outputlevel_weight( 层的权值根据7-15 doubleoutput_error[]=newdouble [2]; intn){//根据第n个样本来调整输出 //用于存放输出层每个神经元的输出 误差 doubletemp[]=(double [])((Vector (1);//得到期望输出 Vector doubleincrement=0.0;//表示权值的增量 doubleweight_temp; output((double[])((Vector //得 到实际输出 for (inti=0;i<2;i++){//对于第i个神经元vctemp=(Vector [i])*(temp[i]- o_put[i]); increment=leaning_rate*output_error[i]*hidden_output[j]; weight_temp=((Double) vctemp.get(j)).doubleValue()+increment; vctemp.add(j,weight_temp); } } returnoutput_error; } publicdouble[]adjust_secondlevel_weight(intn){//根据第n个样本来调整隐 层的权值 根据7-167-17 inti=0,j=0; doubleoutput_error[]= new double [3]; //用于存放隐层每个神经元的输出误 差 doubletemp[]=adjust_outputlevel_weight(n); //得到输出层每个神经元的 输出误差 for(i=0;i<3;i++){ output_error[i]= hidden_output [i]*(1- hidden_output [i])* (((Double)((Vector vc3.get(0)).get(i)).doubleValue()*temp[0]+ ((Double)((Vector (1)).get(i)).doubleValue()*temp[1]); } Vector doubleincrement; for(i=0;i<3;i++){ vctemp=(Vector for(j=0;j<4;j++){ increment=leaning_rate*output_error[i]*in_output [j]; vctemp.add(j,((Double)vctemp.get(j)).doubleValue()+increment); } } return output_error; } 值 publicvoidadjust_firstlevle_weight(int 7-16和7-17 inti=0,j=0; doubleoutput_error[]=newdouble[4]; n){//根据第n个样本来调整输入层的权 //用于存放输入层每个神经元的输出 误差 double temp[]=adjust_secondlevel_weight(n); //得到隐层每个神经元的输 出误差 for (i=0;i<4;i++){ output_error[i]= in_output [i]*(1- in_output [i])* (((Double)((Vector vc2.get(0)).get(i)).doubleValue()*temp[0]+ ((Double)((Vector vc2.get (1)).get(i)).doubleValue()*temp[1]+ ((Double)((Vector } Vector doubleincrement; doublenum[]; vc2.get (2)).get(i)).doubleValue()*temp[2]); for [])((Vector< (i=0;i<4;i++){ vctemp=(Vector for(j=0;j<3;j++){ num=(double double[]>)sa.hashmap.get(n)).get(0); increment=leaning_rate*output_error[i]*num[j]; vctemp.add(j,((Double)vctemp.get(j)).doubleValue()+increment); } } //returnoutput_error; } publicvoidpractice(intn){//n表示样本数量训练过程 inti=0; intt=0;//临时变量,用于select_small()的返回值,表示第t个样本 doublesum=1;//表示样本集误差总和 ints=0; doubletemp=0; while(sum>min_error){ sum=0; for(i=0;i output(((Vector temp=calculate_ep(o_put,i); sum+=temp; if(s==0){ ep[i]=temp; } adjust_firstlevle_weight(i); } s++; } /*for(i=0;i<400;i++){ System.out.println(ep[i]); }*/ } public for voidstudy(intn){ (inti=0;i output(((Vector< ep2[i]=calculate_ep( System.out.println( //测试 double[]>)sa.hashmap2.get(i)).get(0)); o_put,i); ep2[i]); } } } 样本和测试程序: //packageBackPropagation; importjava.util.HashMap; importjava.util.Map; importjava.util.Vector; publicclassSample{ Vector doublex[],y[]; Map Map Sample(){ x=newdouble[3]; y=newdouble[2]; z=newVector (2); hashmap=newHashMap hashmap2=newHashMap for(inti=0;i<400;i++){//400个样本 for(intj=0;j<3;j++){ x[j]=Math.random()*100; } for(intk=0;k<2;k++){ y[k]=Math.random()*100; } z.add(x); z.add(y); hashmap.put(i,z); } for(inti=0;i<100;i++){ for(intj=0;j<3;j++){ x[j]=Math.random(); } for(intk=0;k<2;k++){ y[k]=Math.random(); } z.add(x); z.add(y); hashmap2.put(i,z); } } } 作图程序: //packageBackPropagation; importjava.awt.Color; importjava.awt.Frame; importjava.awt.Graphics; publicclassCurveextendsFrame{ BackPropagationbp=newBackPropagation(); doubletemp[]=bp.ep; publicvoidpaint(Graphicsg){ this.setBackground(Color.GRAY); g.setColor(Color.BLACK); for(inti=0;i<100;i++){ g.drawLine(i*10,(int)(temp[i]*10000),(i+1)*10,(int)(temp[i+1]*10000));//System.out.println((int)(temp[i]*10000)); } //g.drawLine(0,325,600,125); } publicstaticvoidmain(String[]args){ Curvecurve=newCurv
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- BP 实验 报告