BP神经网络原理(附实验程序)

1. 人工神经网络

1.1 原理

人工神经网络(Artificial Neural Networks,ANN)也简称为神经网络(NN),它是一种模仿动物神经网络行为特征,进行分布式并行信息处理的算法数学模型。这种网络依靠系统的复杂程度,通过调整内部大量结点之间相互连接的关系,从而达到处理信息的目的。

神经网络首先要以一定的学习准则进行学习,以

决定神经网络模型性能的三大要素为: 神经元(信息处理单元)的特性; 神经元之间相互连接的形式——拓扑结构; 为适应环境而改善性能的学习规则。

1.2 特点

人工神经网络是有自适应能力的,它可以在训练或者学习过程中改变自身的权重,来适应环境要求。

  • 训练方式
    • 有监督:利用给定的样本进行分类或者模仿。
    • 无监督:规定学习规则,学习的内容随系统所处环境而异,系统可以自发的发现环境的特征,类似人脑的的功能。
  • 泛化能力 对那些没有训练过的样本,有很好的预测能力和控制能力,特别是存在一些噪声的样本。比如,公式 y = 2 x 2 y=2x^2 y=2x2的x和y的值作为样本,假设样本只取x=[0,100],y=x;神经网络训练完之后得到近似公式 y = 2 x 2 y=2x^2 y=2x2的数学模型,即使没有训练过x=999的这个样本,但是仍可以神经网络近似的数学模型知道y的值是多少。
  • 模拟/辨识能力: 当设计者很清楚的知道系统时,可以用数值分析,微积分等数学工具建立,但是当系统很复杂的时候,或者系统未知,信息量很少,建立精确的数学模型就很困难。神经网络的非线性映射能力就表现出优势,因为它不需要对系统有很透彻的了解,只需要知道系统输入与输出的映射关系即可近似得到一个数学模型

2. BP神经网络

BP神经网络是一种典型的非线性算法。BP神经网络由输入层、输出层和之间若干层(一层或多层)隐含层构成,每一层可以有若干个节点。层与层之间节点的连接状态通过权重来体现。

2.1 感知器

上图可以看到BP神经网络时由一个个节点和线连接起来组成的网络,组成这个网络的单元就叫感知器

感知器的结构由输入项 x i x_i xi、权重 w i w_i wi、偏置 θ \theta θ、激活函数 f ( ⋅ ) f(\cdot) f()、输出 y y y组成。其中偏置和激活函数可能不太好理解为什么要把它们放在里面。

首先,偏置(有些文献叫阈值),用一张图来解释为什么要用它,神经网络的作用是对样本数据进行学习然后得到一个近似的模型,细想本质就是寻找规律然后对数据进行分类。

为什么采用激活函数?
第一点,假设每个感知器的表达为 y = a x + b y=ax+b y=ax+b,如果没有激活函数,当x的值也就是输入很大时,经过层层的计算,那这个数值将会非常非常大,激活函数的作用就是将感知器的输出限制在一个固定区间,比如[0,1]。
第二点,按照感知器的输出来看,它是线性的,就算再经过下一层的网络,它仍然是线性的,但是神经网络是需要有非线性的能力的,激活函数正好能赋予它这个能力。

sigmoid激活函数的特点:

  • 上下有界(relu是个特例)
  • 连续光滑,连续可微(不满足这一条后续就无法做偏导)
  • 该函数的中区高增益部分解决了小信号需要放大的问题,两侧的低增益区适合处理大信号。

下图是sigmoid激活函数曲线,类似的有很多,就不一一列举了。
δ ( x ) = 1 1 + e − x \delta(x)=\frac{1}{1+e^{-x}} δ(x)=1+ex1

3. 正向传播和反向传播

BP神经网络的学习过程如下:

### 3.1 正向传播

输入样本从输入层传入,经过各隐层处理之后,传向输出层。

输入层有n个神经元组成,
输入层的输出: x i ( i = 1 , 2 , . . . , n ) x_i(i=1,2,...,n) xi(i=1,2,...,n)

