AI Hero Club

Transformer 实战 · 第 6 章

已自行标记完成0 / 12

仅保存在当前浏览器;完成标记不代表通过项目验收。

本章提纲 9 个小节
全课目录 12 章
完整课程计划 ↗
Transformer 实战 / 课程计划 ↗

CHAPTER 06 / 12建议学习 120 分钟

反向传播与优化

一个损失标量怎样沿整个计算图产生梯度,又怎样变成一次 AdamW 更新?

本章要解决的 4 个问题
  • 从计算图推导 softmax 交叉熵与 head 权重梯度
  • 逐步推导 LayerNorm 的输入与仿射参数梯度
  • 用不变量和中心有限差分定位反传错误
  • 解释 AdamW 偏置校正、解耦衰减与裁剪的不同地位
课程项目 ZIP ↓

目标、边界与计算图

本章回答“损失怎样告诉每个参数该往哪里动”。前提是第五章的 pre-LN 块、矩阵乘法、一元导数和偏导含义;本章把多元链式法则展开到 head 与 LayerNorm,并用有限差分独立核验。结束时你应能区分损失的精确梯度、检查梯度的数值近似,以及优化器选择的更新规则。后两者不是同一个对象,也不能把损失下降一次当作全局收敛证明。

计算图是有向无环图:节点为中间实数或张量,边表示下游计算使用了上游值。参数是需要求导的输入,词元编号是离散数据,不对编号本身求导。标量损失记为 ℓ\ell,节点 aa 的上游梯度记为 aˉ=∂ℓ/∂a\bar a=\partial\ell/\partial a,它描述改变该节点对最终损失的一阶影响。一个节点若被两条路径使用,两条链式贡献必须相加,而不是保留最后到达的一条。

例如 u=ax,v=u+x,ℓ=v2/2u=ax,v=u+x,\ell=v^2/2,其中 aa 为参数、xx 为给定输入。先有 vˉ=v\bar v=v,再有 uˉ=vˉ\bar u=\bar v;输入梯度沿直接加法支路给出 vˉ\bar v,沿乘法支路给出 auˉa\bar u,总计 (1+a)v(1+a)v;参数梯度为 xuˉ=xvx\bar u=xv。这正是残差结构的反传。自动微分保存必要中间值并倒序执行这种局部规则,不是重新拟合一个“梯度模型”。

从 softmax 交叉熵推到输出矩阵

取一个有效预测位置。隐藏行向量为 h∈Rdh\in\mathbb R^d,输出权重为 W∈Rd×VW\in\mathbb R^{d\times V},其中 VV 是词表大小;logits 行向量 s=hWs=hW。真实下一个词元编号为 y∈{0,…,V−1}y\in\{0,\ldots,V-1\}。定义 Z=∑jesjZ=\sum_j e^{s_j}、概率 pj=esj/Zp_j=e^{s_j}/Z、负对数似然 ℓ=−log⁡py\ell=-\log p_y,本章对数均为自然对数,损失单位为 nat。

ℓ=−sy+log⁡∑jesj,∂ℓ∂si=−1i=y+esi∑jesj=pi−1i=y.\ell=-s_y+\log\sum_j e^{s_j},\qquad \frac{\partial\ell}{\partial s_i}=-\mathbf1_{i=y}+\frac{e^{s_i}}{\sum_j e^{s_j}}=p_i-\mathbf1_{i=y}.
精确推导:对第一项求导得目标指示项,对 log 求导再乘指数导数得到概率项。

这里 1i=y\mathbf1_{i=y} 在编号相等时为一,否则为零。若从概率导数出发,商法则给 ∂pj/∂si=pj(1i=j−pi)\partial p_j/\partial s_i=p_j(\mathbf1_{i=j}-p_i);再将 −1/py-1/p_y 乘到 j=yj=y 的一行,也得到同一结果。这是第二条独立推导。求和检查为 ∑isˉi=∑ipi−1=0\sum_i\bar s_i=\sum_i p_i-1=0,对应全部 logits 加同一常数不改变概率与损失。

数值实现不能直接对大 logits 求指数。令 m=max⁡jsjm=\max_j s_j,将损失等价写成 −sy+m+log⁡∑jesj−m-s_y+m+\log\sum_j e^{s_j-m}。这是代数恒等变换,指数都不超过一,减少上溢风险;不是把概率近似掉。手推梯度仍可从原恒等式计算,不需要把“最大值位置”当作真实模型的额外离散决策。有限浮点仍有舍入,极端差值也可能下溢,因此代码对照使用温和输入。

