精华内容
下载资源
问答
  • 前向传播和反向传播

    千次阅读 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 。这比使用微分定义式求偏导的计算量少了不止一点半点,简直是质的飞跃。

    展开全文
  • 神经网络的前向传播和反向传播推导 x1x_{1}x1​x2x_{2}x2​表示输入 wijw_{ij}wij​表示权重 bijb_{ij}bij​表示偏置 σi\sigma_{i}σi​表示激活函数,这里使用sigmoid激活函数 outoutout表示输出 yyy表示真实值...
  • 【深度学习】前向传播和反向传播(四) 写在最前面的话:今天要梳理的知识点是深度学习中的前/反向传播的计算,所需要的知识点涉及高等数学中的导数运算。 在深度学习中,一个神经网络其实就是多个复合函数组成。...

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

    在深度学习中,一个神经网络其实就是多个复合函数组成。函数的本质就是将输入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

    展开全文
  • 本文只包含CNN的前向传播和反向传播,主要是卷积层pool层的前向传播和反向传播,一些卷积网络的基础知识不涉及 符号表示 如果lll层是卷积层: p[l]p[l]p^{[l]}: padding s[l]s[l]s^{[l]}: stride n[l]cnc...

    title: CNN卷积层和pooling层的前向传播和反向传播
    tags: CNN,反向传播,前向传播
    grammar_abbr: true
    grammar_table: true
    grammar_defList: true
    grammar_emoji: true
    grammar_footnote: true
    grammar_ins: true
    grammar_mark: true
    grammar_sub: true
    grammar_sup: true
    grammar_checkbox: true
    grammar_mathjax: true
    grammar_flow: true
    grammar_sequence: true
    grammar_plot: true
    grammar_code: true
    grammar_highlight: true
    grammar_html: true
    grammar_linkify: true
    grammar_typographer: true
    grammar_video: true
    grammar_audio: true
    grammar_attachment: true
    grammar_mermaid: true
    grammar_classy: true
    grammar_cjkEmphasis: true
    grammar_cjkRuby: true
    grammar_center: true
    grammar_align: true
    grammar_tableExtra: true

    本文只包含CNN的前向传播和反向传播,主要是卷积层和pool层的前向传播和反向传播,一些卷积网络的基础知识不涉及

    符号表示

    如果 l l l层是卷积层:

    p [ l ] p^{[l]} p[l]: padding
    s [ l ] s^{[l]} s[l]: stride
    n c [ l ] n_c^{[l]} nc[l] : number of filters

    fliter size: k 1 [ l ] × k 2 [ l ] × n c [ l − 1 ] k_1^{[l]} \times k_2^{[l]}\times n_c^{[l-1]} k1[l]×k2[l]×nc[l1]
    Weight: W [ l ] W^{[l]} W[l] size is k 1 [ l ] × k 2 [ l ] × n c l − 1 × n c l k_1^{[l]} \times k_2^{[l]} \times n_c^{l - 1} \times n_c^{l} k1[l]×k2[l]×ncl1×ncl
    bais: b [ l ] b^{[l]} b[l] size is n c [ l ] n_{c}^{[l]} nc[l]
    liner: z [ l ] z^{[l]} z[l],size is n h [ l ] × n w [ l ] × n c [ l ] n_h^{[l]} \times n_w^{[l]} \times n_c^{[l ]} nh[l]×nw[l]×nc[l]
    Activations: a [ l ] a^{[l]} a[l] size is n h [ l ] × n w [ l ] × n c [ l ] n_h^{[l]} \times n_w^{[l]} \times n_c^{[l ]} nh[l]×nw[l]×nc[l]

    input: a [ l − 1 ] a^{[l-1]} a[l1] size is n h [ l − 1 ] × n w [ l − 1 ] × n c [ l − 1 ] n_h^{[l-1]} \times n_w^{[l-1]} \times n_c^{[l - 1]} nh[l1]×nw[l1]×nc[l1]
    output: a [ l ] a^{[l]} a[l] size is n h [ l ] × n w [ l ] × n c [ l ] n_h^{[l]} \times n_w^{[l]} \times n_c^{[l ]} nh[l]×nw[l]×nc[l]

    n h [ l ] n_h^{[l]} nh[l] n h [ l − 1 ] n_h^{[l-1]} nh[l1]两者满足:
    n h [ l ] ( s [ l ] − 1 ) + f 1 [ l ] ⩽ n h [ l − 1 ] + 2 p n_h^{[l]}({s^{[l]}} - 1) + {f_1^{[l]}} \leqslant n_h^{[l - 1]} + 2p nh[l](s[l]1)+f1[l]nh[l1]+2p
    n h [ l ] = ⌊ n h [ l − 1 ] + 2 p − k 1 [ l ] s + 1 ⌋ n_h^{[l]} = \left\lfloor {\frac{{n_h^{[l - 1]} + 2p - {k_1^{[l]}}}}{s} + 1} \right\rfloor nh[l]=snh[l1]+2pk1[l]+1
    符号 ⌊ x ⌋ \left\lfloor {x} \right\rfloor x表示向下取整, n w [ l ] n_w^{[l]} nw[l] n w [ l − 1 ] n_w^{[l-1]} nw[l1]两者关系同上

    [外链图片转存失败(img-S6uM1cnE-1567131135563)(https://www.github.com/callMeBigKing/story_writer_note/raw/master/小书匠/1535388857043.png)]

    Cross-correlation与Convolution

    很多文章或者博客中把Cross-correlation(互相关)和Convolution(卷积)都叫卷积,把互相关叫做翻转的卷积,在我个人的理解里面两者是有区别的,本文将其用两种表达式分开表示,不引入翻转180度。

    Cross-correlation

    对于大小为 h × w h \times w h×w图像 I I I和 大小为 ( k 1 × k 2 ) (k_1 \times k_2) (k1×k2)kernel K K K,定义其Cross-correlation:

    ( I ⊗ K ) i j = ∑ m = 0 k 1 − 1 ∑ n = 0 k 2 I ( i + m , j + n ) K ( m , n ) {(I \otimes K)_{ij}} = \sum\limits_{m = 0}^{{k_1} - 1} {\sum\limits_{n = 0}^{{k_2}} {I(i + m,j + n)} } K(m,n) (IK)ij=m=0k11n=0k2I(i+m,j+n)K(m,n)

    其中

    0 ⩽ i ⩽ h − k 1 + 1 0 \leqslant i \leqslant h - {k_1} + 1 0ihk1+1
    0 ⩽ j ⩽ w − k 2 + 1 0 \leqslant j \leqslant w - {k_2} + 1 0jwk2+1

    注意这里的使用的符号和 i i i的范围,不考虑padding的话Cross-correlation会产生一个较小的矩阵

    Cross-correlation

    Convolution

    首先回顾一下连续函数的卷积和一维数列的卷积分别如下,卷积满足交换律:
    h ( t ) = ∫ − ∞ ∞ f ( τ ) g ( t − τ ) d τ h(t) = \int_{ - \infty }^\infty {f(\tau )g(t - \tau )d\tau } h(t)=f(τ)g(tτ)dτ

    c ( n ) = ∑ i = − ∞ ∞ a ( i ) b ( n − i ) d i c(n) = \sum\limits_{i = - \infty }^\infty {a(i)b(n - i)di} c(n)=i=a(i)b(ni)di

    对于大小为 h × w h \times w h×w图像 I I I和大小为 ( k 1 × k 2 ) (k_1 \times k_2) (k1×k2)kernel K K K,convolution为 :
    ( I ∗ K ) i j = ( K ∗ I ) i j = ∑ m = 0 k 1 − 1 ∑ n = 0 k 2 − 1 I ( i − m , j − n ) k ( m , n ) {(I * K)_{ij}} = {(K * I)_{ij}} = \sum\limits_{m = 0}^{{k_1} - 1} {\sum\limits_{n = 0}^{{k_2} - 1} {I(i - m,j - n)k(m,n)} } (IK)ij=(KI)ij=m=0k11n=0k21I(im,jn)k(m,n)
    KaTeX parse error: Expected 'EOF', got '\eqalign' at position 1: \̲e̲q̲a̲l̲i̲g̲n̲{ & 0 \leqsla…

    注意:这里的Convolution和前面的cross-correlation是不同的:

    1. i , j i,j i,j范围变大了,卷积产生的矩阵size变大了
    2. 这里出现了很多 I ( − x , − y ) I(-x,-y) I(x,y),这些负数索引可以理解成padding
    3. 这里的卷积核会翻转180度
      具体过程如下图所示

    A*B示意图

    [外链图片转存失败(img-fpdG5ZPq-1567131135566)(https://hosbimkimg.oss-cn-beijing.aliyuncs.com/pic/卷积示意图new.svg “卷积示意图”)]

    如果把卷积的padding项扔掉那么就变成下图这样,此时Convolution和Cross-correlation相隔的就是一个180度的翻转,如下图所示

    卷积

    卷积核旋转180度
    参考自卷积核翻转方法
    翻转卷积核有三种方法,具体步骤移步卷积核翻转方法

    1. 围绕卷积核中心旋转180度 (奇数行列好使)

    2. 沿着两条对角线翻转两次

    3. 同时翻转行和列 (偶数行列好使)

    前向传播

    卷积层

    前向传播:计算 z [ l ] z^{[l]} z[l] a [ l ] a^{[l]} a[l]

    输入 a [ l − 1 ] a^{[l-1]} a[l1] size is n h [ l − 1 ] × n w [ l − 1 ] × n c [ l − 1 ] n_h^{[l-1]} \times n_w^{[l-1]} \times n_c^{[l - 1]} nh[l1]×nw[l1]×nc[l1]

    输出 a [ l ] a^{[l]} a[l]

    为了方便后续的反向传播的方便,只讨论 l l l层的参数,把部分上标 [ l ] [l] [l]去掉,同时另 n c [ l ] = n c [ l − 1 ] = 1 n_c^{[l]}=n_c^{[l-1]}=1 nc[l]=nc[l1]=1,前向传播公式如下:

    KaTeX parse error: Expected 'EOF', got '\eqalign' at position 1: \̲e̲q̲a̲l̲i̲g̲n̲{ {z^l}(i,j) …

    虑通道和padding的前向传播


    pooling层

    pooling层进行下采样,maxpool可以表示为:

    a l ( i , j ) = max ⁡ 0 ⩽ m ⩽ k 1 − 1 , 0 ⩽ n ⩽ k 2 − 1 ( a l − 1 ( i * k 1 + m , j * k 2 + n ) ) {a^l}(i,j) = \mathop {\max }\limits_{0 \leqslant m \leqslant {k_1} - 1,0 \leqslant n \leqslant {k_2} - 1} ({a^{l - 1}}(i{\text{*}}{k_1} + m,j{\text{*}}{k_2} + n)) al(i,j)=0mk11,0nk21max(al1(i*k1+m,j*k2+n))

    avepool可以表示为:
    a l ( i , j ) = 1 k 1 × k 2 ∑ m = 0 k 1 − 1 ∑ n = 0 k 2 − 1 a l − 1 ( i * k 1 + m , j * k 2 + n ) {a^l}(i,j) = \frac{1}{{{k_1} \times {k_2}}}\sum\limits_{m = 0}^{{k_1} - 1} {\sum\limits_{n = 0}^{{k_2} - 1} {{a^{l - 1}}(i{\text{*}}{k_1} + m,j{\text{*}}{k_2} + n)} } al(i,j)=k1×k21m=0k11n=0k21al1(i*k1+m,j*k2+n)

    pooling层

    反向传播

    卷积层的反向传播

    1. 已知 ∂ E ∂ z l \frac{{\partial E}}{{\partial {z^l}}} zlE ∂ E ∂ w l \frac{{\partial E}}{{\partial {w^l}}} wlE

    关联关系

    由上图可知 W W W对每一个元素都有贡献,(偷来的图,用的符号不一致),使用链式法则有:

    ∂ E ∂ w m ′ , n ′ l = ∑ i = 0 n h l − 1 ∑ j = 0 n w l − 1 ∂ E ∂ z i , j l ∂ z i , j l ∂ w m ′ , n ′ l \frac{{\partial E}}{{\partial w_{m',n'}^l}} = \sum\limits_{i = 0}^{n_h^l - 1} {\sum\limits_{j = 0}^{n_w^l - 1} {\frac{{\partial E}}{{\partial z_{i,j}^l}}} } \frac{{\partial z_{i,j}^l}}{{\partial w_{m',n'}^l}} wm,nlE=i=0nhl1j=0nwl1zi,jlEwm,nlzi,jl

    ∂ z i , j l ∂ w m ′ , n ′ l = ∂ ( ∑ m = 0 k 1 − 1 ∑ n = 0 k 2 − 1 a i + m , j + n l − 1 × w m , n + b ) ∂ w m ′ , n ′ l = a i + m ′ , j + n ′ l − 1 \frac{{\partial z_{i,j}^l}}{{\partial w_{m',n'}^l}} = \frac{{\partial \left( {\sum\limits_{m = 0}^{{k_1} - 1} {\sum\limits_{n = 0}^{{k_2} - 1} {a_{i + m,j + n}^{l - 1} \times } {w_{m,n}}} + b} \right)}}{{\partial w_{m',n'}^l}} = a_{i + m',j + n'}^{l - 1} wm,nlzi,jl=wm,nl(m=0k11n=0k21ai+m,j+nl1×wm,n+b)=ai+m,j+nl1

    δ i , j l = ∂ E ∂ z i , j l \delta _{i,j}^l = \frac{{\partial E}}{{\partial z_{i,j}^l}} δi,jl=zi,jlE,有:

    KaTeX parse error: Expected 'EOF', got '\eqalign' at position 1: \̲e̲q̲a̲l̲i̲g̲n̲{ \frac{{\par…

    2. 根据 ∂ E ∂ z l \frac{{\partial E}}{{\partial {z^l}}} zlE ∂ E ∂ z l − 1 \frac{{\partial E}}{{\partial {z^{l - 1}}}} zl1E

    两层之间的关系

    上图是偷来的图,把那边的 X l X^l Xl,当成 z l z^l zl理解,与 z i ′ , j ′ l − 1 z_{i',j'}^{l - 1} zi,jl1
    有关的 a i , j l − 1 a_{i,j}^{l - 1} ai,jl1,索引是从 ( i ′ − k 1 + 1 , j ′ − k 2 + 1 ) (i' - {k_1} + 1,j' - {k_2} + 1) (ik1+1,jk2+1) ( i ′ , j ′ ) (i',j') (i,j)(出现负值或者是越界当成是padding),根据链式法则:
    ∂ E ∂ z i ′ , j ′ l − 1 = ∑ m = 0 k 1 − 1 ∑ n = 0 k 2 + 1 ∂ E ∂ z i ′ − m , j ′ − n l ∂ z i ′ − m , j ′ − n l ∂ z i ′ , j ′ l − 1 \frac{{\partial E}}{{\partial z_{i',j'}^{l - 1}}} = \sum\limits_{m = 0}^{{k_1} - 1} {\sum\limits_{n = 0}^{{k_2} + 1} {\frac{{\partial E}}{{\partial z_{i' - m,j' - n}^l}}\frac{{\partial z_{i' - m,j' - n}^l}}{{\partial z_{i',j'}^{l - 1}}}} } zi,jl1E=m=0k11n=0k2+1zim,jnlEzi,jl1zim,jnl

    ∂ z i ′ − m , j ′ − n l ∂ z i ′ , j ′ l − 1 \frac{{\partial z_{i' - m,j' - n}^l}}{{\partial z_{i',j'}^{l - 1}}} zi,jl1zim,jnl展开有:
    ∂ z i ′ − m , j ′ − n l ∂ z i ′ , j ′ l − 1 = ∂ ∑ s = 0 k 1 − 1 ∑ t = 0 k 2 + 1 z i ′ − m + s , j ′ − n + t l − 1 w s , t l ∂ z i ′ , j ′ l − 1 = w m , n l \frac{{\partial z_{i' - m,j' - n}^l}}{{\partial z_{i',j'}^{l - 1}}} = \frac{{\partial \sum\limits_{s = 0}^{{k_1} - 1} {\sum\limits_{t = 0}^{{k_2} + 1} {z_{i' - m + s,j' - n + t}^{l - 1}w_{s,t}^l} } }}{{\partial z_{i',j'}^{l - 1}}} = w_{m,n}^l zi,jl1zim,jnl=zi,jl1s=0k11t=0k2+1zim+s,jn+tl1ws,tl=wm,nl

    从而可以得到:
    KaTeX parse error: Expected 'EOF', got '\eqalign' at position 1: \̲e̲q̲a̲l̲i̲g̲n̲{ \frac{{\par…

    这里的 ∗ * 代表是卷积操作

    pooling层的反向传播

    pooling层的反向传播比较简,没有要训练的参数

    pooling层误差传播

    maxpool,最大的那个为1其他的均为0:

    KaTeX parse error: Expected 'EOF', got '\eqalign' at position 1: \̲e̲q̲a̲l̲i̲g̲n̲{ & \frac{{\p…

    avepool,每个都是

    ∂ E ∂ a i ′ , j ′ l − 1 = 1 k 1 × k 2 \frac{{\partial E}}{{\partial a_{i',j'}^{l - 1}}} = \frac{1}{{{k_1} \times {k_2}}} ai,jl1E=k1×k21

    考虑多个通道

    z c [ l ] [ l ] z_{{c^{[l]}}}^{[l]} zc[l][l]表示 z [ l ] z^{[l]} z[l]的第 c [ l ] c^{[l]} c[l]个channel:

    KaTeX parse error: Expected 'EOF', got '\eqalign' at position 1: \̲e̲q̲a̲l̲i̲g̲n̲{ & z_{{c^{[l…

    其中, W c [ l − 1 ] , c [ l ] [ l ] {W_{{c^{[l - 1]}},{c^{[l]}}}^{[l]}} Wc[l1],c[l][l] f [ l ] × f [ l ] f^{[l]} \times f^{[l]} f[l]×f[l]的卷积核 W c [ l − 1 ] , c [ l ] [ l ] = W [ l ] ( : , : , c [ l − 1 ] , c [ l ] ) {W_{{c^{[l - 1]}},{c^{[l]}}}^{[l]}}={{W^{[l]}}(:,:,{c^{[l - 1]}},{c^{[l]}})} Wc[l1],c[l][l]=W[l](:,:,c[l1],c[l])

    a c [ l ] [ l ] = g ( z c [ l ] [ l ] ) a_{{c^{[l]}}}^{[l]} = g(z_{{c^{[l]}}}^{[l]}) ac[l][l]=g(zc[l][l])

    g ( x ) g(x) g(x)为激活函数


    考虑padding和stride情况下:

    z c [ l ] [ l ] ( i , j ) = ∑ c [ l − 1 ] = 0 n c l − 1 − 1 ( ∑ m = 0 f [ l ] − 1 ∑ n = 0 f [ l ] − 1 a [ l − 1 ] ( i ∗ s + m − p , j ∗ s + n − p , c [ l − 1 ] ) × W [ l ] ( m , n , c [ l − 1 ] , c [ l ] ) ) + b c l [ l ] z_{{c^{[l]}}}^{[l]}(i,j) = \sum\limits_{{c^{[l - 1]}} = 0}^{n_c^{l - 1} - 1} {(\sum\limits_{m = 0}^{{f^{[l]}} - 1} {\sum\limits_{n = 0}^{{f^{[l]}} - 1} {{a^{[l-1]}}(i*s + m - p,j*s + n - p,{c^{[l - 1]}}) \times } {W^{[l]}}(m,n,{c^{[l - 1]}},{c^{[l]}})} )} + b_{{c^l}}^{[l]} zc[l][l](i,j)=c[l1]=0ncl11(m=0f[l]1n=0f[l]1a[l1](is+mp,js+np,c[l1])×W[l](m,n,c[l1],c[l]))+bcl[l]

    a c [ l ] [ l ] = g ( z c [ l ] [ l ] ) a_{{c^{[l]}}}^{[l]} = g(z_{{c^{[l]}}}^{[l]}) ac[l][l]=g(zc[l][l])

    a [ l ] a^{[l]} a[l]索引越界部分表示padding,其值为0

    展开全文
  • 前向传播和反向传播最好的实例就是自己算一一遍。跟着链接一步步走一定能明白的。 所以前向传播并不能带来学习的效果,而反向传播才是学习效果的关键。 关于梯度的问题,反向传播很明显是使用了梯度了。里面的梯度...
  • 卷积前向传播 卷积反向传播 池化前向传播和反向传播
  • 深度学习 神经网络中的前向传播和反向传播算法推导
  • 听了吴恩达老师的课程之后,按照老师的方法画出神经网络中前向传播和反向传播的示意图,如有错误,请交流指正! 其中,caches部分表示“缓存的信息”,以用于后面计算中的调用。 每一步骤所需的数据已用不同颜色的...
  • 对于CNN卷积神经网络的前向传播和反向传播的理解 前向传播示意图: ​ 咋一看这张图,作为初学者可能会**不知所云( ̄ω ̄=)**?但是想要很好的理解前向传播的原理,我们得从这张图细说。 1.首先我们从x,w的参数...
  • 虽然学深度学习有一段时间了,但是对于一些算法的具体实现还是模糊不清,用了很久也不是很了解,最近在看去年LeCunHinton在Nature上发表的deep learning的review,有两张图分别是讲得网络的前向传播和反向传播,...
  • 在神经网络模型中包括前向传播和反向传播那么究竟什么是前向传播,什么是反向传播前向传播:说的通俗一点就是从输入到得到损失值的过程,当然不仅仅是这么简单,中间还经过了一些处理,那么这些处理包括什么呢:1...
  • caffe学习笔记3从3.1开始主要翻译一下caffe的官方文档,写的...前向传播和反向传播是计算神经网络非常重要的部分。 考虑一个简单的逻辑回归分类问题 前向传播:通过网络的输入计算输出结果的过程,在前向传播中,
  • Basic RNN、LSTM的前向传播和反向传播详细解析 Basic RNN、LSTM由于它们独特的架构,被大量应用在自然语言处理序列模型的任务上。通过它们自身特殊的结构,可以记住之前的输入中的部分内容信息,并对之后的输出...
  • 神经网络的前向传播和反向传播

    千次阅读 2020-05-25 00:50:23
    在讨论反向传播之前,我们讨论一下前向传播,即根据输入X来计算输出Y。输入X用矩阵表示,我们看一下如何基于矩阵X来计算网络的输出Y。 我们使用 表示从层的第 个神经元到层的个神经元的链接上的权重。例如,下图给...
  • 在上一节当中,我们讲到了RNN的其中一个特点是参数共享,在这一节当中,我们用具体代码来展示RNN的前向传播。 首先是给出每一个参数具体的值: W指的是相邻时刻隐藏单元间的权重矩阵,U指的是从X(t)计算得到的对应...
  • 前向传播 输入,输出,缓存为 前向传播的过程: 向量化的过程可以写成: 式中,就是初始的输入X。如下图的两层神经网络所示,可以很好的理解。 反向传播 反向传播主要采用数学上的链式法则,反向...
  • 通常,在得到前向传播结果后,会需要定义一个损失函数(例如交叉熵)来刻画当前的预测值真实答案之间的差距。目前Tensor支持7种反向传播的优化器,比较常用的优化方法有3种:tf.train.GradientDescentOptimizer、...
  • 前向传播和反向传播(举例说明)

    万次阅读 多人点赞 2017-09-19 16:25:06
    假设神经网络结构如下图所示:有2个...----前向传播---- 隐含层神经元h1的输入: 代入数据可得: 假设激励函数用logistic函数,计算得隐含层神经元h1的输出: 同样的方法,可以得到隐含层神经元h
  • 1.神经网络的前向传播和反向传播 require'image'; input=torch.rand(1,32,32) itorch.image(input) 随即生产一张照片,1通道,32x32像素的。为了直观像是,导入image包,然后用itorch.image()方法显示生成的...
  • 第一步:进行前向传播计算 先计算输入层到隐含层,再计算隐含层到输出层,这很简单。 第二步:反向传播计算 首先,计算隐含层到输出层的反向传播更新权值 然后,计算隐含层到隐含层的反向传播更新权值 ...
  • 以如下的预测是否是猫的双层神经网络为例进行公式推导: 符号注解: n_x : 输入特征的数量 ...前向传播: 反向传播: 更新参数: 部分偏导我全用导数代替了,不影响最终结果。字有...
  • 本文由@星沉阁冰不语出品,转载请注明作者出处。文章链接:http://blog.csdn.net/xingchenbingbuyu/article/details/53674544微博:http://weibo.com/xingchenbing ...神经网络中的重点核心就是本文的内容——前向

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 95,598
精华内容 38,239
关键字:

前向传播和反向传播