\[ \begin{align}\begin{aligned}\newcommand{\ba}{\boldsymbol{a}}
\newcommand{\bb}{\boldsymbol{b}}
\newcommand{\be}{\boldsymbol{e}}
\newcommand{\bq}{\boldsymbol{q}}
\newcommand{\bk}{\boldsymbol{k}}
\newcommand{\bw}{\boldsymbol{w}}
\newcommand{\bx}{\boldsymbol{x}}
\newcommand{\by}{\boldsymbol{y}}
\newcommand{\bz}{\boldsymbol{z}}
\newcommand{\bd}{\boldsymbol{d}}
\newcommand{\bv}{\boldsymbol{v}}
\newcommand{\bs}{\boldsymbol{s}}\\\newcommand{\btheta}{\boldsymbol{\theta}}
\newcommand{\bbeta}{\boldsymbol{\beta}}
\newcommand{\bgamma}{\boldsymbol{\gamma}}
\newcommand{\bsigma}{\boldsymbol{\sigma}}
\newcommand{\md}{\mbox{d}}
\newcommand{\bmu}{\boldsymbol{\mu}}
\newcommand{\bone}{\boldsymbol{1}}
\newcommand{\bzero}{\boldsymbol{0}}
\newcommand{\bepsilon}{\boldsymbol{\epsilon}}
\newcommand{\bphi}{\boldsymbol{\phi}}
\newcommand{\bh}{\boldsymbol{h}}
\newcommand{\bc}{\boldsymbol{c}}
\newcommand{\br}{\boldsymbol{r}}
\newcommand{\bQ}{\boldsymbol{Q}}
\newcommand{\bK}{\boldsymbol{K}}
\newcommand{\bV}{\boldsymbol{V}}
\newcommand{\bSigma}{\boldsymbol{\Sigma}}
\newcommand{\bg}{\boldsymbol{g}}
\newcommand{\bxi}{\boldsymbol{\xi}}
\newcommand{\bvarepsilon}{\boldsymbol{\varepsilon}}
\newcommand{\bdelta}{\boldsymbol{\delta}}
\newcommand{\bq}{\boldsymbol{q}}
\newcommand{\bk}{\boldsymbol{k}}
\newcommand{\bJ}{\boldsymbol{J}}
\newcommand{\bp}{\boldsymbol{p}}
\newcommand{\bi}{\boldsymbol{i}}
\newcommand{\bo}{\boldsymbol{o}}
\newcommand{\bE}{\boldsymbol{E}}
\newcommand{\bH}{\boldsymbol{H}}
\newcommand{\bL}{\boldsymbol{L}}
\newcommand{\bu}{\boldsymbol{u}}
\newcommand{\bLambda}{\boldsymbol{\Lambda}}
\newcommand{\trans}{^{\rm\scriptsize T}}
\newcommand{\var}{\mathrm{var}}\\\newcommand{\bA}{\boldsymbol{A}}
\newcommand{\bB}{\boldsymbol{B}}
\newcommand{\bC}{\boldsymbol{C}}
\newcommand{\bD}{\boldsymbol{D}}
\newcommand{\bG}{\boldsymbol{G}}
\newcommand{\bI}{\boldsymbol{I}}
\newcommand{\bM}{\boldsymbol{M}}
\newcommand{\bP}{\boldsymbol{P}}
\newcommand{\bS}{\boldsymbol{S}}
\newcommand{\bU}{\boldsymbol{U}}
\newcommand{\bW}{\boldsymbol{W}}
\newcommand{\bX}{\boldsymbol{X}}
\newcommand{\bY}{\boldsymbol{Y}}
\newcommand{\bZ}{\boldsymbol{Z}}
\newcommand{\cotp}{\textcolor[RGB]{48,209,88}{TP}}
\newcommand{\cotn}{\textcolor[RGB]{100,210,255}{TN}}
\newcommand{\cofp}{\textcolor[RGB]{94,92,230}{FP}}
\newcommand{\cofn}{\textcolor[RGB]{191,90,242}{FN}}\\\newcommand{\numcotp}{\textcolor[RGB]{48,209,88}{50}}
\newcommand{\numcotn}{\textcolor[RGB]{100,210,255}{30}}
\newcommand{\numcofp}{\textcolor[RGB]{94,92,230}{10}}
\newcommand{\numcofn}{\textcolor[RGB]{191,90,242}{10}}
\DeclareMathOperator*{\argmin}{arg\,min}\end{aligned}\end{align} \]
深度学习实验实践指南:参考答案
返回正文练习 · 返回答案索引
说明
以下答案与正文 9 道题逐题对应。推导题给出主要步骤;编程和实验题给出参考程序和检查方法,并说明结果适用于哪些条件。
少量且容易区分的训练样本通常比较容易学习。如果模型不能几乎完全正确地预测这些样本,应优先检查输入数据与标签是否对应、数组维度是否正确、损失函数是否合适、参数是否真正得到更新,以及模型是否具有足够的学习能力。不过,这项检查只表明模型能够学习当前给出的少量训练样本。例如,数据处理程序可能错误地提前使用了验证集或测试集的信息,但模型仍能通过检查;验证样本与验证标签可能没有正确对应,这也不会影响模型学习训练样本;参数很多的模型还可能只是记住了少量训练样本,却不能正确预测新数据。因此,通过这项检查不能证明整个实验流程完全正确,也不能保证模型在新数据上表现良好。
无动量时 \(\Delta\btheta=-0.02\nabla\mathcal J\),故更新范数为 \(0.02(5)=0.1\),相对更新量为 \(0.1/20=0.005\),即 \(0.5\%\)。单步数值没有通用的好坏阈值;应结合损失、梯度范数和多步变化观察。持续接近 0 可能表示学习过慢或梯度断开,持续过大且损失剧烈波动可能表示学习率过大。
验证损失最小的是第 2 轮,应保存该轮。最后一轮损失比最佳轮高 \(0.62-0.55=0.07\),准确率低 \(0.76-0.73=0.03\),即 3 个百分点。选择规则必须在观察测试结果前确定;若用测试指标改选轮次,测试集就参与了模型选择,最终测试结果会偏乐观。
处理一个训练批次的平均时间为 \(40/200=0.2\) 秒。完成一次固定批量预测的平均时间为 \(2/100=0.02\) 秒,即 20 毫秒。设备首次编译、缓存和异步执行都会影响计时,所以各方案必须采用相同预热次数、必要的设备同步、固定批量和重复次数。
检查器应在更新前后分别记录状态:
def check_step(x, y, loss, model, before, allowed_labels, step):
if not np.isfinite(np.asarray(x)).all():
raise FloatingPointError(f"step={step}: 输入非有限")
if not set(np.asarray(y).tolist()) <= set(allowed_labels):
raise ValueError("标签超出允许集合")
if not torch.isfinite(loss):
raise FloatingPointError(f"step={step}: 损失非有限")
grad2 = sum((p.grad.detach() ** 2).sum() for p in model.parameters()
if p.grad is not None)
delta2 = sum(((p.detach() - q) ** 2).sum()
for p, q in zip(model.parameters(), before))
param2 = sum((q ** 2).sum() for q in before)
return {"grad_norm": grad2.sqrt().item(),
"relative_update": (delta2 / param2.clamp_min(1e-30)).sqrt().item()}
异常处理还应保存步号、批次索引、配置和随机数生成器状态。
标签错位应首先表现为小样本无法稳定过拟合或标签—样本一致性测试失败;过大学习率应触发损失/梯度非有限或相对更新量异常;未切换评估模式可通过对同一样本改变同批伙伴后预测变化来发现;NaN 输入必须在前向前被有限性断言截获。每个故障只改变一个因素,测试先确认错误版本稳定失败,再修复并运行全部旧测试。
三个学习率共享同一批次顺序、初始化种子和更新次数。较小值可能稳定但达到阈值较慢,较大值可能更快也可能振荡或发散;应保留失败运行。报告多种子测试指标、达到阈值时间、总训练秒数、固定批量预测时间、参数量和峰值内存。学习率不改变模型结构,因此参数量和推断成本原则上相同;若实测差异明显,应增加重复计时并检查设备状态。
先明确是固定总样本数还是固定更新次数;两种预算回答的问题不同,不能混用。批量大小会影响硬件利用率、峰值内存、更新次数、梯度噪声和最终指标。结果表应给出任务指标均值与标准差、总训练时间、相同固定批量的预测时间、参数量和峰值内存。模型结构不变时参数量及推断图相同,预测计时不应使用各自的训练批量。
三种流程共享同一最大轮数、验证频率和选择指标。使用最后一轮可能错过泛化最好的阶段;加载最佳检查点不节省训练,但通常避免性能回退;提前停止还能减少实际轮数,却可能因验证噪声或耐心值过小而过早结束。应报告实际训练轮数与秒数、测试指标、固定批量预测时间、参数量和峰值内存。三种流程最终网络结构相同,预测成本应近似,主要权衡在任务性能和训练成本。