您的位置:首页 > 能源动力 > 润滑油 > BP算法---借鉴

BP算法---借鉴

luyued 发布于 2011-06-08 00:50   浏览 N 次  

   经过最近一段时间的神经网络学习,终于能初步使用matlab实现BP网络仿真试验。这里特别感谢研友sistor2004的帖子《自己编的BP算法(工具:matlab)》和研友wangleisxcc的帖子《用C++,Matlab,Fortran实现的BP算法》前者帮助我对BP算法有了更明确的认识,后者让我对matlab下BP函数的使用有了初步了解。因为他们发的帖子都没有加注释,对我等新手阅读时有一定困难,所以我把sistor2004发的程序稍加修改后加注了详细解释,方便新手阅读。

  %严格按照BP网络计算公式来设计的一个matlab程序,对BP网络进行了优化设计

  %yyy,即在o(k)计算公式时,当网络进入平坦区时(<0.0001)学习率加大, 出来后学习率又还原

  %v(i,j)=v(i,j)+deltv(i,j)+a*dv(i,j); 动量项

  clear all

  clc

  inputNums=3; %输入层节点

  outputNums=3; %输出层节点

  hideNums=10; %隐层节点数

  maxcount=20000; %最大迭代次数

  samplenum=3; %一个计数器,无意义

  precision=0.001; %预设精度

  yyy=1.3; %yyy是帮助网络加速走出平坦区

  alpha=0.01; %学习率设定值

  a=0.5; %BP优化算法的一个设定值,对上组训练的调整值按比例修改

  error=zeros(1,maxcount+1); %error数组初始化;目的是预分配内存空间

  errorp=zeros(1,samplenum); %同上

  v=rand(inputNums,hideNums); %3*10;v初始化为一个3*10的随机归一矩阵; v表输入层到隐层的权值

  deltv=zeros(inputNums,hideNums); %3*10;内存空间预分配

  dv=zeros(inputNums,hideNums); %3*10;

  w=rand(hideNums,outputNums); *3;同V

  deltw=zeros(hideNums,outputNums);*3

  dw=zeros(hideNums,outputNums); *3

  samplelist=[0.1323,0.323,-0.132;0.321,0.2434,0.456 ;-0.6546,-0.3242,0.3255]; %3*3;指定输入值3*3(实为3个向量)

  expectlist=[0.5435,0.422,-0.642;0.1,0.562,0.5675;- 0.6464,-0.756,0.11]; %3*3;期望输出值3*3(实为3个向量),有导师的监督学

  习

  count=1;

  while (count<=maxcount) %结束条件1迭代20000次

  c=1;

  while (c<=samplenum)

  for k=1

  

  utputNums

  d(k)=expectlist(c,k); %获得期望输出的向量,d(1:3)表示一个期望向量内 的值

  end

  for i=1:inputNums

  x(i)=samplelist(c,i); %获得输入的向量(数据),x(1:3)表一个训练向量

  end

  %Forward();

  for j=1:hideNums

  net=0.0;

  for i=1:inputNums

  net=net+x(i)*v(i,j);%输入层到隐层的加权和∑X(i)V(i)

  end

  y(j)=1/(1+exp(-net)); %输出层处理f(x)=1/(1+exp(-x))单极性sigmiod函数

  end

  for k=1

  

  utputNums

  net=0.0;

  for j=1:hideNums

  net=net+y(j)*w(j,k);

  end

  if count>=2&&error(count)-error(count+1)<=0.0001

  o(k)=1/(1+exp(-net)/yyy); %平坦区加大学习率

  else o(k)=1/(1+exp(-net)); %同上

  end

  end

  %BpError(c)反馈/修改;

  errortmp=0.0;

  for k=1

  

  utputNums

  errortmp=errortmp+(d(k)-o(k))^2; %第一组训练后的误差计算

  end

  errorp(c)=0.5*errortmp; %误差E=∑(d(k)-o(k))^2 * 1/2

  %end

  ckward();

  for k=1

  

  utputNums

  yitao(k)=(d(k)-o(k))*o(k)*(1-o(k)); %输入层误差偏导

  end

  for j=1:hideNums

  tem=0.0;

  for k=1

  

  utputNums

  tem=tem+yitao(k)*w(j,k); %为了求隐层偏导,而计算的∑

  end

  yitay(j)=tem*y(j)*(1-y(j)); %隐层偏导

  end

  %调整各层权值

  for j=1:hideNums

  for k=1

  

  utputNums

  deltw(j,k)=alpha*yitao(k)*y(j); %权值w的调整量deltw(已乘学习率)

  w(j,k)=w(j,k)+deltw(j,k)+a*dw(j,k);%权值调整,这里的dw=dletw(t-1),实际是对BP算法的一个

  dw(j,k)=deltw(j,k); %改进措施--增加动量项目的是提高训练速度

  end

  end

  for i=1:inputNums

  for j=1:hideNums

  deltv(i,j)=alpha*yitay(j)*x(i); %同上deltw

  v(i,j)=v(i,j)+deltv(i,j)+a*dv(i,j);

  dv(i,j)=deltv(i,j);

  end

  end

  c=c+1;

  end%第二个while结束;表示一次BP训练结束

  double tmp;

  tmp=0.0;

  for i=1:samplenum

  tmp=tmp+errorp(i)*errorp(i);%误差求和

  end

  tmp=tmp/c;

  error(count)=sqrt(tmp);%误差求均方根,即精度

  if (error(count)

  break;

  end

  count=count+1;%训练次数加1

  end%第一个while结束

  error(maxcount+1)=error(maxcount);

  p=1:count;

  pp=p/50;

  plot(pp,error(p),'-'); %显示误差

  然后下面是研友wangleisxcc的程序基础上,我把初始化网络,训练网络,和网络使用三个稍微集成后的一个新函数bpnet

  %简单的BP神经网络集成,使用时直接调用bpnet就行

  %输入的是 p-作为训练值的输入

  % t-也是网络的期望输出结果

  % ynum-设定隐层点数 一般取3~20;

  % maxnum-如果训练一直达不到期望误差之内,那么BP迭代的次数 一般设为5000

  % ex-期望误差,也就是训练一小于这个误差后结束迭代 一般设为0.01

  % lr-学习率一般设为0.01

  % pp-使用p-t虚拟蓝好的BP网络来分类计算的向量,也就是嵌入二值水印的大组系数进行训练然后得到二值序列

  % ww-输出结果

  % 注明:ynum,maxnum,ex,lr均是一个值;而p,t,pp,ww均可以为向量

  % 比如p是m*n的n维行向量,t那么为m*k的k维行向量,pp为o*i的i维行向量,ww为o* k的k维行向量

  %p,t作为网络训练输入,pp作为训练好的网络输入计算,最后的ww作为pp经过训练好的BP训练后的输出

  function ww=bpnet(p,t,ynum,maxnum,ex,lr,pp)

  plot(p,t,'+');

  title('训练向量');

  xlabel('P');

  ylabel('t');

  [w1,b1,w2,b2]=initff(p,ynum,'tansig',t,'purelin'); %初始化含一个隐层的BP网络

  zhen=25; %每迭代多少次更新显示

  biglr=1.1; %学习慢时学习率(用于跳出平坦区)

  litlr=0.7; %学习快时学习率(梯度下降过快时)

  a=0.7 %动量项a大小(△W(t)=lr*X*ん+a*△W(t-1))

  tp=[zhen maxnum ex lr biglr litlr a 1.04]; %trainbpx

  [w1,b1,w2,b2,ep,tr]=trainbpx(w1,b1,'tansig',w2,b2, 'purelin',p,t,tp);

  ww=simuff(pp,w1,b1,'tansig',w2,b2,'purelin'); %ww就是调用结果

  下面是bpnet使用简例:

  %bpnet举例,因为BP网络的权值初始化都是随即生成,所以每次运行的状态可能不一样。

  %如果初始化的权值有利于训练,那么可能很快能结束训练,反之则反之

  clear all

  clc

  figure

  randn('state',sum(100*clock))

  num1=5; %隐节点数

  num2=10000; %最大迭代次数

  a1=0.02; %期望误差

  a2=0.05; %学习率

  test=randn(1,5)*0.5; %随即生成5个测试值

  in=-1:.1:1; %训练值

  expout=[-.9602 -.5770 -.0729 .3771 .6405 .6600 .4609 .1336 -.2013 -.4344 -.5000 -.3930 -.1647 .0988 .3072 .3960 .3449 .1816

  -.0312 -.2189 -.3201];

  %上面是指定期望输出

  %expout=0.3*randn(1,21); %随机产生一组期望输出值,不过效果不好

  plot(in,expout,'+');

  title('训练向量');

  xlabel('in');

  ylabel('expout');

  output=bpnet(in,expout,num1,num2,a1,a2,test)

  test

广告赞助商