∂ℓ∂Wij=hisˉj,hˉi=∑jsˉjWij,∇Wℓ=hTsˉ.\frac{\partial\ell}{\partial W_{ij}}=h_i\bar s_j,\qquad \bar h_i=\sum_j\bar s_jW_{ij},\qquad \nabla_W\ell=h^{\mathsf T}\bar s.
由 s_j=Σ_i h_i W_ij 逐项求偏导;外积形状为 [d,V],隐藏梯度形状为 [d]。

对多个有效位置,先逐位置产生同样形状的权重梯度,再求和或按有效词元数平均;第八章将严格处理 padding。这里先用一个位置,因此不额外除批量或词表大小。若框架 head.weight 存储形状为 [V,d][V,d],它的梯度是上式的转置。形状对上只代表乘法合法,目标是否右移、平均分母是否正确还需要另查。

算例一:两类 head 的完整梯度与一次下降

取 h=(1,2)h=(1,2),WW 的两行分别为 (0.2,−0.1)(0.2,-0.1) 与 (0,0.3)(0,0.3),目标为零号。logits 是 (0.2,0.5)(0.2,0.5);减去最大值后指数为 (e−0.3,1)(e^{-0.3},1),归一化概率约 (0.4255575,0.5744425)(0.4255575,0.5744425)。损失为 log⁡(1+e0.3)≈0.8543552\log(1+e^{0.3})\approx0.8543552,所以 logits 梯度为 (−0.5744425,0.5744425)(-0.5744425,0.5744425)。

第一行权重梯度为隐藏第一坐标一乘该梯度,第二行为二乘,得到两行 (−0.5744425,0.5744425)(-0.5744425,0.5744425)、(−1.1488850,1.1488850)(-1.1488850,1.1488850)。隐藏梯度第一项为负零点五七四四乘零点二加正零点五七四四乘负零点一,约负零点一七二三三;第二项为正零点五七四四乘零点三,约正零点一七二三三。若误把目标写成一号,两类梯度会换成另一组,程序仍能下降,却在训练错误任务。

用学习率 η=0.1\eta=0.1 的一次普通梯度下降,按 Wnew=W−η∇WℓW_{new}=W-\eta\nabla_W\ell 更新。新权重两行约为 (0.257444,−0.157444)(0.257444,-0.157444) 和 (0.114889,0.185111)(0.114889,0.185111);新 logits 约为 (0.487221,0.212779)(0.487221,0.212779),目标类从落后变成领先,损失约零点五六五三。这个下降是该数值输入的观察,不是任意学习率都有效的定理;过大学习率仍可能破坏更复杂的网络。

独立运行独立标准库:解析外积梯度、中心差分和实际损失变化三者对照。
import math
h=[1.0,2.0]; W=[[0.2,-0.1],[0.0,0.3]]; target=0
def loss(w):
    s=[sum(h[i]*w[i][j] for i in range(2)) for j in range(2)]
    top=max(s)
    return -s[target]+top+math.log(sum(math.exp(v-top) for v in s))
s=[sum(h[i]*W[i][j] for i in range(2)) for j in range(2)]
e=[math.exp(v-max(s)) for v in s]; probs=[v/sum(e) for v in e]
gs=[p-(j==target) for j,p in enumerate(probs)]
gw=[[x*g for g in gs] for x in h]
step=1e-5; errors=[]
for i in range(2):
    for j in range(2):
        plus=[r[:] for r in W]; minus=[r[:] for r in W]
        plus[i][j]+=step; minus[i][j]-=step
        numerical=(loss(plus)-loss(minus))/(2*step)
        errors.append(abs(numerical-gw[i][j]))
new=[[w-0.1*g for w,g in zip(row,grad)] for row,grad in zip(W,gw)]
assert max(errors)<1e-8
assert abs(sum(gs))<1e-12
assert loss(new)<loss(W)
print('loss',loss(W),'after',loss(new),'max gradient error',max(errors))

LayerNorm 的反传为何不能冻结均值和方差

