深度学习与 PyTorch
机制原理 基础 重要度 4/5 面试就绪 理解阶段 约 60 分钟

两层网络的反向传播:手算、矩阵与代码

从预测减真实、导数的方向和梯度下降的减号出发,手算两层网络的全部梯度、参数更新与新损失,再推到批量矩阵形式。

发布于 2026-09-09 · 更新于 2026-09-09

本文目录

    学习目标

    先不背反向传播公式。我们从“预测错了,应该改哪个参数”开始。

    这篇是 P0 基础必修,按两遍读:

    • 第一遍: 从一个参数开始,弄懂方向,再完成两层网络的手算。
    • 第二遍: 看批量矩阵形式,运行代码,检查自己的梯度是否正确。

    读到每个“停一下”时,先用自己的话回答,再往下读。暂时不需要理解 Adam 或分布式训练。

    问题与基线

    模型没有直接“知道正确参数”的能力。训练数据提供输入和答案,当前参数给出预测,损失函数把预测质量转成一个可优化的标量。求导回答的是当前位置附近的敏感度,不会直接交出一组最优参数。

    例如输入为 2、答案为 3,模型预测 2:知道“偏低”还不足以修改所有权重,因为某个权重增大可能提高预测,也可能降低预测。我们需要把参数对预测的影响算进去。

    本文数值全部是教学算例,不是模型训练性能或个人项目结果。一个样本上的损失下降,只验证本次更新,不能证明模型能泛化。

    输入与输出

    第 1 步:先让模型算出一个答案

    我们只有一个训练样本:输入是 2,正确答案是 3。

    用 x=2x=2 表示输入,y=3y=3 表示正确答案。模型先只用一个权重:

    y^=wx.\hat y=wx.

    这里 ww 是要学习的参数,y^\hat y 读作“y hat”,表示模型预测。先设 w=1w=1:

    y^=1×2=2.\hat y=1\times2=2.

    模型预测了 2,但我们希望它预测 3。

    输入和答案是给定数据,不靠训练修改。要改的是权重 ww;预测值会随着权重重新计算。后面加入的偏置 bb 也是参数,θ\theta 则用来统称全部参数。

    停一下:训练修改的是答案、预测值,还是产生预测的参数? 修改参数;预测是重新计算得到的结果。

    核心机制

    第 2 步:把“预测错了多少”算出来

    约定误差为“预测减真实”:

    e=y^−y.e=\hat y-y.

    代入刚才的预测:e=2−3=−1e=2-3=-1。

    负号表示预测偏低,不表示损失应该变得更负。

    误差为正表示预测偏高,为负表示预测偏低。直接最小化有符号误差会鼓励预测无限变小,并不等于预测准确。

    这里使用平方损失:

    L=12(y^−y)2.L=\frac12(\hat y-y)^2.

    当前损失为 L=(−1)2/2=0.5L=(-1)^2/2=0.5。如果预测正好等于 3,损失就是 0。

    所以我们最小化损失:损失小,表示预测接近答案。

    平方使两种减法顺序等价:(y^−y)2=(y−y^)2(\hat y-y)^2=(y-\hat y)^2。为了少记一个符号,本文统一写“预测减真实”。交叉熵等损失不是简单的两个量相减,不能把这个等价结论随意推广。

    最小化不是优化的唯一形式。若定义得分 S=−LS=-L,最大化 SS 与最小化 LL 是同一个目标;最大化原来的平方损失则是在鼓励犯错。

    第 3 步:为什么内层求导要乘 −1

    如果把内层写成 u=y−y^u=y-\hat y,先不用求导规则,直接看数字:

    • 预测是 2 时,u=3−2=1u=3-2=1。
    • 预测变为 2.1 时,u=3−2.1=0.9u=3-2.1=0.9。

    预测增加 0.1,差值减少 0.1。 变化率就是 −0.1/0.1=−1-0.1/0.1=-1。

    因此 ∂u/∂y^=−1\partial u/\partial\hat y=-1。外层是 L=u2/2L=u^2/2,对 uu 求导得到 uu。预测先改变差值,差值再改变损失,两段变化率相乘:

    ∂L∂y^=∂L∂u∂u∂y^=(y−y^)(−1)=y^−y.\frac{\partial L}{\partial\hat y} =\frac{\partial L}{\partial u}\frac{\partial u}{\partial\hat y} =(y-\hat y)(-1)=\hat y-y.

    负号来自内层运算,不是为了让梯度下降“凑对方向”。写成另一种减法顺序,正确使用链式法则,仍会得到同一个梯度。

    第 4 步:导数到底在告诉我们什么

    导数回答:当前位置,把参数增大一点,损失会怎么变?

    一个参数时,导数的定义是:

    L′(w)=lim⁡h→0L(w+h)−L(w)h.L'(w)=\lim_{h\to0}\frac{L(w+h)-L(w)}{h}.

    它描述在当前位置,参数增大一点时损失的变化率。多个参数时,固定其他参数,只对其中一个求导,得到偏导数。将偏导数组成向量就是梯度:

    ∇θL=[∂L/∂w∂L/∂b].\nabla_\theta L= \begin{bmatrix}\partial L/\partial w\\\partial L/\partial b\end{bmatrix}.

    “导数为负”指单个数的符号;“负梯度”是把梯度向量整体取反。例如梯度为 (−2,−1)(-2,-1),负梯度就是 (2,1)(2,1),并不是所有分量都为负。

    第 5 步:为什么优化要减去梯度

    把横轴看成参数,纵轴看成损失。你能控制左右移动,希望得到的是高度下降。导数为正表示往右上坡,应向左走;导数为负表示往右下坡,应向右走。参数增大还是减小不是目标,损失降低才是目标。

    情况一:导数为正。 往右走会上坡,那就往左走,也就是减小参数。

    情况二:导数为负。 往右走就能下坡,那就往右走,也就是增大参数。

    这两种情况都可以用“减去导数”实现。导数为零时,标准梯度下降这一步不动,但不能据此认定已达到最优。

    记方向:下降的是损失,不一定是参数。减去负数,参数反而增大。

    数学上,对小变化有 ΔL≈gΔw\Delta L\approx g\Delta w。取 Δw=−ηg\Delta w=-\eta g,便有 ΔL≈−ηg2\Delta L\approx-\eta g^2。非零梯度时这个一阶近似为负,因此选择:

    θnew=θ−η∇θL.\theta_{\mathrm{new}}=\theta-\eta\nabla_\theta L.

    多参数时,损失的一阶变化为 ∇L⊤Δθ\nabla L^\top\Delta\theta。在欧氏范数下比较等长的小步,负梯度是局部最陡下降方向;这不是“直指全局最优点”的承诺,也不保证任意学习率下损失都下降。Adam 和动量法会利用历史信息,其实际步向不必与当前负梯度共线。

    逐步推导

    第 6 步:把两段影响接起来

    回到 y^=wx\hat y=wx,仍然取 x=2,y=3,w=1x=2,y=3,w=1。前向预测为 2,损失为 0.5。

    先问:预测提高一点,损失会怎样?

    平方损失对预测的导数是 y^−y=−1\hat y-y=-1。因此,提高预测会在当前位置附近降低损失。

    再问:权重提高一点,预测会怎样?

    因为预测为 wxwx,对权重求导得到 x=2x=2。因此,权重的小变化会让预测产生两倍的变化。

    最后把两段相乘,得到权重对损失的影响:

    ∂L∂w=∂L∂y^⏟y^−y=−1∂y^∂w⏟x=2=−2.\frac{\partial L}{\partial w} =\underbrace{\frac{\partial L}{\partial\hat y}}_{\hat y-y=-1} \underbrace{\frac{\partial\hat y}{\partial w}}_{x=2} =-2.

    第 7 步:实际修改参数,再验证一次

    取学习率 η=0.1\eta=0.1。它只负责控制步子大小。

    wnew=1−0.1×(−2)=1.2.w_{\mathrm{new}}=1-0.1\times(-2)=1.2.

    用新权重重新前向:

    y^new=1.2×2=2.4.\hat y_{\mathrm{new}}=1.2\times2=2.4. Lnew=12(2.4−3)2=0.18.L_{\mathrm{new}}=\frac12(2.4-3)^2=0.18.

    损失从 0.5 降到 0.18。这才算完成一次参数更新的验证。

    停一下:为什么不能只根据“预测偏低”直接增大权重? 因为还要看权重增大究竟会提高还是降低预测。

    反例:若 x=−2,w=−1,y=3x=-2,w=-1,y=3,预测同样是 2,但权重梯度为 (−1)(−2)=2(-1)(-2)=2,更新需要减小权重。不能由“预测偏低”直接得出“所有参数都增大”。

    第 8 步:网络多一层,链式法则就多接一段

    使用一个隐藏神经元,两层都有可训练权重与偏置:

    第一层先做乘法与加法:z=w1x+b1z=w_1x+b_1。

    然后过 ReLU:h=max⁡(0,z)h=\max(0,z),也就是负数变成零、正数原样保留。

    第二层拿 hh 当输入:y^=w2h+b2\hat y=w_2h+b_2。

    最后仍用平方损失:L=(y^−y)2/2L=(\hat y-y)^2/2。

    每层都不用知道整个网络怎么求导,只要把收到的梯度继续乘上自己的局部导数。

    反向从 ∂L/∂L=1\partial L/\partial L=1 开始。为避免写很长的分式,用 gvg_v 表示损失对中间量 vv 的梯度。逐层计算:

    gy^=y^−y,∂L∂w2=gy^h,∂L∂b2=gy^.g_{\hat y}=\hat y-y, \quad \frac{\partial L}{\partial w_2}=g_{\hat y}h, \quad \frac{\partial L}{\partial b_2}=g_{\hat y}. gh=gy^w2,gz=gh 1z>0.g_h=g_{\hat y}w_2,\qquad g_z=g_h\,\mathbf{1}_{z>0}. ∂L∂w1=gzx,∂L∂b1=gz.\frac{\partial L}{\partial w_1}=g_zx, \qquad \frac{\partial L}{\partial b_1}=g_z.

    ReLU 在正区间导数是 1,负区间是 0,在零点不可导;本文实现选择零点导数为 0,并让数值检查远离零点。

    第 9 步:为什么只需一次反向传播

    不是“两层网络做两次反向”,而是“一次反向里,依次算两层”。

    先算 gy^g_{\hat y},用它得到输出层梯度和 ghg_h;再复用 ghg_h 得到前一层梯度。不需要为四个参数各从损失重新走一遍。

    D2L 计算图:沿依赖关系计算局部导数,共享路径的梯度可以复用。

    图来自 D2L 计算图,作者 Aston Zhang、Zachary C. Lipton、Mu Li、Alexander J. Smola,许可 CC BY-SA 4.0。图用于说明一般计算依赖,不是下文四参数算例的逐节点对应图。

    共享的中间梯度要复用,多条路径的贡献要相加。例如 a=wx,c=wx,y^=a+ca=wx,c=wx,\hat y=a+c,同一个 ww 有两条路径,∂L/∂w=gy^x+gy^x\partial L/\partial w=g_{\hat y}x+g_{\hat y}x。若只算其中一条就会少一半;复用不是丢弃分支。

    Worked Example

    固定输入 x=2x=2、目标 y=3y=3,初始参数 w1=1,b1=0,w2=1,b2=0w_1=1,b_1=0,w_2=1,b_2=0,学习率取 0.05。下面四个梯度必须使用同一组旧参数计算。

    手算 1:先完成前向,不求导

    第一层算出 2:

    z=1×2+0=2.z=1\times2+0=2.

    2 是正数,ReLU 不改变它,所以隐藏层输出 h=2h=2。

    第二层仍然算出 2:

    y^=1×2+0=2.\hat y=1\times2+0=2.

    对照目标 3,计算损失:

    L=12(2−3)2=0.5.L=\frac12(2-3)^2=0.5.

    到这里,前向结束。保存 x=2,z=2,h=2x=2,z=2,h=2 和误差 −1,后面求梯度会用到。

    手算 2:从损失回到预测

    平方损失对预测的导数是预测减真实:

    gy^=2−3=−1.g_{\hat y}=2-3=-1.

    这是输出层收到的上游梯度。 它告诉输出层:把预测提高一点,损失会下降。

    手算 3:求输出层两个参数的梯度

    输出层公式是 y^=w2h+b2\hat y=w_2h+b_2。

    先看权重 w2w_2。它每增加一点,预测会增加 h=2h=2 倍,所以:

    ∂L∂w2=(−1)×2=−2.\frac{\partial L}{\partial w_2}=(-1)\times2=-2.

    再看偏置 b2b_2。它增加多少,预测就增加多少,局部导数是 1:

    ∂L∂b2=(−1)×1=−1.\frac{\partial L}{\partial b_2}=(-1)\times1=-1.

    输出层的参数梯度已经算出,但现在先不更新。 隐藏层还需要使用旧的输出层权重。

    手算 4:把梯度传回隐藏层

    隐藏层输出 hh 对预测的影响由 w2=1w_2=1 决定:

    gh=gy^w2=(−1)×1=−1.g_h=g_{\hat y}w_2=(-1)\times1=-1.

    再往回穿过 ReLU。因为前向的 z=2>0z=2>0,它的局部导数是 1:

    gz=gh×1=−1.g_z=g_h\times1=-1.

    这里没有新参数需要更新,只是在把“损失对后面结果的影响”换算成“损失对前面结果的影响”。

    手算 5:求第一层两个参数的梯度

    第一层公式是 z=w1x+b1z=w_1x+b_1,收到的上游梯度为 gz=−1g_z=-1。

    权重的局部导数是输入 x=2x=2:

    ∂L∂w1=(−1)×2=−2.\frac{\partial L}{\partial w_1}=(-1)\times2=-2.

    偏置的局部导数是 1:

    ∂L∂b1=(−1)×1=−1.\frac{\partial L}{\partial b_1}=(-1)\times1=-1.

    到这里,一次反向传播结束。四个参数都有了自己的梯度。

    手算 6:统一更新四个参数

    学习率是 0.05,每个参数都执行“旧值减去学习率乘梯度”:

    w1′=1−0.05×(−2)=1.1,b1′=0−0.05×(−1)=0.05,w2′=1−0.05×(−2)=1.1,b2′=0−0.05×(−1)=0.05.\begin{aligned} w_1' &= 1-0.05\times(-2)=1.1,\\ b_1' &= 0-0.05\times(-1)=0.05,\\ w_2' &= 1-0.05\times(-2)=1.1,\\ b_2' &= 0-0.05\times(-1)=0.05. \end{aligned}

    四个梯度来自同一次前向、同一组旧参数。这是一次同步的梯度下降更新,不是逐层改变参数后再接着求导。

    手算 7:重新前向,检查是否真的改善

    第一层的新输出:

    z′=1.1×2+0.05=2.25.z'=1.1\times2+0.05=2.25.

    它仍为正数,所以 h′=2.25h'=2.25。第二层的新预测:

    y^′=1.1×2.25+0.05=2.525.\hat y'=1.1\times2.25+0.05=2.525.

    最后,新损失为:

    L′=12(2.525−3)2=0.1128125.L'=\frac12(2.525-3)^2=0.1128125.

    这一轮的结果:预测从 2 接近到 2.525,损失从 0.5 降到约 0.113。

    第一步确实降低了损失。下一步必须重算梯度:例如输出层权重梯度变成 (−0.475)×2.25=−1.06875(-0.475)\times2.25=-1.06875,不是继续沿用旧的 −2。随着位置变化,局部导数和上游梯度都可能改变。

    第二遍再读:从标量扩展到批量矩阵

    第一次读到这里可以暂停。 先试着独立复算上面七步,再进入矩阵形式;矩阵只是把多个样本、多个神经元的同类运算一起写出来。

    设 batch 为 BB,输入维度 dd,隐藏宽度 HH,输出维度 CC;样本按行排列:

    Z=XW1+b1,A=ReLU⁡(Z),P=AW2+b2.Z=XW_1+b_1,\quad A=\operatorname{ReLU}(Z),\quad P=AW_2+b_2.

    先核对每个量的形状:

    • 输入 XX:B×dB\times d,每行一个样本。
    • 第一层权重 W1W_1:d×Hd\times H。
    • 隐藏层 Z,AZ,A:B×HB\times H。
    • 第二层权重 W2W_2:H×CH\times C。
    • 预测 PP 和目标 YY:B×CB\times C。

    偏置沿 batch 广播。先规定损失按样本平均、对输出维求和,后面才知道要除以哪个数:

    L=12B∑i=1B∑j=1C(Pij−Yij)2,GP=P−YB.L=\frac1{2B}\sum_{i=1}^B\sum_{j=1}^C(P_{ij}-Y_{ij})^2, \qquad G_P=\frac{P-Y}{B}. ∇W2L=A⊤GP,∇b2L=∑i=1B(GP)i,:,GA=GPW2⊤.\nabla_{W_2}L=A^\top G_P,\quad \nabla_{b_2}L=\sum_{i=1}^B(G_P)_{i,:},\quad G_A=G_PW_2^\top. GZ=GA⊙1Z>0,∇W1L=X⊤GZ,∇b1L=∑i=1B(GZ)i,:.G_Z=G_A\odot\mathbf1_{Z>0},\quad \nabla_{W_1}L=X^\top G_Z,\quad \nabla_{b_1}L=\sum_{i=1}^B(G_Z)_{i,:}.

    为什么权重梯度有转置?

    单个权重的梯度是所有样本中“该输入乘对应输出梯度”的和:∂L/∂(W1)jk=∑iXij(GZ)ik\partial L/\partial(W_1)_{jk}=\sum_i X_{ij}(G_Z)_{ik},写成矩阵就是 X⊤GZX^\top G_Z。其形状 d×Hd\times H 必须与 W1W_1 相同。

    为什么偏置梯度求和,而不是再取一次平均?

    偏置被所有样本共享,反向时要把贡献相加,所以沿 batch 求和。GPG_P 已经除过 BB,后面不能再平均一次。若改成对全部 BCBC 个元素平均,起点应除以 BCBC;先说清 reduction,才谈梯度大小。

    分类网络通常把 PP 换成 logits,再接 Softmax 和交叉熵。此时损失对 logits 的梯度可化简为 (p−y)/B(p-y)/B,之后仍复用相同的线性层反向公式;它不是交叉熵对概率 pp 本身的导数。相关推导接 概率、损失与泛化。

    复杂度与资源

    两层稠密网络前向主要乘法量为 O(BdH+BHC)O(BdH+BHC),反向的主要矩阵乘法与之同阶,还要计算参数梯度。不要把“反向同阶”说成在任何硬件上固定耗时几倍。

    反向需要前向的输入、激活或其他算子所需中间量,因此训练除了参数还需要保存梯度与中间结果。激活检查点用重算换保存空间,会增加部分前向计算;这不等于为每个参数单独反向一次。实际还要考虑优化器状态和实现临时缓冲区。

    工程实现

    下面只依赖 Python 标准库,实现四参数网络、手写梯度、一次同步更新和中心有限差分检查。检查分别覆盖 ReLU 正区间、负区间及负输入;没有使用自动求导。

    先完成七步手算,再运行代码,最后遮住 backward 自己重写。

    from math import isclose
    
    
    def forward(params, x, target):
        w1, b1, w2, b2 = params
        z = w1 * x + b1
        h = max(0.0, z)
        prediction = w2 * h + b2
        error = prediction - target
        loss = 0.5 * error * error
        return loss, (x, z, h, error)
    
    
    def backward(params, cache):
        _, _, w2, _ = params
        x, z, h, error = cache
        d_prediction = error
        d_w2 = d_prediction * h
        d_b2 = d_prediction
        d_h = d_prediction * w2
        d_z = d_h * (1.0 if z > 0.0 else 0.0)
        return (d_z * x, d_z, d_w2, d_b2)
    
    
    def finite_difference(params, x, target, eps=1e-6):
        result = []
        for i in range(len(params)):
            plus, minus = list(params), list(params)
            plus[i] += eps
            minus[i] -= eps
            result.append(
                (forward(plus, x, target)[0] - forward(minus, x, target)[0])
                / (2.0 * eps)
            )
        return result
    
    
    params = (1.0, 0.0, 1.0, 0.0)
    loss, cache = forward(params, 2.0, 3.0)
    grads = backward(params, cache)
    assert grads == (-2.0, -1.0, -2.0, -1.0)
    updated = tuple(p - 0.05 * g for p, g in zip(params, grads))
    new_loss, _ = forward(updated, 2.0, 3.0)
    assert isclose(new_loss, 0.1128125, abs_tol=1e-12)
    assert new_loss < loss
    
    cases = [
        (params, 2.0, 3.0),
        ((-1.0, 0.0, 1.0, 0.0), 2.0, 3.0),
        ((-1.0, 0.0, 0.7, 0.1), -2.0, 3.0),
    ]
    for values, x, target in cases:
        _, cache = forward(values, x, target)
        analytic = backward(values, cache)
        numeric = finite_difference(values, x, target)
        for a, n in zip(analytic, numeric):
            assert isclose(a, n, rel_tol=1e-5, abs_tol=1e-7), (a, n)
    
    # 步长太大,即使方向是负梯度,也可能增加损失。
    overshot = tuple(p - 1.0 * g for p, g in zip(params, grads))
    assert forward(overshot, 2.0, 3.0)[0] > loss
    print("PASS: hand-derived gradients, update, and finite differences")

    有限差分比较 [L(w+ϵ)−L(w−ϵ)]/(2ϵ)[L(w+\epsilon)-L(w-\epsilon)]/(2\epsilon) 与解析梯度。它适合检查小算例,不能用于大模型每轮训练:每个参数需要额外扰动和求值。ϵ\epsilon 太小受浮点消减影响,太大则不够局部;ReLU 拐点附近两侧属于不同分支,也不能据此简单判定反向实现错误。

    PyTorch 中常见训练顺序是 optimizer.zero_grad()、前向与 loss、loss.backward()、optimizer.step()。backward() 计算并累加梯度,step() 才修改参数。下一轮重新前向构建相应计算图;不能误以为调用一次 backward 后,就能用旧梯度一直正确更新。梯度累积和训练模式细节见 训练循环与排错。

    边界与失败方式

    • 反向算到一层就立即更新这一层。 这会让更早层使用新权重传播梯度,不再是原来那次前向对应的导数。应先得到本步所需梯度,再更新参数。
    • 把多层计算叫作多次反向传播。 通常一次反向遍历中逐层计算所有所需梯度。梯度累积可以多次前向和反向后才更新,必须区分 microbatch 与 optimizer step。
    • 认为一次更新必须让所有样本都更好。 batch 梯度来自当前聚合目标,样本之间可能冲突;随机小批次下降方向也不保证全数据损失单调下降。
    • 把梯度为零当作达到全局最优。 还可能是鞍点、局部极值、ReLU 关闭或计算路径断开。对本算例,隐藏层关闭时输出偏置仍可能获得梯度。
    • 把链式法则写成只有一个乘积。 多维输出要做求和或向量—雅可比积,共享参数要累计所有路径。如果损失还有直接依赖参数的正则项,其梯度也要加入。

    面试输出

    90 秒口述: 神经网络训练把预测误差通过计算图转成参数梯度。先前向计算预测和标量损失,并保留反向所需中间结果。反向从损失出发,各节点将上游梯度乘局部导数;有分支就累计贡献,从而一次反向得到所有参与计算的可训练参数梯度。它复用中间梯度,不是每个参数单独求一次完整导数。标准梯度下降再减去学习率乘梯度,因为负梯度是局部下降方向,但步长过大不保证实际损失下降。比如平方损失接线性模型,权重梯度是预测误差乘输入。反向计算与参数更新是两个动作,通常先算完梯度,再由优化器更新。

    应能写出的证据: 完整复算上面的四参数网络,写对 ReLU 分支;解释偏置梯度求和、batch 平均只出现一次;使用有限差分验证,而不是只凭 loss 偶尔下降判断梯度正确。

    主动回忆

    先遮住答案,判断方向,再代数计算。答错时回到对应推导,不另背一套口诀。

    1. 为什么平方误差两种减法顺序都行? 平方后相等,链式求导也相同;写成真实减预测必须乘内层导数 −1。
    2. 导数为 −2 时,负梯度是什么方向? 单参数下为正方向,参数增大;“负梯度”不是“数值为负”。
    3. 预测偏低,权重一定增大吗? 不一定。在线性模型中权重梯度为误差乘输入,输入为负时更新方向会反过来。
    4. 两层网络需要两次 backward 吗? 通常不需要,一次 backward 包含两层的局部反向计算,并复用上游梯度。
    5. 为什么不能更新输出层以后再求隐藏层梯度? 隐藏层梯度需要原计算图中的旧输出层权重,否则链式导数不再对应同一次前向。
    6. 共享参数出现两次怎么办? 两条路径的导数贡献相加。若 y^=wx+wx\hat y=wx+wx,梯度是 2x(y^−y)2x(\hat y-y)。
    7. 为什么矩阵公式里的偏置梯度是求和? 同一个偏置被广播到每个样本,各样本对它的贡献必须累计;平均因子已由损失定义决定。
    8. 标准梯度下降走负梯度,为什么 loss 还能升? 负梯度描述局部一阶方向,有限步长太大可能越过低处;小批次和全量目标也可能不同。

    参考资料

    输入关键词,查找全部技术文章。

      搜索范围:正文、标题、分类和标签