BP神经网络及拟合实例

BP神经网络结构

BP神经网络(Back Propagation)是一种多层神经网络,其误差是反向传播的,因此称为BP神经网络。
BP神经网络包括输入层、隐含层和输出层三层,通常来说,隐含层的激活函数为
f 1 ( x ) = 1 1 + e − x f_1(x) = \frac {1}{1+e^{-x}} f1(x)=1+ex1
输出层的激活函数为
f 2 ( x ) = x f_2(x)=x f2(x)=x

前向计算

我们记BP神经网络具有n个输入层神经元,隐含层有 s 1 s_1 s1个神经元,输出层有 s 2 s_2 s2个神经元。其隐含层权值矩阵为 W 1 ∈ R s 1 × u W_1\in R^{s_1\times u} W1Rs1×u,偏置向量为 b 1 ∈ R s 1 b_1\in R^{s_1} b1Rs1,输出层权值矩阵为 W 2 ∈ R s 2 × s 1 W_2 \in R^{s_2\times s_1} W2Rs2×s1,偏置向量为 b 1 ∈ R s 2 b_1\in R^{s_2} b1Rs2
BP神经网络的前向计算过程可以分为:隐含层的输出计算和输出层的输出计算。
我们记隐含层的输出为 a ∈ R s 1 a\in R^{s_1} aRs1,输出层的输出为 y ∈ R s 2 y\in R^{s_2} yRs2
一个神经元的计算过程包括两部分:

  1. 输入的线性组合
  2. 激活函数的计算

隐含层的输入为神经网络的输入 u ∈ R n u\in R^{n} uRn,其输出为
a = f 1 ( W 1 u + b 1 ) a=f_1(W_1u+b_1) a=f1(W1u+b1)
在matlab中,我们可以运用其矩阵运算来很方便的计算上式。
输出层的输入为隐含层的输出 a a a,其输出为
y = f 2 ( W 2 a + b 2 ) y=f_2(W_2a+b_2) y=f2(W2a+b2)

误差反向传播

梯度下降法

通过有效的训练,BP神经网络可以具有逼近任何非线性函数的能力。定义神经网络的估计误差均方差
E = 1 2 ∑ i = 1 s 2 e i 2 = 1 2 ∑ i = 1 s 2 ( y d − y ) 2 E =\frac{1}{2}\sum_{i=1}^{s_2}e_i^2= \frac{1}{2} \sum_{i=1}^{s_2}(y_d-y)^2 E=21i=1s2ei2=21i=1s2(ydy)2
其中, y d y_d yd为期望的输出, y y y为神经网络对输出的预测(或者说估计)。
神经网络的训练过程为,通过误差不断调整神经网络的参数(权值和偏移量),使得网络的估计误差均方差最小。
梯度下降法便是一种最为常用的寻找目标函数(即误差均方差函数 E E E)的方法。其基本原理为,沿着目标函数的梯度方向,目标函数是下降最快的。

输出层参数调节

基于上文,我们可以知道,调节权值矩阵 W 2 W_2 W2的最快方法为
Δ W 2 i j = − η ∂ E ∂ W 2 i j \Delta W_{2ij} = -\eta \frac{\partial E}{\partial W_{2ij}} ΔW2ij=ηW2ijE
可以将上式表示为矢量形式,对权值矩阵的一整行进行操作,记权值矩阵 W 2 W_2 W2的第 i ( i = 1 , 2 , . . . s 2 ) i(i=1,2,...s_2) i(i=1,2,...s2)行为 W 2 i 0 W_{2i0} W2i0,可知,此行元素通过影响第 i i i个输出,进而影响到最后的误差。权值矩阵 W 2 W_2 W2 i i i行的更新值为
Δ W 2 i 0 = − η ∂ E ∂ W 2 i 0 \Delta W_{2i0} = -\eta \frac{\partial E}{\partial W_{2i0}} ΔW2i0=ηW2i0E
可以通过链式法则来计算,即偏微分如下形式
∂ E ∂ W 2 i 0 = ∂ E ∂ e i ∂ e i ∂ f 2 ∂ f 2 ∂ W 2 i 0 = − e i f 2 ′ a T \frac{\partial E}{\partial W_{2i0}}=\frac{\partial E}{\partial e_i} \frac{\partial e_i}{\partial f_2} \frac{\partial f_2}{\partial W_{2i0}}=-e_if_2'a^T W2i0E=eiEf2eiW2i0f2=eif2aT
那么,可以得到,输出层权值矩阵 W 2 W_2 W2 i i i行的更新律为
Δ W 2 i 0 = η e i f 2 ′ a T \Delta W_{2i0} = \eta e_if_2'a^T ΔW2i0=ηeif2aT
类似的,可以得到偏移量 b 2 b_2 b2的更新律为
Δ b 2 i = η e i f 2 ′ \Delta b_{2i} = \eta e_if_2' Δb2i=ηeif2

隐含层参数调节