沿第五章记号,输入长度为 dd,均值 μ\mu,中心化坐标 ci=xi−μc_i=x_i-\mu,人口方差 v=∑ici2/dv=\sum_i c_i^2/d,r=v+εr=\sqrt{v+\varepsilon},zi=ci/rz_i=c_i/r,输出 oi=γizi+βio_i=\gamma_i z_i+\beta_i。稳定常数保持 10−510^{-5}。现在给定上游梯度 ai=∂ℓ/∂oia_i=\partial\ell/\partial o_i,定义 ui=aiγiu_i=a_i\gamma_i,则 zˉi=ui\bar z_i=u_i;仿射参数梯度分别为 aizia_i z_i 与 aia_i。

为展开输入梯度,令 δxi\delta x_i 为任意微小扰动。均值变化为 δμ=∑iδxi/d\delta\mu=\sum_i\delta x_i/d,故 δci=δxi−δμ\delta c_i=\delta x_i-\delta\mu。对平方求导得 δv=2∑iciδci/d\delta v=2\sum_i c_i\delta c_i/d。由于中心化坐标和为零,乘 δμ\delta\mu 的一项消去,剩下 2∑iciδxi/d2\sum_i c_i\delta x_i/d。这些变化都是输入依赖,不可在反传时设为零。

δr=δv2r,δzi=δxi−δμr−ciδv2r3.\delta r=\frac{\delta v}{2r},\qquad \delta z_i=\frac{\delta x_i-\delta\mu}{r}-\frac{c_i\delta v}{2r^3}.
先对平方根求导,再对 c_i/r 用乘积与倒数求导;eps 是固定常数。

损失一阶变化为 δℓ=∑iuiδzi\delta\ell=\sum_i u_i\delta z_i。代入上式后,第一项给每个 δxi\delta x_i 系数 ui/ru_i/r;均值项给所有坐标共同系数 −u‾/r-\overline u/r;方差项给第 ii 坐标系数 −ciuc‾/r3-c_i\overline{uc}/r^3。横线表示沿特征轴的算术平均,不表示跨批量平均。于是读出完整输入梯度:

xˉi=ui−u‾r−ciuc‾r3=ui−u‾−ziuz‾r.\bar x_i=\frac{u_i-\overline u}{r}-\frac{c_i\overline{uc}}{r^3}=\frac{u_i-\overline u-z_i\overline{uz}}{r}.
精确 LayerNorm 输入梯度;第二式用 c=rz 代换得到,保留 eps。

对所有坐标求和,第一部分为零,第二部分含 ∑ici=0\sum_i c_i=0,所以输入梯度和为零。这是平移不变性的反向检查。另一个常被误用的检查是“梯度与标准化向量正交”:稳定常数非零时,归一化并非精确尺度不变,因此该内积一般不是严格零。不能为通过一个只适用于 eps=0 的检查而删掉稳定常数。多位置共享的 gamma、beta 梯度需沿批量和时间求和,不能只留下最后一个位置。

算例二:漏掉统计路径的失败梯度

取 x=(1,2,3)x=(1,2,3),默认 gamma 一、beta 零,损失仅取归一化输出第一坐标,即 ℓ=z1\ell=z_1。上游 u=(1,0,0)u=(1,0,0);均值二,c=(−1,0,1)c=(-1,0,1),v=2/3v=2/3,r=2/3+10−5r=\sqrt{2/3+10^{-5}},u‾=1/3\overline u=1/3,uc‾=−1/3\overline{uc}=-1/3。依公式,梯度依次是 2/(3r)−1/(3r3)2/(3r)-1/(3r^3)、−1/(3r)-1/(3r)、−1/(3r)+1/(3r3)-1/(3r)+1/(3r^3),约 (0.20413,−0.40825,0.20411)(0.20413,-0.40825,0.20411)。三项之和为零。

失败实现把均值和方差当作常量,只对分子中的当前坐标求导,会给 (1/r,0,0)(1/r,0,0),约 (1.22474,0,0)(1.22474,0,0)。它不仅与中心差分相差很大,梯度和也非零;沿全部特征共同平移的方向,它错误预测损失变化。这样的双重证据比只检查某一坐标正负可靠:一种检查来自精确不变量,另一种来自独立数值扰动。

