《深度学习之图像识别:核心技术与案例实战》 ——1.1.3 BP算法

举报
华章计算机 发表于 2020/02/23 10:48:44 2020/02/23
【摘要】 本节书摘来自华章计算机《深度学习之图像识别:核心技术与案例实战》 —— 书中第1章,第1.1.3节,作者是言有三   。

1.1.3  BP算法

  多层感知机(Multi-Layer Perceptron)是由单层感知机推广而来,最主要的特点是有多个神经元层。一般将MLP的第一层称为输入层,中间的层为隐藏层,最后一层为输出层。MLP并没有规定隐藏层的数量,因此可以根据实际处理需求选择合适的隐藏层层数,对于隐藏层和输出层中每层神经元的个数也没有限制。

  MLP神经网络结构模型分别为单隐层前馈网络和多层前馈网络,如图1.3和图1.4所示。其中,输入层神经元仅接受外界信息并传递给隐藏层,隐藏层与输出层的神经元对信号进行加工,包含功能神经元。

             image.png

       图1.3  单隐层前馈网络示意图     图1.4  多层前馈网络示意图

  多层感知机的关键问题在于如何训练其中各层间的连接权值。其训练问题又大致分为两类:一类是将其他连接权值进行固定,只训练某两层间的连接权值,研究者们已从数学上证明了这种方法对所有非线性可分的样本集都是收敛的;另一类即大家所熟知的Back Propagation(BP)算法,通常使用sigmoid和tanh等连续函数模拟神经元对激励的响应,使用反向传播对神经网络的连接权值进行训练。

  现在带领大家推导一下BP算法公式,让大家有一个直观的理解。

  令表示第l-1层的第i个神经元到第l层的第j个神经元的连接权值,表示第l层第j个神经元的输入,表示第l层第j个神经元的输出,表示第l层第j个神经元的偏置,C代表代价函数(Cost Function),则有:

           image.png    (1.2)

  image.png             (1.3)

  其中,f(·)表示激活函数,比如sigmoid函数。

  训练多层网络的目的就是使代价函数C最小化,对于一个单独的训练样本x,其标签为Y,定义其代价函数为:

               image.png(1.4)

  可以看出,这个函数依赖于实际的目标值Y,yL可以看成是权值和偏置的函数,通过不断地修改权值和偏置值来改变神经网络的输出值。

  接下来就要更新权值和偏值。首先定义误差δ,令表示第l层第j个神经元上的误差,可定义为:

           image.png    (1.5)

  结合式(1.2)和式(1.3),由链式法则可得输出层的误差方程为:

              image.png (1.6)

  因为当前层神经元的输入是上一层神经元输出的线性组合,由链式法则可实现通过下层神经元的误差来表示当前层的误差:

               image.png(1.7)

  又因是的函数,可得:

        image.png       (1.8)

  对求偏导,可得:

           image.png    (1.9)

  故有:

             image.png  (1.10)

  以上就是反向传播的过程,即第l层神经元j的误差值,等于第l+1层所有与神经元j相连的神经元误差值的权重之和,再乘以该神经元j的激活函数梯度。

  权值的更新可以通过式(1.11)获得:

             image.png  (1.11)

  则:

               image.png(1.12)

              image.png (1.13)

  由梯度下降法可得更新规则为:

               image.png(1.14)

             image.png  (1.15)

  由此可以看出,反向传播的过程就是更新神经元误差值,然后再根据所求出的误差值正向更新权值和偏值。

  接下来给出基于BP算法的多层感知机解决异或问题的Python实例,例子中对神经元添加非线性输入,使等效的输入维度变大,划分对象不再是线性。代码如下:

 

import numpy as np

import matplotlib.pyplot as plt

n = 0                                                                       #迭代次数

lr = 0.11                                                                     #学习速率

#输入数据分别是:偏置值、x1、x2、x1^2、x1*x2、x2^2

X = np.array([[1,0,0,0,0,0],

            [1,0,1,0,0,1],

            [1,1,0,1,0,0],

            [1,1,1,1,1,1]])

#标签

Y = np.array([-1,1,1,-1])

# 权重初始化,取值范围为-1~1

W = (np.random.random(X.shape[1])-0.5)*2

print('初始化权值:',W)

def get_show():

    # 正样本

    x1 = [0, 1]

    y1 = [1, 0]

    # 负样本

    x2 = [0,1]

    y2 = [0,1]

    #生成x刻度

    xdata = np.linspace(-1, 2)

    plt.figure()

    #画出两条分界线

    plt.plot(xdata, get_line(xdata,1), 'r')

    plt.plot(xdata, get_line(xdata,2), 'r')

    plt.plot(x1, y1, 'bo')

    plt.plot(x2, y2, 'yo')

    plt.show()

 

#获得分界线

def get_line(x,root):

    a = W[5]

    b = W[2] + x*W[4]

    c = W[0] + x*W[1] + x*x*W[3]

    #两条不同的分界线

    if root == 1:

        return (-b+np.sqrt(b*b-4*a*c))/(2*a)

    if root == 2:

        return (-b-np.sqrt(b*b-4*a*c))/(2*a)

 

#更新权值函数

def get_update():

    global X,Y,W,lr,n

    n += 1

    #新输出:X与W的转置相乘,得到的结果再由阶跃函数处理,得到新输出

    new_output = np.dot(X,W.T)

    #调整权重: 新权重 = 旧权重 + 改变权重

    new_W = W + lr*((Y-new_output.T).dot(X))/int(X.shape[0])

    W = new_W

def main():

    for _ in range(100):

        get_update()

        get_show()

    last_output = np.dot(X,W.T)

    print('最后逼近值:',last_output)

if __name__ == "__main__":

  main()

 

  结果示意图如图1.5所示。

  虽然BP算法应用广泛,但同时存在优化函数容易陷入局部最优问题,在优化过程中偏离真正的全局最优点,性能下降,并且“梯度消失”现象严重等问题亟待解决。这些问题也限制了BP神经网络在计算机视觉等方面的应用。

 image.png

图1.5  感知机模型解决NOR问题结果示意图


【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。