隐藏层有q个神经元组成,输入层和隐藏层的权值为 v k i ( i = 1 , 2 , . . . , n ; k = 1 , 2 , . . . , q ) v_{ki}(i=1,2,...,n;k=1,2,...,q) vki(i=1,2,...,n;k=1,2,...,q)
隐藏层输入(含阈值 θ \theta θ):
S k = ∑ i = 1 n v k i ⋅ x i S_k=\sum_{i=1}^{n}v_{ki}\cdot x_i Sk=i=1nvkixi
隐藏层输出:
z k = f ( S k ) z_k=f(S_k) zk=f(Sk)

输出层由m个神经元组成, y j ( j = 1 , 2 , . . . , m ) y_j(j=1,2,...,m) yj(j=1,2,...,m)为该层的输出
隐藏层和输出层的权值为 w j k ( k = 1 , 2 , . . . , q ; j = 1 , 2 , . . . , m ) w_{jk}(k=1,2,...,q;j=1,2,...,m) wjk(k=1,2,...,q;j=1,2,...,m)
输出层输入:
S j = ∑ k = 1 q w j k ⋅ z k S_j=\sum_{k=1}^{q}w_{jk}\cdot z_k Sj=k=1qwjkzk
输出层输出:
y j = f ( S j ) y_j=f(S_j) yj=f(Sj)

3.2 反向传播

正向传播是输入样本从输入层传入,经过各隐层处理之后,传向输出层。若输出层的实际输出与期望的输出不符合,则开始反向传播:将误差用某种形式通过隐藏层逐层反传,并将误差分摊给各层的神经元,从而获得各层神经元的误差信号,用于修正各个神经元的权值。
神经元的正向传播和反向传播是周而复始进行的,一直进行到误差减少到可以接受的程度为止,神经网络学习的过程就是不断修正权值的过程。

3.2.1 梯度下降

当一个人站在山顶或者半山腰,想要以最快的速度到达山脚,那么哪条路最快呢?
是每一步都下降最快的路,变化最快。在数学上,用梯度的概念来描述。

下面用梯度下降法求函数的最小值问题:

梯度是一个矢量,表示某一函数在该点处的方向导数沿着该方向取得最大值,只需要不断的求偏导进行迭代就可以以最快速度到达最小值。
这边的学习率也就是步长,如果取太长,会在最小值左右来回震荡;如果的取的太小,会增加学习时长,一般在[0,1]之间。

3.2.2 公式推导

期望输出用符号t表示,误差的形式一般采用:
E = 1 2 ∑ j = 1 m ( y j − t j ) 2 E=\frac{1}{2}\sum_{j=1}^m(y_j-t_j)^2 E=21j=1m(yjtj)2

根据梯度下降原理,对每个权值的修正方向为E的函数梯度的反方向,确保 ω i j \omega_{ij} ωij为负值。

△ ω i j = − η ∂ E ∂ ω i j \triangle \omega_{ij}=-\eta \frac{\partial E}{\partial \omega_{ij}} ωij=ηωijE

对于输出层

△ ω j k = − η ∂ E ∂ ω j k \triangle \omega_{jk}=-\eta \frac{\partial E}{\partial \omega_{jk}} ωjk=ηωjkE
根据链式法则,可以把它转化为两式相乘, E E E对输出层的输入 S j S_j Sj求偏导; S j S_j Sj对权值求偏导
∂ E ∂ ω j k = ∂ E ∂ S j ∂ S j ∂ ω j k \frac{\partial E}{\partial \omega_{jk}}=\frac{\partial E}{\partial S_j} \frac{\partial S_j}{\partial \omega_{jk}} ωjkE=SjEωjkSj
进一步展开:
∂ E ∂ S j = ( y j − t j ) f ′ ( S j ) \frac{\partial E}{\partial S_j}=(y_j-t_j)f'(S_j) SjE=(yjtj)f(Sj)
还记得输出层的输入吗, S j = ∑ k = 1 q w j k ⋅ z k S _j=\sum_{k=1}^{q}w_{jk}\cdot z_k Sj=k=1qwjkzk
所以得到
∂ S j ∂ ω i j = z k \frac{\partial S_j}{\partial \omega_{ij}}=z_k ωijSj=zk
整理上述,隐藏层和输出层的权值变化量可表示为:
△ ω j k = η ( t j − y j ) f ′ ( S j ) z k \triangle \omega_{jk}=\eta(t_j-y_j)f'(S_j)z_k ωjk=η(tjyj)f(Sj)zk
其中 f ′ ( S j ) f'(S_j) f(Sj)是激活函数的导数,不同的激活函数有着不一样的求导函数。


