BP神经网络逼近函数

本文讲述的是使用BP神经网络对一个函数的逼近模拟,理论部分可参考博客:

首先利用BP神经网络来模拟函数的系统框架图如下:

Matlab BP神经网络窗口关闭后怎么打开 matlab bp神经网络函数_机器学习


将对象函数的输入U(k)输入到BP神经网络中进行前向传播,得到输出yn(k),然后用yn(k)和对象函数实际的输出y(k)进行比较得到误差e,再用误差进行反向传播不断地更新BP神经网络中的权值和偏置等参数,最后让神经网络学习到合适的权值,从而达到输入U(k)即可得到正确的y(k),从而将该函数对象模拟出来。

那么下面我们进入程序:
首先设置合适的BP网络参数,学习率等,而后随机生成一个6x1的矩阵作为权值w2,先令w2_1=w2,w2_2=w2_1。对权值w1同理,设置一个2x6的随机矩阵。而后设置一系列的初值

xite=0.5;
alfa=0.05;
w2=rands(6,1);
w2_1=w2;
w2_2=w2_1;
w1=rands(2,6);
w1_1=w1;
w1_2=w1_1;
dw1=0*w1;
x=[0 0]';
u_1=0;
y_1=0;
I=[0,0,0,0,0,0]';
Iout=[0,0,0,0,0,0]';
FI=[0,0,0,0,0,0]';
ts=0.001;

随后进入迭代部分,此处比较复杂,一层一层解释,先设置一个迭代2000次的学习循环,后设置时间,因为这是一个离散函数的系统,因此时间的变化对该函数的输入输出都有影响。由于题目没有给定具体的u(k)函数,因此我们选择:Matlab BP神经网络窗口关闭后怎么打开 matlab bp神经网络函数_迭代_02,y(k)题目已经给出:
Matlab BP神经网络窗口关闭后怎么打开 matlab bp神经网络函数_权值_03

for k=1:1:2000
    time(k)=k*ts;
    %u(k)=sin(k*ts);
    u(k)=0.50*sin(3*2*pi*k*ts);
    %y(k)=u(k);
    y(k)=(u_1-0.9*y_1)/(1+y_1^2);

而后我们对神经网络的第一层开始前向传播:将第一层的输出放入在Iout的矩阵内部

for j=1:1:size(w1,2)
        I(j)=x'*w1(:,j);%线性传播
        Iout(j)=1/(1+exp(-I(j)));%激活函数激活
    end

然后开始第二层传播得到yn(k)的第一次取值,然后计算实际的y(k)和第一次推导的yn(k)的误差e(k)

yn(k)=w2'*Iout;
    %yn(k)
    e(k)=y(k)-yn(k);
    e(k)

随后开始进行BP网络的反向传播更新权值:

w2=w2_1+(xite*e(k))*Iout+alfa*(w2_1-w2_2);
    for j=1:1:6
        FI(j)=exp(-I(j))/(1+exp(-I(j)))^2;
    end
    for i=1:1:size(w1,1)
        for j=1:1:size(w1,2)
            dw1(i,j)=e(k)*xite*FI(j)*w2(j)*x(i);
        end
    end
    w1=w1_1+dw1+alfa*(w1_1-w1_2);

然后开始计算jacobian的信息:然后对权值和初始值u_1,y_1更新赋值。

yu=0;
    for j=1:1:size(w1,2)
        yu=yu+w2(j)*w1(1,j)*FI(j);
    end
    dyu(k)=yu;
    x(1)=u(k);
    x(2)=y(k);
    w1_2=w1_1;
    w1_1=w1;
    w2_2=w2_1;
    w2_1=w2;
    u_1=u(k);
    y_1=y(k);
end

就这样不断地循环迭代,最后可以得到一个训练完全的BP神经网络,该网络可以模拟该函数y(k)。

最后进行作图,得到函数的图像:

Matlab BP神经网络窗口关闭后怎么打开 matlab bp神经网络函数_神经网络_04

还有迭代过程中的误差error图像:

Matlab BP神经网络窗口关闭后怎么打开 matlab bp神经网络函数_迭代_05

由误差图像可以看到,在0秒左右该BP神经网络的误差就已经稳定在0的左右波动了,系统就已经趋于稳定了,因此更说明了上图函数模拟的准确性在0秒左右就已经模拟的很好了。

还有dyu的图像如下:证明输出对输入的敏感度是规律变化的

Matlab BP神经网络窗口关闭后怎么打开 matlab bp神经网络函数_神经网络_06

以下是完整的程序:

clear all
close all
xite=0.5;
alfa=0.05;
w2=rands(6,1);
w2_1=w2;
w2_2=w2_1;
w1=rands(2,6);
w1_1=w1;
w1_2=w1_1;
dw1=0*w1;
x=[0 0]';
u_1=0;
y_1=0;
I=[0,0,0,0,0,0]';
Iout=[0,0,0,0,0,0]';
FI=[0,0,0,0,0,0]';
ts=0.001;
for k=1:1:2000
    time(k)=k*ts;
    %u(k)=sin(k*ts);
    u(k)=0.50![在这里插入图片描述]()
*sin(3*2*pi*k*ts);
    %y(k)=u(k);
    y(k)=(u_1-0.9*y_1)/(1+y_1^2);
    for j=1:1:size(w1,2)
        I(j)=x'*w1(:,j);
        Iout(j)=1/(1+exp(-I(j)));
    end
    yn(k)=w2'*Iout;
    %yn(k)
    e(k)=y(k)-yn(k);
    e(k)
    w2=w2_1+(xite*e(k))*Iout+alfa*(w2_1-w2_2);
    for j=1:1:6
        FI(j)=exp(-I(j))/(1+exp(-I(j)))^2;
    end
    for i=1:1:size(w1,1)
        for j=1:1:size(w1,2)
            dw1(i,j)=e(k)*xite*FI(j)*w2(j)*x(i);
        end
    end
    w1=w1_1+dw1+alfa*(w1_1-w1_2);
    %jacobian的信息计算
    yu=0;
    for j=1:1:size(w1,2)
        yu=yu+w2(j)*w1(1,j)*FI(j);
    end
    dyu(k)=yu;
    x(1)=u(k);
    x(2)=y(k);
    w1_2=w1_1;
    w1_1=w1;
    w2_2=w2_1;
    w2_1=w2;
    u_1=u(k);
    y_1=y(k);
end
figure(1);
plot(time,y,'r',time,yn,'b');
xlabel('time(s)');
ylabel('y and yn');
figure(2);
plot(time,y-yn,'r');
xlabel('time(s)');
ylabel('error');
figure(3);
plot(time,dyu);
xlabel('time(s)');
ylabel('dy');

补充

jacobian的信息这是目前很多大学都在研究的一个方向,这里不做展开,具体就是jacobian信息可以用来表示对象函数的输出对输入的敏感度。