失踪人口来冒个泡,好久没来更新了
这是最近学的BP网络,然后给老师的代码做了下注释
注释仅供参考,如有错误请吱我一声
-
原理
-
代码
clear all;
close all;
x1=0.3;a1=0.05;%x1学习率 a1惯性系数
In=4;h=5;Out=3; %输入神经元 隐层神经元 输出神经元个数
wi=[-0.2846 0.2193 -0.5097 -1.0668;
-0.7484 -0.1210 -0.4708 0.0988;
-0.7176 0.8297 -1.6000 0.2049;
-0.0858 0.1925 -0.6346 0.0347;
0.4358 0.2369 -0.4564 -0.1324]; %随机初始化权重值
wi1=wi;wi2=wi;wi3=wi; %预赋值
wo=[1.0438 0.5478 0.8682 0.1446 0.1537;
0.1716 0.5811 1.1214 0.5067 0.7370;
1.0063 0.7428 1.0534 0.7824 0.6494]; %随机初始化权重值
wo1=wo;wo2=wo;wo3=wo; %预赋值
x=[0,0,0]; %初始化各值
du1=0;
u1=0;u2=0;u3=0;u4=0;u5=0;
y1=0;y2=0;y3=0;
oh=zeros(h,1);
I=oh;
error2=0;
error1=0;
ts=0.003;
for k=1:1:1000,
time(k)=k*ts;
rin(k)=sin(1*2*pi*k*ts); %输入信号离散化取值
a(k)=1+0.15*sin(k*pi/25); %被控对象数学模型离散化取值
y(k)=(a(k)*y1+u1)/(1+y1^2); %被控对象数学模型离散化取值
error(k)=rin(k)-y(k);%计算此刻误差
xi=[rin(k),y(k),error(k),1]; %将四个值合并为四维矩阵,作为输入参数
x(1)=error(k)-error1; %计算此刻与前一刻的误差
x(2)=error(k); %保留此刻误差
x(3)=error(k)-2*error1+error2; %(error(k)-error1)-(error1-error2) 两次误差的差
ed=[x(1);x(2);x(3)]; %合并为列矩阵
I=xi*wi'; %输入值*输入权重,所以I为各隐层神经元接受的值
for j=1:1:h %通过正负取对称的sigmoid函数,计算隐层神经元输出
oh(j)=(exp(I(j))-exp(-I(j)))/(exp(I(j))+exp(-I(j))); %激活函数
end
K=wo*oh; %K为隐层神经元输出*输出权重,所以K为各输出神经元接受的值
for j=1:1:Out%通过非负的sigmoid函数,计算输出神经元输出
K(j)=exp(K(j))/(exp(K(j))+exp(-K(j))); %激活函数
end
kp(k)=K(1);ki(k)=K(2);kd(k)=K(3); %将输出各值分别赋值给对应矩阵
Kd=[kp(k),ki(k),kd(k)];
du(k)=Kd*ed; %pid各值*对应的系数值 得到调节输出
u(k)=u1+du(k);%前个输出 + 调节输出 作为目前输出
if u(k)>=10, %限定输出上下限,不知道在这里为什么设这个值,可能在实际项目里会用到,防止损坏
u(k)=10;
end
if u(k)<=-10,
u(k)=-10;
end
dyu(k)=sign((y(k)-y1)/(du(k)-du1+0.0001)); %由于偏y(k)/偏u(k)未知,用sign函数取代
for j=1:1:Out,
dK(j)=2/(exp(K(j))+exp(-K(j)))^2;%输出的激活函数对x求偏导 偏u(k)/偏O的值
end
for i=1:1:Out,
de3(i)=error(k)*dyu(k)*ed(i)*dK(i); %得输出层的各局部梯度
end
for j=1:1:Out,
for i=1:1:h
dwo=x1*de3(j)*oh(i)+a1*(wo1-wo2);%输出权重的调节量
end
end
wo=wo1+dwo+a1*(wo1-wo2); %得到输出权重 +惯性系数防止陷入局部最优解
for i=1:1:h,
dO(i)=4/(exp(I(i))+exp(-I(i)))^2; %隐层的激活函数对x求偏导
end
seg=de3*wo; %输出的梯度*输出权重
for i=1:1:h
de2(i)=dO(i)*seg(i);%得隐层各值的局部梯度
end
dwi=x1*de2'*xi; %得到隐层权重调节值
wi=wi1+dwi+a1*(wi1-wi2); %得到隐层权重+惯性系数防止陷入局部最优解
du1=du(k); %保存各历史值
u5=u4;u4=u3;u3=u2;u2=u1;u1=u(k);
y2=y1;y1=y(k);
wo3=wo2;wo2=wo1;wo1=wo;
wi3=wi2;wi2=wi1;wi1=wi;
error2=error1;
error1=error(k);
end
figure(1);
plot(time,rin,'r',time,y,'b');
xlabel('时间(秒)');ylabel('输出跟踪输入的响应曲线');
figure(2);
plot(time,u,'r');
xlabel('时间(秒)');ylabel('控制信号u(k)的变化曲线');
figure(3);
subplot(311);
plot(time,kp,'r');
xlabel('时间(秒)');ylabel('参数kp');
subplot(312);
plot(time,ki,'r');
xlabel('时间(秒)');ylabel('参数ki');
subplot(313);
plot(time,kd,'r');
xlabel('时间(秒)');ylabel('参数kd');
figure(4);
plot(time,error,'r');
xlabel('time(s)'); ylabel('误差曲线');
这是对sin函数的拟合情况