精华内容
下载资源
问答
  • 【深度学习】前向传播和反向传播(四)
    千次阅读
    2020-03-05 17:20:24

    写在最前面的话:今天要梳理的知识点是深度学习中的前/反向传播的计算,所需要的知识点涉及高等数学中的导数运算。

    在深度学习中,一个神经网络其实就是多个复合函数组成。函数的本质就是将输入x映射到输出y中,即 f ( x ) = y f(x)=y f(x)=y,而函数中的系数就是我们通过训练确定下来的,那么如何训练这些函数从而确定参数呢?这就涉及网络中的两个计算:前向传播和反向传播。

    前向传播

    前向传播(Forward Propagation)的理解较为简单,从输入经过一层层隐层计算得到输出的过程即为前向过程,也称前向传播。举个栗子,假设网络中只有一个神经元,
    单个神经元网络
    单个神经元网络中,正向传播是:(公式1)
    y = W ∗ x + B y=W*x+B y=Wx+B
    而反向传播则是根据(标签值Y-预测值y),来调整W和B。

    反向传播

    反向传播(Backward Propagation)则是与前向传播的计算方向相反,它是通过输出值与真实值之间的误差,来更新训练参数,具体来说反向传播是根据损失函数,通过网络反向流动来计算每一层参数的梯度(偏导数),从而更新参数。反向传播解决了神经网络中训练模型时参数的更新问题,所以理解反向传播较为重要!对于上面单个神经元网络的栗子,它的损失函数假设为(标签值Y-预测值y)不考虑正则化问题,即:
    L = Y − ( W ∗ x + B ) L=Y-(W*x+B) L=Y(Wx+B)
    如果我们想要知道参数W和B对y做了多少贡献(即当W和B改变时,y如何变化),分别对(公式1)中W和B求导。可得到W的贡献为x,而B的贡献为1,因此,我们可以得到 △ W = ϑ L ϑ W = x \bigtriangleup W=\frac{\vartheta L}{\vartheta W}=x W=ϑWϑL=x △ B = ϑ L ϑ B = 1 \bigtriangleup B=\frac{\vartheta L}{\vartheta B}=1 B=ϑBϑL=1,因此可得更新参数 W ′ = W + △ W , B ′ = B + △ B W'=W+\bigtriangleup W, B'=B+\bigtriangleup B W=W+W,B=B+B
    最后通过观察W,B与loss之间的关系:

    • 如果正比关系,那么需要降低W/B值,来减少损失值loss
    • 如果反比关系,那么需要增大W/B值,来减少损失值loss

    以上就是简单的单个神经元网络中的反向传播。如果神经网络较为复杂,我们需要用到链式法则: ϑ L ϑ x = ϑ L ϑ y ϑ y ϑ x \frac{\vartheta L}{\vartheta x}=\frac{\vartheta L}{\vartheta y}\frac{\vartheta y}{\vartheta x } ϑxϑL=ϑyϑLϑxϑy

    太简单的例子相对比较好理解。为了加深上面的理解,我们再举一个多层神经网络,先借用一幅图:
    多层
    上图显示了多层网络中的L1、L2和L3层,经过L2层的输出为 a i ( 2 ) a_i^{(2)} ai(2),经过L3层后的输出为 h W , b h_{W,b} hW,b,其中每一层对应的表达式为:
    a 1 ( 2 ) = f ( u 11 ( 1 ) x 1 + u 12 ( 1 ) x 2 + u 13 ( 1 ) x 3 + v 1 ( 1 ) ) a_1^{(2)}=f(u_{11}^{(1)}x_1+u_{12}^{(1)}x_2+u_{13}^{(1)}x_3+v_1^{(1)}) a1(2)=f(u11(1)x1+u12(1)x2+u13(1)x3+v1(1))
    a 2 ( 2 ) = f ( u 21 ( 1 ) x 1 + u 22 ( 1 ) x 2 + u 23 ( 1 ) x 3 + v 2 ( 1 ) ) a_2^{(2)}=f(u_{21}^{(1)}x_1+u_{22}^{(1)}x_2+u_{23}^{(1)}x_3+v_2^{(1)}) a2(2)=f(u21(1)x1+u22(1)x2+u23(1)x3+v2(1))
    a 3 ( 2 ) = f ( u 31 ( 1 ) x 1 + u 32 ( 1 ) x 2 + u 33 ( 1 ) x 3 + v 3 ( 1 ) ) a_3^{(2)}=f(u_{31}^{(1)}x_1+u_{32}^{(1)}x_2+u_{33}^{(1)}x_3+v_3^{(1)}) a3(2)=f(u31(1)x1+u32(1)x2+u33(1)x3+v3(1))
    h W , b ( x ) = f ( W 11 ( 2 ) a 1 ( 2 ) + W 12 ( 2 ) a 2 ( 2 ) + W 13 ( 2 ) a 3 ( 2 ) + b 1 ( 2 ) ) h_{W,b}(x)=f(W_{11}^{(2)}a_1^{(2)}+W_{12}^{(2)}a_2^{(2)}+W_{13}^{(2)}a_3^{(2)}+b_1^{(2)}) hW,b(x)=f(W11(2)a1(2)+W12(2)a2(2)+W13(2)a3(2)+b1(2))
    其中 W i , j W_{i,j} Wi,j u i , j u_{i,j} ui,j是相邻两层神经元之间的权重(对应图中的相邻两层之间的每一条连线),为深度学习中训练的参数。为了简化上面表达式,我们将上角标去掉,得到:
    a i = f ( u i 1 x 1 + u i 2 x 2 + u i 3 x 3 + v i ) = f ( U i X i + V i ) a_i=f(u_{i1}x_1+u_{i2}x_2+u_{i3}x_3+v_i)=f(U_iX_i+V_i) ai=f(ui1x1+ui2x2+ui3x3+vi)=f(UiXi+Vi)
    h W , b = f ( W i 1 a 1 + W i 2 a 2 + W i 3 a 3 + b i ) = f ( W i a i + b i ) h_{W,b}=f(W_{i1}a_1+W_{i2}a_2+W_{i3}a_3+b_i)=f(W_ia_i+b_i) hW,b=f(Wi1a1+Wi2a2+Wi3a3+bi)=f(Wiai+bi)
    通常我们采用误差的平方来衡量损失,因此损失函数为:
    E r r o r = ( h − y ) , C o s t = ( E r r o r ) 2 = ( h − y ) 2 Error=(h-y),Cost=(Error)^2=(h-y)^2 Error=(hy)Cost=(Error)2=(hy)2

    根据链式法则,我们可以得到:
    ϑ C o s t ϑ W = ϑ C ϑ h ϑ h ϑ W = 2 × ( h − y ) ⋅ a \frac{\vartheta Cost}{\vartheta W}=\frac{\vartheta C}{\vartheta h}\frac{\vartheta h}{\vartheta W}=2\times(h-y)\cdot a ϑWϑCost=ϑhϑCϑWϑh=2×(hy)a
    ϑ C o s t ϑ U = ϑ C ϑ h ϑ h ϑ a ϑ a ϑ U = 2 × ( h − y ) ⋅ w ⋅ x \frac{\vartheta Cost}{\vartheta U}=\frac{\vartheta C}{\vartheta h}\frac{\vartheta h}{\vartheta a}\frac{\vartheta a}{\vartheta U}=2\times(h-y)\cdot w\cdot x ϑUϑCost=ϑhϑCϑaϑhϑUϑa=2×(hy)wx
    因此,可以得到参数更新的差值 △ W = ϑ C o s t ϑ W \bigtriangleup W=\frac{\vartheta Cost}{\vartheta W} W=ϑWϑCost △ U = ϑ C o s t ϑ U \bigtriangleup U=\frac{\vartheta Cost}{\vartheta U} U=ϑUϑCost

    总结

    本文简单梳理了前向传播和反向传播,以及相关计算。梳理得有点简单,往后想到再继续补充吧~

    参考文章:
    https://www.cnblogs.com/cation/p/11664741.html
    https://blog.csdn.net/qq_16137569/article/details/81449209
    https://www.zhihu.com/question/27239198?rf=24827633

    更多相关内容
  • 神经网络的前向传播和反向传播推导 x1x_{1}x1​x2x_{2}x2​表示输入 wijw_{ij}wij​表示权重 bijb_{ij}bij​表示偏置 σi\sigma_{i}σi​表示激活函数,这里使用sigmoid激活函数 outoutout表示输出 yyy表示真实值...
  • 前向传播和反向传播

    千次阅读 2019-02-15 23:35:28
    前向传播和反向传播1. 前向传播2. 反向传播 例程:生产一批零件,将体积X1重量X2为特征输入NN,通过NN后输出一个数值 1. 前向传播 前向传播过程 用Tensorflow表示前向传播 X为1*2的...

    例程:生产一批零件,将体积X1和重量X2为特征输入NN,通过NN后输出一个数值

    1. 前向传播

    前向传播就是搭建模型的计算过程,让模型具有推理能力,可以针对一组输入给出相应的输出

    1.1 前向传播过程

    在这里插入图片描述

    • 第一层
    X W ( 1 ) W^(1^) W(1)a
    x 表示输入,是一个 1 行 2 列矩阵,表示1次输入1组特征(包含了体积和重量两个元素)对于第一层的 w 前面有两个节点,后面有三个节点 W ( 1 ) W^(1^) W(1) 应该是个2行3列矩阵a 为第一层网络,a 是一个1行3列矩阵
    • 第二层
    W ( 2 ) W^(2^) W(2)
    参数要满足前面三个节点,后面一个节点,所以 是3行1列矩阵

    注:神经网络共有几层(或当前是第几层网络)都是指的计算层,输入不是计算层,所以 a 为第一层网络

    1.2 用Tensorflow表示前向传播

    -

    • 变量初始化、计算图节点运算都要用会话(with 结构)实现
      with tf.Session() as sess:
      sess.run()

      • 变量初始化:在 sess.run 函数中用 tf.global_variables_initializer()汇总所有待优化变量。
        init_op = tf.global_variables_initializer()
        sess.run(init_op)
      • 计算图节点运算:在 sess.run 函数中写入待运算的节点
        sess.run(y)
      • 用 tf.placeholder 占位,在 sess.run 函数中用 feed_dict 喂数据
        喂一组数据:
        x = tf.placeholder(tf.float32, shape=(1, 2))
        sess.run(y, feed_dict={x: [[0.5,0.6]]})
        喂多组数据:
        x = tf.placeholder(tf.float32, shape=(None, 2))
        sess.run(y, feed_dict={x: [[0.1,0.2],[0.2,0.3],[0.3,0.4],[0.4,0.5]]})

    1.3 实现神经网络前向传播过程,网络自动推理出输出 y 的值

    • 例1:用 placeholder 实现输入定义(sess.run 中喂入一组数据)的情况
      第一组喂体积 0.7、重量 0.5
    #coding:utf-8
    import tensorflow as tf
    
    #定义输入和参数
    x=tf.placeholder(tf.float32,shape=(1,2))
    w1=tf.Variable(tf.random_normal([2,3],stddev=1,seed=1))
    w2=tf.Variable(tf.random_normal([3,1],stddev=1,seed=1))
    
    #定义前向传播过程
    a=tf.matmul(x,w1)
    y=tf.matmul(a,w2)
    
    #用会话计算结果
    with tf.Session() as sess:
    	init_op=tf.global_variables_initializer()
    	sess.run(init_op)
    	print (sess.run(y,feed_dict={x:[[0.7,0.5]]}))
    
    • 例2:用 placeholder 实现输入定义(sess.run 中喂入多组数据)的情况
      第一组喂体积 0.7、重量 0.5,第二组喂体积 0.2、重量 0.3,第三组喂体积0.3、重量 0.4,第四组喂体积 0.4、重量 0.5.
    #coding:utf-8
    import tensorflow as tf
    #定义输入和参数
    x=tf.placeholder(tf.float32,shape=(None,2))
    w1=tf.Variable(tf.random_normal([2,3],stddev=1,seed=1))
    w2=tf.Variable(tf.random_normal([3,1],stddev=1,seed=1))
    #定义前向传播过程
    a=tf.matmul(x,w1)
    y=tf.matmul(a,w2)
    #用会话计算结果
    with tf.Session() as sess:
    	init_op=tf.global_variables_initializer()
    	sess.run(init_op)
    	print(sess.run(y,feed_dict={x:[[0.7,0.5],[0.2,0.3],[0.3,0.4],[0.4,0.5]]}))
    

    2. 反向传播

    反向传播:就是训练模型参数,在所有参数上用梯度下降,使 NN 模型在训练数据上的损失函数最小

    2.1 损失函数

    损失函数(loss):计算得到的预测值 y 与已知答案 y_的差距

    • 损失函数计算方法:有很多方法,均方误差 MSE 是比较常用的方法之一
    均方误差 MSE解释
    定义求前向传播计算结果与已知答案之差的平方再求平均
    公式图1
    tensorflow 函数表示loss_mse = tf.reduce_mean(tf.square(y_ - y))

    2.2 反向传播训练方法:以减小 loss 值为优化目标

    反向传播训练方法梯度下降momentum 优化器adam 优化器、、、
    用 tensorflow 函数表示train_step=tf.train.GradientDescentOptimizer(learning_rate).minimize(loss)train_step=tf.train.MomentumOptimizer(learning_rate, momentum).minimize(loss)train_step=tf.train.AdamOptimizer(learning_rate).minimize(loss)
    区别使用随机梯度下降算法,使参数沿着梯度的反方向,即总损失减小的方向移动,实现更新参数更新参数时,利用了超参数利用自适应学习率的优化算法,Adam 算法和随机梯度下降算法不同。随机梯度下降算法保持单一的学习率更新所有的参数,学习率在训练过程中并不会改变。而 Adam 算法通过计算梯度的一阶矩估计和二阶矩估计而为不同的参数设计独立的自适应性学习率
    参数更新的公式在这里插入图片描述 损失函数:J(?) 参数:?,学习率:?在这里插入图片描述 ?为学习率,超参数为?,?为参数,损失函数的梯度:?(??−1)
    • 学习率
      • 决定每次参数更新的幅度
      • 优化器中都需要一个叫做学习率的参数,使用时,如果学习率选择过大会出现震荡不收敛的情况,如果学习率选择过小,会出现收敛速度慢的状况。我们可以选个比较小的值填入,比如 0.01、0.001
    展开全文
  • 详解神经网络的前向传播和反向传播(从头推导)

    万次阅读 多人点赞 2018-08-06 17:12:35
    详解神经网络的前向传播和反向传播 本篇博客是对Michael Nielsen所著的《Neural Network and Deep Learning》第2章内容的解读,有兴趣的朋友可以直接阅读原文Neural Network and Deep Learning。  对神经网络有些...

    详解神经网络的前向传播和反向传播

    本篇博客是对Michael Nielsen所著的《Neural Network and Deep Learning》第2章内容的解读,有兴趣的朋友可以直接阅读原文Neural Network and Deep Learning

      对神经网络有些了解的人可能都知道,神经网络其实就是一个输入 X X 到输出Y的映射函数: f(X)=Y f ( X ) = Y ,函数的系数就是我们所要训练的网络参数 W W ,只要函数系数确定下来,对于任何输入xi我们就能得到一个与之对应的输出 yi y i ,至于 yi y i 是否符合我们预期,这就属于如何提高模型性能方面的问题了,本文不做讨论。

      那么问题来了,现在我们手中只有训练集的输入 X X 和输出Y,我们应该如何调整网络参数 W W 使网络实际的输出f(X)=Y^与训练集的 Y Y 尽可能接近?

      在开始正式讲解之前,让我们先对反向传播过程有一个直观上的印象。反向传播算法的核心是代价函数C对网络中参数(各层的权重 w w 和偏置b)的偏导表达式 Cw ∂ C ∂ w Cb ∂ C ∂ b 。这些表达式描述了代价函数值 C C 随权重w或偏置 b b 变化而变化的程度。到这里,BP算法的思路就很容易理解了:如果当前代价函数值距离预期值较远,那么我们通过调整w b b 的值使新的代价函数值更接近预期值(和预期值相差越大,则w b b 调整的幅度就越大)。一直重复该过程,直到最终的代价函数值在误差范围内,则算法停止。

      BP算法可以告诉我们神经网络在每次迭代中,网络的参数是如何变化的,理解这个过程对于我们分析网络性能或优化过程是非常有帮助的,所以还是尽可能搞透这个点。我也是之前大致看过,然后发现看一些进阶知识还是需要BP的推导过程作为支撑,所以才重新整理出这么一篇博客。

    前向传播过程

      在开始反向传播之前,先提一下前向传播过程,即网络如何根据输入X得到输出 Y Y 的。这个很容易理解,粗略看一下即可,这里主要是为了统一后面的符号表达。

    wjkl为第 l1 l − 1 层第 k k 个神经元到第l层第 j j 个神经元的权重,bjl为第 l l 层第j个神经元的偏置, alj a j l 为第 l l 层第j个神经元的激活值(激活函数的输出)。不难看出, alj a j l 的值取决于上一层神经元的激活:

    alj=σ(kwljkal1k+blj)(1) (1) a j l = σ ( ∑ k w j k l a k l − 1 + b j l )
    将上式重写为矩阵形式:
    al=σ(wlal1+bl)(2) (2) a l = σ ( w l a l − 1 + b l )
    为了方便表示,记 zl=wlal1+bl z l = w l a l − 1 + b l 为每一层的权重输入, (2) ( 2 ) 式则变为 al=σ(zl) a l = σ ( z l )
      利用 (2) ( 2 ) 式一层层计算网络的激活值,最终能够根据输入 X X 得到相应的输出Y^

    反向传播过程

      反向传播过程中要计算 Cw ∂ C ∂ w Cb ∂ C ∂ b ,我们先对代价函数做两个假设,以二次损失函数为例:

    C=12nxy(x)aL(x)2(3) (3) C = 1 2 n ∑ x ‖ y ( x ) − a L ( x ) ‖ 2
    其中 n n 为训练样本x的总数, y=y(x) y = y ( x ) 为期望的输出,即ground truth, L L 为网络的层数,aL(x)为网络的输出向量。
    假设1:总的代价函数可以表示为单个样本的代价函数之和的平均:
    C=1nxCx  Cx=12yaL2(4) (4) C = 1 n ∑ x C x     C x = 1 2 ‖ y − a L ‖ 2

      这个假设的意义在于,因为反向传播过程中我们只能计算单个训练样本的 Cxw ∂ C x ∂ w Cxb ∂ C x ∂ b ,在这个假设下,我们可以通过计算所有样本的平均来得到总体的 Cw ∂ C ∂ w Cb ∂ C ∂ b
    假设2:代价函数可以表达为网络输出的函数 costC=C(aL) c o s t C = C ( a L ) ,比如单个样本 x x 的二次代价函数可以写为:
    (5)Cx=12yaL2=12j(yjajL)2

    反向传播的四个基本方程

      权重 w w 和偏置b的改变如何影响代价函数 C C 是理解反向传播的关键。最终,这意味着我们需要计算出每个Cwjkl Cblj ∂ C ∂ b j l ,在讨论基本方程之前,我们引入误差 δ δ 的概念, δlj δ j l 表示第 l l 层第j个单元的误差。关于误差的理解,《Neural Network and Deep Learning》书中给了一个比较形象的例子。

      如上图所示,假设有个小恶魔在第 l l 层第j个单元捣蛋,他让这个神经元的权重输出变化了 Δzlj Δ z j l ,那么这个神经元的激活输出为 σ(zlj+Δzlj) σ ( z j l + Δ z j l ) ,然后这个误差向后逐层传播下去,导致最终的代价函数变化了 CzljΔzlj ∂ C ∂ z j l Δ z j l 。现在这个小恶魔改过自新,它想帮助我们尽可能减小代价函数的值(使网络输出更符合预期)。假设 Czlj ∂ C ∂ z j l 一开始是个很大的正值或者负值,小恶魔通过选择一个和 Czlj ∂ C ∂ z j l 方向相反的 Δzlj Δ z j l 使代价函数更小(这就是我们熟知的梯度下降法)。随着迭代的进行, Czlj ∂ C ∂ z j l 会逐渐趋向于0,那么 Δzlj Δ z j l 对于代价函数的改进效果就微乎其微了,这时小恶魔就一脸骄傲的告诉你:“俺已经找到了最优解了(局部最优)”。这启发我们可以用 Czlj ∂ C ∂ z j l 来衡量神经元的误差:

    δlj=Czlj δ j l = ∂ C ∂ z j l
    下面就来看看四个基本方程是怎么来的。
      
    1. 输出层的误差方程
    δLj=CzLj=CaLjaLjzLj=CaLjσ(zLj)(BP1) (BP1) δ j L = ∂ C ∂ z j L = ∂ C ∂ a j L ∂ a j L ∂ z j L = ∂ C ∂ a j L σ ′ ( z j L )
    如果上面的东西你看明白了,这个方程应该不难理解,等式右边第一项 CaLj ∂ C ∂ a j L 衡量了代价函数随网络最终输出的变化快慢,而第二项 σ(zLj) σ ′ ( z j L ) 则衡量了激活函数输出随 zLj z j L 的变化快慢。当激活函数饱和,即 σ(zLj)0 σ ′ ( z j L ) ≈ 0 时,无论 CaLj ∂ C ∂ a j L 多大,最终 δLj0 δ j L ≈ 0 ,输出神经元进入饱和区,停止学习。
      (BP1)方程中两项都很容易计算,如果代价函数为二次代价函数 C=12j(yjaLj)2 C = 1 2 ∑ j ( y j − a j L ) 2 ,则 CaLj=aLjyj ∂ C ∂ a j L = a j L − y j ,同理,对激活函数 σ(z) σ ( z ) zLj z j L 的偏导即可求得 σ(zLj) σ ′ ( z j L ) 。将(BP1)重写为矩阵形式:
    δL=aCσ(zL)(BP1a) (BP1a) δ L = ∇ a C ⊙ σ ′ ( z L )
    为Hadamard积,即矩阵的点积。
    2. 误差传递方程
    δl=((wl+1)Tδl+1)σ(zl)(BP2) (BP2) δ l = ( ( w l + 1 ) T δ l + 1 ) ⊙ σ ′ ( z l )
    这个方程说明我们可以通过第 l+1 l + 1 层的误差 δl+1 δ l + 1 计算第 l l 层的误差δl,结合(BP1)和(BP2)两个方程,我们现在可以计算网络中任意一层的误差了,先计算 δL δ L ,然后计算 δL1 δ L − 1 δL2 δ L − 2 ,…,直到输入层。
    证明过程如下:
    δlj=Czlj=kCzl+1kzl+1kzlj=kδl+1kzl+1kzlj δ j l = ∂ C ∂ z j l = ∑ k ∂ C ∂ z k l + 1 ∂ z k l + 1 ∂ z j l = ∑ k δ k l + 1 ∂ z k l + 1 ∂ z j l
    因为 zl+1k=jwl+1kjalj+bl+1k=jwl+1kjσ(zlj)+bl+1k z k l + 1 = ∑ j w k j l + 1 a j l + b k l + 1 = ∑ j w k j l + 1 σ ( z j l ) + b k l + 1 ,所以 zl+1kzlj=wl+1kjσ(zlj) ∂ z k l + 1 ∂ z j l = w k j l + 1 σ ′ ( z j l ) ,因此可以得到(BP2),
    δlj=kwl+1kjδl+1kσ(zlj) δ j l = ∑ k w k j l + 1 δ k l + 1 σ ′ ( z j l )

    3. 代价函数对偏置的改变率
    Cblj=Czljzljblj=Czlj=δlj(BP3) (BP3) ∂ C ∂ b j l = ∂ C ∂ z j l ∂ z j l ∂ b j l = ∂ C ∂ z j l = δ j l
    这里因为 zlj=kwljkal1k+blj z j l = ∑ k w j k l a k l − 1 + b j l 所以 zLjbLj=1 ∂ z j L ∂ b j L = 1
    4. 代价函数对权重的改变率
    Cwljk=CzljzLjwljk=Czljal1k=al1kδlj(BP4) (BP4) ∂ C ∂ w j k l = ∂ C ∂ z j l ∂ z j L ∂ w j k l = ∂ C ∂ z j l a k l − 1 = a k l − 1 δ j l
    可以简写为
    Cw=ainδout(6) (6) ∂ C ∂ w = a i n δ o u t
    ,不难发现,当上一层激活输出接近0的时候,无论返回的误差有多大, Cw ∂ C ∂ w 的改变都很小,这也就解释了为什么神经元饱和不利于训练。

      从上面的推导我们不难发现,当输入神经元没有被激活,或者输出神经元处于饱和状态,权重和偏置会学习的非常慢,这不是我们想要的效果。这也说明了为什么我们平时总是说激活函数的选择非常重要。

      当我计算得到 Cwljk ∂ C ∂ w j k l Cblj ∂ C ∂ b j l 后,就能愉悦地使用梯度下降法对参数进行一轮轮更新了,直到最后模型收敛。

    反向传播为什么快

      回答这个问题前,我们先看一下普通方法怎么求梯度。以计算权重为例,我们将代价函数看成是权重的函数 C=C(w) C = C ( w ) ,假设现在网络中有100万个参数,我们可以利用微分的定义式来计算代价函数对其中某个权重 wj w j 的偏导:

    CwjC(w+εej)C(w)ε(7) (7) ∂ C ∂ w j ≈ C ( w + ε e j → ) − C ( w ) ε
    然后我们算一下,为了计算 Cwj ∂ C ∂ w j ,我们需要从头到尾完整进行一次前向传播才能得到最终 C(w+εej) C ( w + ε e j → ) 的值,要计算100万个参数的偏导就需要前向传播100万次,而且这还只是一次迭代,想想是不是特别可怕?
      再反观反向传播算法,如方程(BP4)所示,我们只要知道 al1k a k l − 1 δlj δ j l 就能计算出偏导 Cwljk ∂ C ∂ w j k l 。激活函数值 al1k a k l − 1 在一次前向传播后就能全部得到,然后利用(BP1)和(PB2)可以计算出 δlj δ j l ,反向传播和前向传播计算量相当,所以总共只需2次前向传播的计算量就能计算出所有的 Cwljk ∂ C ∂ w j k l 。这比使用微分定义式求偏导的计算量少了不止一点半点,简直是质的飞跃。

    展开全文
  • 本文为作者本人对卷积神经网络的前向反向传播过程数学推导的总结笔记,对深度学习初学者来说是个对卷积神经网络深度了解很好的机会,是自己搭建卷积神经网络的理论支持,欢迎下载,共同进步
  • 神经网络的前向传播和反向传播

    千次阅读 2020-05-25 00:50:23
    在讨论反向传播之前,我们讨论一下前向传播,即根据输入X来计算输出Y。输入X用矩阵表示,我们看一下如何基于矩阵X来计算网络的输出Y。 我们使用 表示从层的第 个神经元到层的个神经元的链接上的权重。例如,下图给...

    本博客是对Michael Nielsen所著的《Neural Network and Deep Learning》第2章内容的解读,有兴趣的朋友可以直接阅读原文http://neuralnetworksanddeeplearning.com/chap2.html

    前向传播过程

    在讨论反向传播之前,我们讨论一下前向传播,即根据输入X来计算输出Y。输入X用矩阵表示,我们看一下如何基于矩阵X来计算网络的输出Y。

    我们使用 表示从 ( - 1) 层的第 k 个神经元到  层的第 j 个神经元的链接上的权重。例如,下图给出了网络中第二层的第四个神经元到第三层的第二个神经元的链接上的权重:

    我们使用表示在  层第 j 个神经元的偏置,使用表示  层第 j 个神经元的激活值(激活函数的输出)。

    那么,第  层的第 j 个神经元的激活值可以表示为:

                                                             (1)

    其中,为激活函数。

    对每一层 ,定义一个权重矩阵,权重矩阵 的元素正是连接到  层神经元的权重,矩阵中第 j 行第 k 列的元素是 。类似的,对每一层,定义一个偏置向量,向量的每个元素为,每个元素对应于  层每个神经元的偏置。最后,我们定义激活向量,其元素是那些激活值

    那么,公式(1)就可以表示为如下的向量形式:

                                                              (2)

    这个表达式给出了一种更加全局的思考每层的激活值和前一层激活值的关联方式:用权重矩阵作用在激活值上,然后加上一个偏置向量,最后作用 σ 函数,则得到每层的激活值。

    为了方便表示,记,表示  层神经元的权重输入,则公式(2)变为

     

    输入X,然后根据公式(2)一层层计算网络的激活值,最终得到网络的输出Y。

     

    反向传播过程

    反向传播的两个假设

    反向传播的目标是计算代价函数C关于w和b的偏导数∂C/∂w 和 ∂C/∂b。为了使反向传播工作,我们需要对代价函数做两个假设。在给出这两个假设之前,我们先看一个具体的代价函数,即如下的二次代价函数:

                                         (3)

    其中x为训练样本,n是训练样本的总数;y = y(x) 是期望的输出,即样本的真实值;L表示网络的层数;为网络的输出向量。

    假设1:代价函数可以表示为单个样本的代价函数的均值,即:

                                                  (4)

    其中,表示训练样本x的代价函数。以二次代价函数为例,

    需要做这个假设的原因是,反向传播实际上是对一个独立的训练样本计算了 ∂Cx/∂w 和 ∂Cx/∂b。在这个假设下,我们可以通过计算所有样本的平均来得到总体的∂C/∂w 和 ∂C/∂b。

    假设2:代价函数可以表示为神经网络输出的函数:

    比如,单个样本x的平方代价函数可以写为:

                          (5)

    这是输出的激活值的函数。当然,这个代价函数同样还依赖于目标输出 y。不过,输入的训练样本 x 是固定的,所以输出 y 同样是一个固定的参数。尤其是它并不会随权重和偏置而改变,也就是说,这不是神经网络学习的对象。所以,将C看成输出激活值的函数才是合理的,而 y 仅仅是帮助定义函数的参数而已。

    反向传播的四个基本方程

    反向传播指的是权重w和偏置b的改变如何改变代价函数C。其含义其实就是计算偏导数。在讨论基本方程之前,我们引入一个中间变量,表示第  层第 j 个单元的误差。关于误差,《Neural Networks and Deep Learning》给出了一个很形象的例子:

    如上图所示,假设网络中有个小调皮鬼,他在第  层第 j 个神经元上。当输入进来时,调皮鬼对神经元的操作进行扰乱,导致神经元的权重输入增加很小的变化,使得神经元输出由变为。这个变化向网络后面的层进行传播,最终导致整个代价产生的改变为 。

    现在,这个调皮鬼改过自新了,他想帮助我们尽可能减小代价,他试着找到可以让代价更小的。假设一开始是个很大的正值或负值,那么,调皮鬼可以通过选择一个和方向相反的使代价函数更小。随着迭代的进行,会逐渐趋近于0,那么对代价函数的改进就微乎其微了。这时,对调皮鬼来说,他已经找到最优解了(局部最优)。这启发我们可以用来衡量神经元的误差。即, 层第 j 个神经元的误差为:

                                               (6)

    我们用来表示  层的误差向量。

     

    下面我们看看反向传播的四个基本方程。

    1. 输出层的误差方程,

    由于,应用链式法则,加入输出激活值的偏导数,则之前偏导数变为:

                                  (7)

    求和是在输出层的所有神经元k上进行的。第 k 个神经元的输出激活值只依赖于当 k = j 时第 j 个神经元的输入权重,所以当  k ≠ j 时 项为0。则上一个方程可以简化为:

                                              (8)

    由于,上式中右边第二项可以写为,则方程变为:

                                                 (BP1)

    右式第一项∂C/表示代价随着第 j 个输出激活值的变化而变化的速度。右式第二项刻画了在处激活函数 σ 变化的速度。

    (BP1)改写为矩阵形式,为:

                           (BP1a)

    其中,是一个向量,其元素为偏导数∂C/表示hadamard乘积运算。

     

    注:hadamard乘积即按元素乘法,比如:

     

    2. 误差传递方程:

    即,根据下一层的误差来表示误差

    根据公式(6),,应用链式法则:

                            (9)

    注意:

                       

    做微分,则得到:

    把它代入公式(9),则得到:

    改为分量形式,则为:

                                        (BP2

    这个方程说明我们可以通过第 l + 1 层的误差计算第 l 层的误差。结合(BP1)和(BP2),我们可以计算任何层的误差。首先,使用方程(BP1)计算,然后用方程(BP2)来计算,然后再次用方程(BP2)来计算,如此一步一步的反向传播完整个网络。

     

    3. 代价函数对bias的改变率

                                                    (BP3)

    由于,所以

     

    4. 代价函数对权重的改变率

                                                       (BP4)

    可以简写为:

    其中,是输入给权重w的的神经元的激活值,是输出自权重 w 的神经元的误差。

    不难看出,当上一层激活值很小的时候,即 ≈ 0,无论误差多大,梯度 ∂C/∂w 也会很小,表示在梯度下降的时候,这个权重不会改变太多。也就是说,来自低激活值神经元的权重学习会非常缓慢。

    另外,从输出层看,先看看(BP1  )中的项。若σ为sigmoid函数,在靠近0和1的时候,σ函数变得非常平。这时≈ 0。所以,如果输出神经元处于低激活值(≈ 0)或高激活值(≈ 1)时,最终层的权重/bias变化也会比较小,学习变慢。此时,我们常常称输出神经元已经饱和了。

    总结来说,如果输入神经元激活值很低,或者输出神经元已经饱和了(过高或过低的激活值),权重和bias会学习的非常慢。

    反向传播算法

    有了以上反向传播方程,反向传播算法描述如下:

    1. 输出 x

    2. 前向传播:对l = 2, 3, ..., L,计算

    3. 计算输出层误差:计算向量

    4. 反向传播误差:对每个 l = L - 1, L - 2, ..., 2,计算

    5. 输出:计算代价函数梯度

    得到梯度后,就可以使用梯度下降法对参数进行一轮轮更新了,直到最后模型收敛。

     

    为什么说反向传播算法高效

    在哪种层面上,反向传播是快速的算法?为了回答这个问题,首先考虑另一个计算梯度的方法。把代价看做权重的函数 C = C(w)。你给这些权重,...进行编号,期望计算某些权重的偏导数。 而一种近似的方法就是下面这种:

                                      (10)

    其中 ε > 0 是一个很小的正数,而  是在第 j 个方向上的单位向量。换句话说,我们可以通过计算两个接近相同的 的代价 C 来估计 。同样方法也可以用来计算 ∂C/∂b。

    不过,这个方法非常低效。假如我们的网络中有100万个权重。要计算,我们需要从头到尾进行一次完整的前向传播才能得到的值。要计算100万个权重的偏导就需要前向传播100万次。我们同样需要计算 C(w),需要一次网络传播。总共需要 100百万+1 次网络传播。

    再反观反向传播算法,根据方程(BP4),我们只需要知道就能计算出。激活值在一次前向传播后就能全部得到,然后利用(BP1)和(BP2)就可以计算出。反向传播和前向传播计算量相当,所以,总共需要2次前向传播的计算量就能计算出所有的。对比用微分定义求偏导的100百万次,计算量大大减少。

     

    展开全文
  • 神经网络的前向传播和反向传播总述正文开始初始化Step 1 前向传播1.输入层---->隐含层:2.隐含层---->输出层:Step 2 反向传播1.计算总误差2.隐含层---->输出层的权值更新:3.隐含层---->隐含层的权值...
  • 本文只包含CNN的前向传播和反向传播,主要是卷积层pool层的前向传播和反向传播,一些卷积网络的基础知识不涉及 符号表示 如果lll层是卷积层: p[l]p[l]p^{[l]}: padding s[l]s[l]s^{[l]}: stride n[l]cnc...
  • 手推BP神经网络的前向传播和反向传播 一、基本术语 1、监督学习与非监督学习 Supervised Learning有监督式学习: 输入的数据被称为训练数据,一个模型需要通过一个训练过程,在这个过程中进行预期判断,如果错误了再...
  • 对于CNN卷积神经网络的前向传播和反向传播的理解 前向传播示意图: ​ 咋一看这张图,作为初学者可能会**不知所云( ̄ω ̄=)**?但是想要很好的理解前向传播的原理,我们得从这张图细说。 1.首先我们从x,w的参数...
  • RNN的前向传播和反向传播

    千次阅读 2020-04-20 16:01:43
    在上一节当中,我们讲到了RNN的其中一个特点是参数共享,在这一节当中,我们用具体代码来展示RNN的前向传播。 首先是给出每一个参数具体的值: W指的是相邻时刻隐藏单元间的权重矩阵,U指的是从X(t)计算得到的对应...
  • 听了吴恩达老师的课程之后,按照老师的方法画出神经网络中前向传播和反向传播的示意图,如有错误,请交流指正! 其中,caches部分表示“缓存的信息”,以用于后面计算中的调用。 每一步骤所需的数据已用不同颜色的...
  • 通常,在得到前向传播结果后,会需要定义一个损失函数(例如交叉熵)来刻画当前的预测值真实答案之间的差距。目前Tensor支持7种反向传播的优化器,比较常用的优化方法有3种:tf.train.GradientDescentOptimizer、...
  • 前向传播 输入,输出,缓存为 前向传播的过程: 向量化的过程可以写成: 式中,就是初始的输入X。如下图的两层神经网络所示,可以很好的理解。 反向传播 反向传播主要采用数学上的链式法则,反向...
  • 机器学习之多层网络前向传播和反向传播 在上一篇文章中提到了单层感知机的前向传播后向传播。 现在再谈谈对多层感知机的前向、后向传播的理解。 多层感知机顾名思义,就是由多个神经元构成的一组网络。 可以...
  • 前向传播与反向传播

    2018-10-21 21:52:28
    人工智能技术是现代社会非常火的一门技术,前向传播与后向传播为其中的一项重要技术
  • 前向传播和反向传播(举例说明)

    万次阅读 多人点赞 2017-09-19 16:25:06
    假设神经网络结构如下图所示:有2个...----前向传播---- 隐含层神经元h1的输入: 代入数据可得: 假设激励函数用logistic函数,计算得隐含层神经元h1的输出: 同样的方法,可以得到隐含层神经元h
  • 以如下的预测是否是猫的双层神经网络为例进行公式推导: 符号注解: n_x : 输入特征的数量 ...前向传播: 反向传播: 更新参数: 部分偏导我全用导数代替了,不影响最终结果。字有...
  • 神经网络前向传播与反向传播 神经网络 神经网络通俗地可以理解成一个函数近似器,它需要近似一个输入x到输出y的映射函数。我们所要训练的网络参数其实就是在拟合这个映射函数的未知量。神经网络的训练可以分为两个...
  • 1.前向传播: 以三层神经网络为例,图中input为0.9,0.1,0.8,我们不用数字,用字母代替,设输入为x1,x2,x3,隐藏层的第一个神经元输出Ohidden1=S[(w11x1+b1)+(w21x2+b2)+(w31*x1+b3)](原文中未考虑偏置,这里...
  • 1. 普通递推神经网络(Recurrent Neural Network)的前向传播公式 2. 门控递推单元(Gated Recurrent Unit,GRU)的前向传播公式 3. 长短期记忆单元(Long Short-Term Memory,LSTM)的前向传播公式 4. ...
  • 卷积前向传播 卷积反向传播 池化前向传播和反向传播
  • 一个典型的神经元模型可以用下图表示: ...对于一个还没有训练好的神经网络而言,各个神经元之间的参数都是随机值,即初始化时赋的值,前向传播过程是神经网络的输入输出过程,即网络是如何根据A的值得到输出的Y值...
  • 在神经网络模型中包括前向传播和反向传播那么究竟什么是前向传播,什么是反向传播前向传播:说的通俗一点就是从输入到得到损失值的过程,当然不仅仅是这么简单,中间还经过了一些处理,那么这些处理包括什么呢:1...
  • # 定义神经网络前向传播的过程 a = tf.matmul(x, w1) # a为隐藏层的输出,matmul为矩阵的相乘 y = tf.matmul(a, w2) # y为神经网络的输出 # 定义损失函数和反向传播的算法 cross_entropy = -tf.reduce_mean(y_ * tf....
  • 2.1 前向传播 2.1.1 输入层到隐含层 NET(h1)=w1*i1+w2*i2+b1=0.25*0.02+0.25*0.04+0.4=0.005+0.01+0.4=0.415 神经元h1到输出h1的激活函数是sigmoid OUT(h1)=1/(1+e^(-NET(h1)))=1/(1+0.660340281)=0.602286177 同理...
  • 虽然学深度学习有一段时间了,但是对于一些算法的具体实现还是模糊不清,用了很久也不是很了解,最近在看去年LeCunHinton在Nature上发表的deep learning的review,有两张图分别是讲得网络的前向传播和反向传播,...
  • 当前,深度学习已经应用到很多领域:无人驾驶汽车,黑科技以及图像分类等等,这些前沿的科技也面临许多挑战,如无人驾驶...深度学习的过程可以分为前向传播和反向传播两个过程,前向传播。 简单来说,前向传播过程就是
  • 前向传播和反向传播最好的实例就是自己算一一遍。跟着链接一步步走一定能明白的。 所以前向传播并不能带来学习的效果,而反向传播才是学习效果的关键。 关于梯度的问题,反向传播很明显是使用了梯度了。里面的梯度...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 109,397
精华内容 43,758
关键字:

前向传播和反向传播