独立运行独立标准库:三个差分步长、零和不变量和冻结统计错误的对照。
import math
x=[1.0,2.0,3.0]; eps=1e-5
mu=sum(x)/3; c=[v-mu for v in x]
r=math.sqrt(sum(v*v for v in c)/3+eps)
u=[1.0,0.0,0.0]; mean_u=sum(u)/3
mean_uc=sum(a*b for a,b in zip(u,c))/3
g=[(a-mean_u)/r-b*mean_uc/r**3 for a,b in zip(u,c)]
def loss(values):
    avg=sum(values)/len(values)
    variance=sum((v-avg)**2 for v in values)/len(values)
    return (values[0]-avg)/math.sqrt(variance+eps)
for delta in [1e-3,1e-5,1e-7]:
    numerical=[]
    for i in range(3):
        plus=x[:]; minus=x[:]; plus[i]+=delta; minus[i]-=delta
        numerical.append((loss(plus)-loss(minus))/(2*delta))
    error=max(abs(a-b) for a,b in zip(g,numerical))
    print(delta,error)
    assert error<1e-5
assert abs(sum(g))<1e-12
print('exact formula',g,'wrong frozen-statistics',[1/r,0,0])

从局部梯度走回完整块

前馈线性层按刚才 head 的同一规则反传:权重梯度是输入与输出上游梯度的外积,输入梯度乘权重转置;共享偏置梯度沿所有位置求和。精确 GELU 的导数由乘积法则得到 g′(a)=Φ(a)+aϕ(a)g^{\prime}(a)=\Phi(a)+a\phi(a),其中 ϕ(a)=e−a2/2/2π\phi(a)=e^{-a^2/2}/\sqrt{2\pi} 是正态密度,且 Φ′=ϕ\Phi^{\prime}=\phi 由积分上限求导得到。先过第二线性层,再乘这个逐元素导数,再过第一层、归一化,最后将分支输入梯度加到残差主路。

中心差分用 [L(θ+δ)−L(θ−δ)]/(2δ)[L(\theta+\delta)-L(\theta-\delta)]/(2\delta) 近似导数。若损失在邻域有三阶连续导数,泰勒展开的偶次项相消,截断误差为 O(δ2)O(\delta^2);浮点相减又会产生约随 1/δ1/\delta 放大的舍入影响,所以步长不是越小越好。检查前关闭 dropout、使用双精度、固定同一输入,并避免把优化器更新夹在正负扰动之间。本章的检查验证给定点,不替代全域解析推导。

补齐注意力分支的反向接线

为使链式法则走完一个块,再固定单头形状:序列长度为 TT、头宽为 dhd_h,查询、键和值矩阵 Q,K,VQ,K,V 均为 [T,dh][T,d_h],分数 S=QKT/dhS=QK^{\mathsf T}/\sqrt{d_h} 为 [T,T][T,T]。因果掩码规定哪些位置合法,合法位置按行 softmax 得概率矩阵 PP,头输出为 O=PVO=PV。这里大写 VV 指值矩阵,不是本节前面词表大小;以下公式局部使用这个约定,输出词表仍由 head 负责。

给定头输出上游梯度 GG,先展开 Oia=∑jPijVjaO_{ia}=\sum_jP_{ij}V_{ja}。对一个值元素求导并汇总所有查询行,得到 Vˉ=PTG\bar V=P^{\mathsf T}G;对一个概率元素求导并汇总输出特征,得到 Pˉ=GVT\bar P=GV^{\mathsf T}。前者形状是头宽矩阵,后者为分数方阵。接下来每一行都应用已经推导的 softmax 雅可比,不可把交叉熵的简化公式直接用于任意上游梯度。

Sˉij=Pij(Pˉij−∑kPikPˉik),Qˉ=SˉK/dh,Kˉ=SˉTQ/dh.\bar S_{ij}=P_{ij}\left(\bar P_{ij}-\sum_kP_{ik}\bar P_{ik}\right),\quad \bar Q=\bar S K/\sqrt{d_h},\quad \bar K=\bar S^{\mathsf T}Q/\sqrt{d_h}.
合法位置的精确反向;非法位置概率和分数梯度约定为零。

第一式来自逐项累加 ∑kPˉik ∂Pik/∂Sij\sum_k\bar P_{ik}\,\partial P_{ik}/\partial S_{ij},把指示项留下,再把公共概率因子提出。后两式分别对分数里的查询和键求导,缩放因子保持不变。回到投影时,查询路径给输入梯度 QˉWQT\bar QW_Q^{\mathsf T},键和值路径各给同类项,三者共同汇入归一化输出。拼头只是坐标重排,反传做逆重排;输出投影仍用线性层外积规则。因果掩码是固定约束而非可训练权重,反传时不得给禁止位置重新分配概率。检查顺序应先验证单行 softmax,再验证矩阵乘法,最后验证完整分支;否则一个总梯度错误无法告诉你究竟是哪一层先偏离。

