%BP小波神经网络快速学习算法
clear
clc
SamIn=-1:0.001:1;
SamOut=2*sin(3*SamIn).*exp(-0.1*SamIn.*SamIn);
% figure;plot(SamIn,SamOut);
% pause
% Bp小波神经网络参数初始化
W=rand(15,1);
B=10*rands(15,1);
% 对伸缩因子A进行初始化
temp=rand(15,1);
i=1;
while(i<=15)
if temp(i,1)<=0.5
A(i,1)=2*temp(i,1);
else
A(i,1)=8*temp(i,1)-3;
end
i=i+1;
end
% BP算法训练小波神经网络
N=2001;
g=1.55;
l=0.0008;
t=SamIn;
study_rate=0.0002;
m=0.2; % 动量系数
count=0;
Err_NetworkOut_SamOuts=[]; % 全局变量
NetworkOutSet=[]; % 局部变量
for i=1:N
NetworkOut=0; % 局部变量
for j=1:15
tao=(t(i)-B(j,1))/A(j,1);
h=cos(1.75*tao).*exp(-tao^2/2);
NetworkOut=NetworkOut+h*W(j,1);
end
NetworkOutSet=[NetworkOutSet NetworkOut];
end
% 计算误差函数和相对误差
count=count+1;
Err_NetworkOut_SamOut=(1/2)*sumsqr(NetworkOutSet-SamOut); % 误差函数
former=Err_NetworkOut_SamOut; % 记录前一次的误差
Err_NetworkOut_SamOuts=[Err_NetworkOut_SamOuts Err_NetworkOut_SamOut]; % 误差函数集合
Err_SamOut=(1/2)*sumsqr(SamOut); % 函数平方和
ErrRate=Err_NetworkOut_SamOut/Err_SamOut; % 相对误差
% 计算增加量
E_diff_W=0; % 局部变量:梯度
E_diff_B=0; % 局部变量:梯度
E_diff_A=0; % 局部变量:梯度
E_diff_W1=[]; % 局部变量:梯度集合
E_diff_B1=[]; % 局部变量:梯度集合
E_diff_A1=[]; % 局部变量:梯度集合
delt_w=0;
delt_b=0;
delt_a=0; % 增加量
deltW=[];
deltB=[];
deltA=[];% 增加量集合
for i=1:15
for j=1:N
tao=(t(j)-B(i,1))/A(i,1);
h=cos(1.75*tao).*exp(-tao^2/2);
f=1.75*sin(1.75*tao)+tao*cos(1.75*tao);
s1=SamOut(j)-NetworkOutSet(j);
s2=s1*h;
s3=s1*(W(i,1)/A(i,1))*exp(-tao^2/2).*f;
E_diff_W=E_diff_W+s2;
E_diff_B=E_diff_B+s3;
E_diff_A=E_diff_A+s3*tao;
end
E_diff_W=-E_diff_W;
E_diff_B=-E_diff_B;
E_diff_A=-E_diff_A;
E_diff_W1=[E_diff_W1,E_diff_W];
E_diff_B1=[E_diff_B1,E_diff_B];
E_diff_A1=[E_diff_A1,E_diff_A];
end
delt_w=-((1-m)*study_rate*E_diff_W1');
delt_b=-((1-m)*study_rate*E_diff_B1');
delt_a=-((1-m)*study_rate*E_diff_A1');
deltW=[deltW,delt_w];
deltB=[deltB,delt_b];
deltA=[deltA,delt_a];
W=W+delt_w;
B=B+delt_b;
A=A+delt_a;
ErrRate
while ErrRate>=0.0005
% 计算前向传播网络
% 采用小波函数h(t)=cos(1.75t).*exp(-t^2/2);
NetworkOutSet=[];
for i=1:N
NetworkOut=0;
for j=1:15
tao=(t(i)-B(j,1))/A(j,1);
h=cos(1.75*tao).*exp(-tao^2/2);
NetworkOut=NetworkOut+h*W(j,1);
end
NetworkOutSet=[NetworkOutSet NetworkOut];
end
%计算误差函数和相对误差
Err_NetworkOut_SamOut=(1/2)*sumsqr(NetworkOutSet-SamOut); %误差函数
Err_NetworkOut_SamOuts=[Err_NetworkOut_SamOuts Err_NetworkOut_SamOut]; %误差函数集合
ErrRate=Err_NetworkOut_SamOut/Err_SamOut; % 相对误差
now=Err_NetworkOut_SamOut;
Err_NetworkOut_SamOut
ErrRate
pause
%计算增加量
E_diff_W=0;
E_diff_B=0;
E_diff_A=0; % 初始化为0是为了计算各个参数的梯度;
E_diff_W1=[]; % 局部变量:梯度集合
E_diff_B1=[]; % 局部变量:梯度集合
E_diff_A1=[]; % 局部变量:梯度集合
for i=1:15
for j=1:N
tao=(t(j)-B(i,1))/A(i,1);
h=cos(1.75*tao).*exp(-tao^2/2);
f=1.75*sin(1.75*tao)+tao*cos(1.75*tao);
s1=SamOut(j)-NetworkOutSet(j);
s2=s1*h;
s3=s1*(W(i,1)/A(i,1))*exp(-tao^2/2).*f;
E_diff_W=E_diff_W+s2;
E_diff_B=E_diff_B+s3;
E_diff_A=E_diff_A+s3*tao;
end
E_diff_W=-E_diff_W;
E_diff_B=-E_diff_B;
E_diff_A=-E_diff_A;
E_diff_W1=[E_diff_W1,E_diff_W];
E_diff_B1=[E_diff_B1,E_diff_B];
E_diff_A1=[E_diff_A1,E_diff_A];
end
if(now>former) % 如果这样,减少学习速度,并设动量系数为0
study_rate=l*study_rate;
delt_w=-study_rate*E_diff_W1';
delt_b=-study_rate*E_diff_B1';
delt_a=-study_rate*E_diff_A1';
else % 否则,增加学习速度,并恢复动量系数
study_rate=g*study_rate;
delt_w=m*deltW(:,count)-((1-m)*study_rate*E_diff_W1');
delt_b=m*deltB(:,count)-((1-m)*study_rate*E_diff_B1');
delt_a=m*deltA(:,count)-((1-m)*study_rate*E_diff_A1');
end
former=now;
W=W+delt_w;
B=B+delt_b;
A=A+delt_a;
deltW=[deltW,delt_w];
deltB=[deltB,delt_b];
deltA=[deltA,delt_a];
count=count+1;
end
W
B
A
ErrRate
count
plot(1:count,Err_NetworkOut_SamOuts) % 误差曲线
%end
楼主能把这个解释下吗??f=1.75*sin(1.75*tao)+tao*cos(1.75*tao);
是不是只是一个计算伸缩、平移因子改变量的一个中间变量。谢谢楼主!
顺便说句这个程序运行还是有点慢,不过很不错了,神经网路的逼近能力还可以就是不知道泛化能力怎么样,也就
是向外延伸的能力(预报)。
首先,谢谢站长和版主及各位大侠的支持!
f是计算误差函数对小波参数a和b求导(即a和b的梯度)所产生的式子中的一个因子。
我在这里写一下推导过程:(用sum表示"和号")
原信号s(t)=sum(W*h((t-b)/a))(这是用小波表示信号的物理意义,在网络中相当于标准输出);网络输出我们用s^(t)表示。
因此均方误差就是E=(1/2)*sum(s(t)-s^(t))^2;
那么,各个参数的梯度如下:
E_diff_W=-sum((s(t)-s^(t))*h(tao));
E_diff_B=-sum((s(t)-s^(t))*(W/A)*exp(-tao^2/2)*f);
E_diff_A=-sum((s(t)-s^(t))*tao*(W/A)*exp(-tao^2/2)*f);
这下,应该清楚了。
该程序的泛化能力我没试过,这个程序肯定还有改进的地方,还有许多不完善的地方。这个程序是我根据一
篇很简单的论文编写的,我们可以通过多看小波神经网络的文章,多学习改进的算法,从这个简单的程序入手,
对它进行改造。这样循序渐进的学习,我们就会达到一定的高度。
以后,我编写的小波算法会发上来同大家讨论,通过团结大家的力量,我们就能走出自己的道路。 |