隐含层参数矩阵和偏移量的更新方法是一样的,同样是对误差平方差进行求偏导得到,但是要复杂很多。权值矩阵 W 1 W_1 W1的第 i i i行是通过隐含层所有神经元来影响最终的网络输出的,因此,其更新律为
Δ W 1 j 0 = − η ∑ k = 1 s 2 ( ∂ E ∂ e k ∂ e k ∂ f 2 ∂ f 2 ∂ a j ∂ a j ∂ W 1 j 0 ) = η f 2 ′ u ∑ k = 1 s 2 ( e k W 2 k j ) f 1 ′ \Delta W_{1j0} = -\eta \sum_{k=1}^{s_2}(\frac{\partial E}{\partial e_k} \frac{\partial e_k}{\partial f_2} \frac{\partial f_2}{\partial a_j} \frac{\partial a_j}{\partial W_{1j0}}) = \eta f_2'u \sum_{k=1}^{s_2}(e_kW_{2kj})f_1' ΔW1j0=ηk=1s2(ekEf2ekajf2W1j0aj)=ηf2uk=1s2(ekW2kj)f1
表示为矩阵运算形式为
Δ W 1 = η A ′ W 2 T Y ′ e u T \Delta W_1 = \eta \bm{A}'\bm{W}_2^T\bm{Y}'\bm{e} \bm{u}^T ΔW1=ηAW2TYeuT
其中, A ′ = d i a g [ f 1 j ′ ] s 1 × s 1 \bm{A}'=diag[f_{1j}']_{s_1\times s_1} A=diag[f1j]s1×s1, Y ′ = d i a g [ f 2 j ′ ] s 2 × s 2 \bm{Y}'=diag[f_{2j}']_{s_2 \times s_2} Y=diag[f2j]s2×s2为对角阵。
类似的,偏移量 b 1 b_1 b1的更新律只与权值 W 1 W_1 W1相差一个因子 u u u
Δ b 1 j = η f 2 ′ f 1 ′ ∑ k = 1 s 2 ( e k W 2 k j ) \Delta b_{1j} = \eta f_2'f_1' \sum_{k=1}^{s_2}(e_kW_{2kj}) Δb1j=ηf2f1k=1s2(ekW2kj)
化为矩阵运算形式为
Δ b 1 = η A ′ W 2 T Y ′ e \Delta \bm{b}_1 = \eta \bm{A}'\bm{W}_2^T\bm{Y}'\bm{e} Δb1=ηAW2TYe

BP神经网络拟合实例

采用BP神经网络对正弦函数 y = s i n ( t ) y=sin(t) y=sin(t)进行拟合。网络结构设置为1-20-1,代码如下

% 训练简单的BP神经网络来拟合,自己写训练算法
clear,clc
%% 生成训练数据
ts = 0.01;
u1 = 0;
y1 = 0;

for k=1:1000
    u(k) = k*ts;
    y(k) = sin(u(k));
end
n = length(u);

训练算法主体部分

%% 训练算法
% 采用的BP神经网络为1-20-1的结构
yita = 0.1;     %训练速度
num_h = 20;
w1 = rand(num_h,1);
% w1 = ones(num_h,1);
w2 = rand(num_h,1);
% w2 = ones(num_h,1);
b1 = zeros(num_h,1);
b2 = 0;
e_tol = 1e-3;
e = e_tol;
cnt = 1;
while cnt<10000 && e>=e_tol
    % 打乱数据
    idx_rand = randperm(n);
    x_train = y(idx_rand);    %网络输出
    u_train = u(idx_rand);    %网络输入
    e = 0;
    for i=1:400
        %神经网络前向计算
        for j = 1:num_h
            H_input(j) = u_train(i)*w1(j)+b1(j);
            H_output(j) = logsig(H_input(j));
        end
        Output(i) = dot(H_output,w2)+b2;
        %误差反向传播
        Error(i) = x_train(i) - Output(i);
        for j=1:num_h
            Delta_w2(j) = yita*Error(i)*H_output(j);
            Dlogsig(j) = H_output(j)*(1-H_output(j));
            Delta_w1(j) = yita*Error(i)*w2(j)*Dlogsig(j)*u_train(j);
            w1(j) = w1(j)+Delta_w1(j);
            w2(j) = w2(j)+Delta_w2(j);
            b1(j) = b1(j) + yita*Error(i)*w2(j)*Dlogsig(j);
        end
        b2 = b2 + yita*Error(i);
        e = e + Error(i)^2/2;
    end
    e = e/400;
    e_store(cnt) = e;
    cnt = cnt+1;
end

检测训练结果,并进行可视化

%% 检验训练结果
for i = 1:n
%     k = randi(1000);
    u_test = u(i);
    x_test = y(i);
    
    for j=1:num_h
        H_input_test(j) = u_test*w1(j)+b1(j);
        H_output_test(j) = logsig(H_input_test(j));
    end
    Output_test(i) = dot(H_output_test,w2)+b2;
%     Output_test(i) = net_BP(u_test(i),w1,w2,b1,b2);
    Error_test(i) = x_test-Output_test(i);
    
end
time = u;
figure(2)
plot(time(1:n),y(1:n),'r');
hold on
plot(time(1:n),Output_test,'b--');
hold on
plot(time(1:n),Error_test,'g-.');
legend('train','test','error');

神经网络拟合结果如下
神经网络拟合结果

  • 7
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值