检查每行分数梯度和为零:把第一式对列求和,第二项包含概率和一,正好抵消第一项。若第一位置只有它自己合法,概率恒为一,该行查询与键的梯度可能恰为零;这不是断图。参数有可达的梯度路径、某一批次梯度不为零、更新后参数改变,是三个不同断言。应在包含多个合法过去位置的输入上检查前两者,并用有限差分判断疑似错误,而不是要求所有元素每次都非零。

AdamW 是更新规则,不是链式法则的结论

把模型所有待更新实数排成参数向量 θ\theta,在第 tt 次更新前计算当前梯度 gtg_t。AdamW 维护逐坐标一阶滑动平均 mtm_t 和平方梯度平均 vtv_t;初值都为零。系数 β1,β2\beta_1,\beta_2 处于零到一之间,学习率 η>0\eta>0,衰减系数 λ≥0\lambda\ge0,优化器稳定常数 ϵa>0\epsilon_a>0,它与归一化的 eps 是两个不同超参数。

mt=β1mt−1+(1−β1)gt,vt=β2vt−1+(1−β2)gt2,m^t=mt1−β1t,v^t=vt1−β2t.m_t=\beta_1m_{t-1}+(1-\beta_1)g_t,\quad v_t=\beta_2v_{t-1}+(1-\beta_2)g_t^2,\quad \hat m_t=\frac{m_t}{1-\beta_1^t},\quad \hat v_t=\frac{v_t}{1-\beta_2^t}.
平方、除法和后续平方根均按坐标进行;t 从一开始计数。

为什么要做偏置校正?若梯度在各步期望恒为同一个值,展开一阶递推得到系数和 1−β1t1-\beta_1^t,所以未校正期望被零初值缩小;除回此系数去掉该模型下的初始化偏置。二阶递推对平方梯度有同样计算。这个推导解释校正因子,不证明实际非平稳训练的梯度分布恒定,更不证明优化必然收敛。

θt+1=(1−ηλ)θt−ηm^tv^t+ϵa.\theta_{t+1}=(1-\eta\lambda)\theta_t-\eta\frac{\hat m_t}{\sqrt{\hat v_t}+\epsilon_a}.
AdamW 定义:衰减直接作用于参数,未先将 λθ 塞入自适应矩估计。

取单个参数初值二、梯度零点一、学习率零点零一、衰减零点零一、两个 beta 为零点九和零点九九九,优化 eps 为 10−810^{-8}。第一步矩为零点零一与零点零零零零一,校正后为零点一与零点零一;自适应步约零点零一,衰减步为零点零零零二,结果约一点九八九八。若把 λθ\lambda\theta 先加进梯度,矩和分母也随之改变,那是另一种更新,不能称为本式的等价改写。

全局梯度裁剪先计算 q=∑kgk2q=\sqrt{\sum_k g_k^2},阈值 c>0c>0,再取 gkclip=gkmin⁡(1,c/q)g^{\mathrm{clip}}_k=g_k\min(1,c/q),零范数时比例约定为一。梯度三、四的范数五,阈值一便变为零点六、零点八。裁剪是选用的优化启发,不是原损失解析梯度变了,也不一般等于对一个固定新目标求导。采用 AdamW 时先裁剪再更新矩;它会影响历史状态,不能在保存检查点时只记权重。

独立运行独立标准库:偏置校正、解耦衰减和全局裁剪的具体数值。
import math
parameter,grad,lr,decay=2.0,0.1,0.01,0.01
b1,b2=0.9,0.999
m=(1-b1)*grad; v=(1-b2)*grad*grad
mh=m/(1-b1); vh=v/(1-b2)
new=(1-lr*decay)*parameter-lr*mh/(math.sqrt(vh)+1e-8)
assert abs(new-1.989800001)<1e-10
raw=[3.0,4.0]; norm=math.sqrt(sum(x*x for x in raw))
clipped=[x*min(1.0,1.0/norm) for x in raw]
assert abs(sum(x*x for x in clipped)-1.0)<1e-12
print('AdamW first step',new,'clipped gradient',clipped)