隐藏层相对麻烦一点,因为隐藏层的输入为 S k S_{k} Sk,表达式为:
△ v k i = − η ∂ E ∂ v k i = − η ∂ E ∂ S k ∂ S k ∂ v k i \triangle v_{ki}=-\eta \frac{\partial E}{\partial v_{ki}}=-\eta \frac{\partial E}{\partial S_{k}}\frac{\partial S_{k}}{\partial v_{ki}} vki=ηvkiE=ηSkEvkiSk
先看前半部分,因为隐藏层的输出为 z k = f ( S k ) z_k=f(S_k) zk=f(Sk)(如果看不明白,最好把正向传播的公式抄下来对着看),可以展开为:
{ ∂ E ∂ S k = ∂ E ∂ z k ∂ z k ∂ S k ∂ S k ∂ v k i = x i \begin{cases} \frac{\partial E}{\partial S_{k}}=\frac{\partial E}{\partial z_{k}} \frac{\partial z_{k}}{\partial S_{k}}\\ \frac{\partial S_{k}}{\partial v_{ki}}=x_i \end{cases} {SkE=zkESkzkvkiSk=xi

进一步展开:
{ ∂ E ∂ z k = ∑ j = 1 m ( y j − t j ) ∂ y j ∂ z k ∂ z k ∂ S k = f z ′ ( S k ) \begin{cases} \frac{\partial E}{\partial z_{k}}=\sum_{j=1}^{m}(y_j-t_j)\frac{\partial y_{j}}{\partial z_{k}}\\ \frac{\partial z_k}{\partial S_{k}}=f_z'(S_k) \end{cases} {zkE=j=1m(yjtj)zkyjSkzk=fz(Sk)
其中 f z ′ ( S k ) f_z'(S_k) fz(Sk)是隐藏层的激活函数的导数, y i y_i yi是输出层的输出,继续展开:
∂ y j ∂ z k = ∂ y j ∂ S j ∂ S j ∂ z k = f ′ ( S j ) ∂ S j ∂ z k \frac{\partial y_{j}}{\partial z_{k}}=\frac{\partial y_{j}}{\partial S_{j}}\frac{\partial S_{j}}{\partial z_{k}}=f'(S_j)\frac{\partial S_{j}}{\partial z_{k}} zkyj=SjyjzkSj=f(Sj)zkSj
其中 f ′ ( S j ) f'(S_j) f(Sj)为输出层的激活函数,和上面的 f z ′ ( S k ) f_z'(S_k) fz(Sk)不要弄混
∂ S j ∂ z k = ω j k \frac{\partial S_{j}}{\partial z_{k}}=\omega_{jk} zkSj=ωjk

又回到最初的公式,整理上面的公式:
△ v k i = η x i f z ′ ( S k ) ( ∑ j = 1 m ( t j − y j ) f ′ ( S j ) ω j k ) \triangle v_{ki}=\eta x_if_z'(S_k)(\sum_{j=1}^{m}(t_j-y_j)f'(S_j)\omega_{jk}) vki=ηxifz(Sk)(j=1m(tjyj)f(Sj)ωjk)
最终,得到隐藏层和输出层的权值公式为:
{ △ ω j k = η ( t j − y j ) f ′ ( S j ) z k △ v k i = η x i f z ′ ( S k ) ( ∑ j = 1 m ( y j − t j ) f ′ ( S j ) ω j k ) \begin{cases} \triangle \omega_{jk}=\eta(t_j-y_j)f'(S_j)z_k\\ \triangle v_{ki}=\eta x_if_z'(S_k)(\sum_{j=1}^{m}(y_j-t_j)f'(S_j)\omega_{jk}) \end{cases} {ωjk=η(tjyj)f(Sj)zkvki=ηxifz(Sk)(j=1m(yjtj)f(Sj)ωjk)
两个权值有公共部分,可简化为:
{ δ = ( t j − y j ) f ′ ( S j ) △ ω j k = η δ z k △ v k i = η x i f z ′ ( S k ) ( ∑ j = 1 m δ ω j k ) \begin{cases} \delta=(t_j-y_j)f'(S_j)\\ \triangle \omega_{jk}=\eta\delta z_k\\ \triangle v_{ki}=\eta x_if_z'(S_k)(\sum_{j=1}^{m}\delta\omega_{jk}) \end{cases} δ=(tjyj)f(Sj)ωjk=ηδzkvki=ηxifz(Sk)(j=1mδωjk)
对公式中的符号再说明一下, t j t_j tj表示期望输出; y j y_j yj表示实际的输出,一般用输出层输出表示; η \eta η表示学习率; z k z_k zk表示隐藏层的输出; x i x_i xi表示输入层的输入(或输出); ω j k \omega_{jk} ωjk表示隐藏层和输出层的权值; S j S_{j} Sj S k S_{k} Sk分别为隐藏层和输出层的输入; f z ′ ( ⋅ ) f_z'(\cdot) fz() f ′ ( ⋅ ) f'(\cdot) f()为隐藏层和输出层的激活函数。

3.2.3 激活函数

对于激活函数的选择,有很多方式,可以选择同一个激活函数,那么 f ( ⋅ ) = f z ( ⋅ ) f(\cdot)=f_z(\cdot) f()=fz(),以下是激活函数及其的导数形式

激活函数导数形式
s i g m o i d ( x ) = 1 1 + e − x sigmoid(x)=\frac{1}{1+e^{-x}} sigmoid(x)=1+ex1 s i g m o i d ′ ( x ) = 1 1 + e − x ( 1 − 1 1 + e − x ) sigmoid'(x)=\frac{1}{1+e^{-x}}(1-\frac{1}{1+e^{-x}}) sigmoid(x)=1+ex1(11+ex1)
t a n h ( x ) = e x − e − x e x + e − x tanh(x)=\frac{e^{x}-e^{-x}}{e^{x}+e^{-x}} tanh(x)=ex+exexex t a n h ′ ( x ) = 1 − t a n h 2 ( x ) tanh'(x)=1-tanh^2(x) tanh(x)=1tanh2(x)
r e l u ( x ) = { x x ⩾ 0 0 x < 0 relu(x)=\begin{cases}x\quad x\geqslant 0 \\ 0\quad x< 0 \end{cases} relu(x)={xx00x<0 r e l u ′ ( x ) = { 1 x ⩾ 0 0 x < 0 relu'(x)=\begin{cases}1\quad x\geqslant 0 \\ 0\quad x< 0 \end{cases} relu(x)={1x00x<0

3.3 权值更新

神经网络的修正和更新主要是对权值进行更新和修正,我们已经知道了每一层的 △ ω \triangle \omega ω的具体公式,用下面公式进行更新:
ω i j ← ω i j + △ ω i j \omega_{ij}\leftarrow\omega_{ij}+\triangle \omega_{ij} ωijωij+ωij

3.3.1 神经网络存在的问题

神经网络存在一些问题

  • 局部最小:在某些初始条件的权值下,会陷入局部最小的问题。有时候局部最小离全局最小值较远的情况下会导致学习失败。
  • 学习率选取问题:如果取太长,可能会在最小值左右来回震荡;如果的取的太小,会大大增加学习时长。
  • 隐藏层的节点个数的确定缺少完整的理论指导。
3.3.2 添加动量项

将权值修正公式变为
△ ω ( n ) = − η ∂ E ( ω ) ∂ ω ( n ) + α △ ω ( n − 1 ) \triangle \omega(n)=-\eta \frac{\partial E(\omega)}{\partial \omega(n)}+\alpha \triangle \omega(n-1) ω(n)=ηω(n)E(ω)+αω(n1)
ω i j ← ω i j + △ ω i j \omega_{ij}\leftarrow\omega_{ij}+\triangle \omega_{ij} ωijωij+ωij

添加动量因子 α \alpha α 0 < α < 1 0<\alpha <1 0<α<1)的本质是改变学习率,一开始误差较大时可以提高收敛速度,并抑制训练过程中的震荡,起到了缓冲平滑的作用。
此外,如果网络的训练已进入了误差曲面的平坦区域,那么误差将变化很小,权值的调整幅度也将相应的变得非常小,也就是说 △ ω ( n − 1 ) \triangle \omega(n-1) ω(n1)近似为 △ ω ( n ) \triangle \omega(n) ω(n),公式可以看作:
△ ω ( n ) = − η 1 − α ∂ E ( ω ) ∂ ω ( n ) \triangle \omega(n)=-\frac{\eta}{1-\alpha}\frac{\partial E(\omega)}{\partial \omega(n)} ω(n)=1αηω(n)E(ω)
从而有利于快速脱离饱和区

程序

用神经网络去逼近函数 y = 3 10 x 2 − 2 x − 1 y=\frac{3}{10}x^2-2x-1 y=103x22x1

%BP神经网络逼近实例
clc;
close all;
clear all;
xite=0.050; % 学习速率
alfa=0.05; % 动量因子
%产生随机信号w1,w2
w2=rands(6,1);

w2_1=w2;w2_2=w2_1;
w1=rands(2,6);
w1_1=w1;w1_2=w1;
dw1=0*w1;%BP网络逼近初始化
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]';
maxtime=500;


%BP神经网络逼近开始
for k=1:1:maxtime
    %目标函数
    X=k/100;
    y(k)=0.3*X*X-2*X-1;
    u(k)=X;
   x(1)=u(k);
    x(2)=y(k);
    for j=1:6
        I(j)=x'*w1(:,j);
        Iout(j)=1/(1+exp(-I(j)));
    end
    yn(k)=w2'*Iout; % 神经网络的输出
    e(k)=y(k)-yn(k); % 构造误差性能指标函数
    w2=w2_1+(xite*e(k))*Iout+alfa*(w2_1-w2_2); % 计算权值w2
    for j=1:6
        FI(j)=exp(-I(j))/(1+exp(-I(j)))^2;
    end
    for i=1:2
        for j=1:6
            dw1(i,j)=e(k)*xite*FI(j)*w2(j)*x(i);
        end
    end
    w1=w1_1+dw1+alfa*(w1_1-w1_2); % 计算权值w1
    %计算jacobian阵
    yu=0;
    for j=1:6
        yu=yu+w2(j)*w1(1,j)*FI(j);
    end
    dyu(k)=yu;
     
    w1_2=w1_1;
    w1_1=w1;
    w2_2=w2_1;
    w2_1=w2;
    u_1=u(k);
    y_1=y(k);
end
time=1:1:maxtime;
figure(1);
plot(time,y,'r',time,yn,'b--','linewidth',2.5);
xlabel('times');
ylabel('y and yn');
legend('y','yn');
grid;
title('BP神经网络系统逼近');
figure(2);
plot(time,e,'r');
xlabel('times');
ylabel('error');
grid;
title('误差曲线')

参考文献

[1]冷雨泉等. 《机器学习入门到实战MATLAB实践应用》[J]. 清华大学出版社, 2019
[2]刘益民. 基于改进BP神经网络的PID控制方法的研究[D].中国科学院研究生院(西安光学精密机械研究所),2007.

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

木白CPP

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值