项目增量与后继依赖

项目在 train_step 中先清旧梯度、执行前向取得 loss、反向、检查有限性、全局裁剪,再调用优化器更新;若先更新后反向,更新用的就是空梯度或上一批梯度。自动微分可承担全部层的反传,但必须通过本章的 head 外积和 LayerNorm 小例复核关键路径。第七章检查完整模型每类参数是否参与计算,第八章再保存权重、矩、步数及采样状态;本章导数正确也不能替代这些系统检查。

TRY IT YOURSELF

练习一|基础:平移 logits 的检查

三类预测概率为 0.2、0.3、0.5,目标编号一。写出 logits 梯度及其和;给全部 logits 加一百是否改变损失?

提示 1
目标编号采用零起始,把p与对应独热向量逐项相减。
提示 2
先检查梯度和,再将每个exp(z)共同乘exp(100),分析精确结果与直接计算的上溢风险。
对照参考解答
梯度为 (0.2,0.3−1,0.5)=(0.2,−0.7,0.5),和为零。全部 logits 加一百,分子分母的指数共同乘 e^100,归一化概率不变,所以精确损失不变。直接指数实现可能因大数产生数值问题,稳定 logsumexp 通过减最大值避免这一类上溢。零和与平移不变是同一机制的导数和函数层检查,不应把二者误算为两种完全独立理论。

TRY IT YOURSELF

练习二|推导:归一化的共享参数梯度

同一套两特征 LayerNorm 在两个位置使用。标准化输出分别为 (−1,1) 与 (0.5,−0.5),输出上游梯度分别为 (2,3) 与 (4,−2)。求 gamma 和 beta 梯度。

提示 1
同一gamma、beta跨位置共享,不能把两位置当两套参数。
提示 2
每位置对gamma是上游乘标准化值,对beta是上游;分别算后按特征坐标累加。
对照参考解答
每位置 gamma 梯度是上游逐坐标乘标准化输出:第一位置 (−2,3),第二位置 (2,1);共享参数要累加,得到 (0,4)。beta 每位置梯度就是上游,累加为 (6,1)。这些是给定标准化值下的仿射参数精确梯度,不要求这两组值一定来自同一原始方差。只保存最后位置将错误得到 gamma=(2,1)、beta=(4,−2),形状虽正确但损失对共享参数的总导数不完整。

TRY IT YOURSELF

练习三|诊断:同样小的第一步为何不能证明裁剪无用

为便于精确算数,设标量 AdamW 第一步 beta1=beta2=0、优化 eps=0、参数一、学习率 0.1、衰减 0.1。正梯度二,裁剪到零点五前后更新结果是多少?说明这个特殊情况不能推出什么。

提示 1
把两种梯度分别代入首步m、v,注意本题beta与eps的特殊设定。
提示 2
比较g/√(g²)而非只比较g大小,最后单独加衰减;再指出多步历史会破坏哪些特殊条件。
对照参考解答
不裁剪时 m=2、v=4,自适应比值为一;裁剪后 m=0.5、v=0.25,比值仍一。两者参数均为 (1−0.1×0.1)×1−0.1=0.89。这个例子分母非零,所以临时设优化 eps 零合法;生产设置仍使用正稳定项。不能推出裁剪通常无效,因为多步矩历史、不同坐标比例、非零 eps 和异常极值都可改变行为。也不能说两种梯度相同,它们只在这个特殊归一化更新中给出相同步长。

CHECK YOUR UNDERSTANDING

检验理解

先作答,再决定是否展开解析。选择题用于发现理解缺口;独立实现与迁移任务仍需另行检验。

1. 单个有效目标的 logits 梯度为?

查看解析损失为 −s_y+logsumexp(s),两项求导分别给 −指示项和概率。
2. LayerNorm 反传把均值方差当常数会漏掉什么?

查看解析每个输入都影响均值和方差,必须把这些链式贡献计算进去。
3. AdamW 与把 λθ 加入梯度的 Adam 一般等价吗?

查看解析解耦衰减不进入梯度矩估计,二者更新定义不同。
4. 中心差分步长越小结果一定越准吗?

查看解析平滑情形截断误差随步长平方减小,但浮点舍入会在过小步长下主导。

自行标记用于记录学习进度,不代表通过项目验收。