用全连接网络识别 MNIST:参考答案

目录

\[ \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} \]

用全连接网络识别 MNIST:参考答案#

返回正文练习 · 返回答案索引

说明#

以下答案与正文 7 道题逐题对应。推导题给出主要步骤;编程和实验题给出参考程序和检查方法,并说明结果适用于哪些条件。

  1. 展平后为 \(64\times784\)⁠,随后依次为 \(64\times128\)⁠、\(64\times64\)\(64\times10\)⁠。ToTensor 把原始 0--255 整数像素转换为浮点并缩放到 \([0,1]\)⁠。三层参数量为 \(128(784+1)=100480\)⁠、\(64(128+1)=8256\)⁠、\(10(64+1)=650\)⁠,合计 109386。展平只改变维度,不增加参数。

  2. 分母为 \(e^2+e+1\)⁠,概率约为 \((0.6652,0.2447,0.0900)\)⁠。损失为 \(-\log0.6652\approx0.4076\)⁠。稳定写法先减最大值 2:\(\log(e^0+e^{-1}+e^{-2})\approx\log1.5032=0.4076\)⁠,等价于 \(\log\sum_k e^{z_k}-z_y\)⁠,无需先形成可能上溢的 \(e^2\) 一般化大数。

  3. 总损失和为 \(64(0.2)+36(0.5)=30.8\)⁠,除以 100 得 \(0.308\)⁠。直接平均两个批均值会得到 \(0.35\)⁠,等价于错误地给 36 样本小批次与 64 样本批次相同权重。程序应累加 batch_mean * batch_size最后除以真实样本数。

  4. \(k\) 类概率为 \(e^{z_k+c}/\sum_j e^{z_j+c}=e^ce^{z_k}/[e^c\sum_j e^{z_j}]=e^{z_k}/\sum_j e^{z_j}\)⁠,所以整体平移不改变 Softmax。取 \(c=-\max_kz_k\) 后所有指数输入不大于 0,避免很大的正指数溢出;真实类负对数概率也保持不变。

  5. 可复现训练的关键是验证集与随机状态独立保存:

    def train_model(model, train_loader, valid_loader, epochs, optimizer, criterion):
        best_loss, best_state, history = float("inf"), None, []
        for epoch in range(epochs):
            model.train()
            for x, y in train_loader:
                optimizer.zero_grad(); loss = criterion(model(x), y)
                loss.backward(); optimizer.step()
            valid_loss, valid_acc = evaluate(model, valid_loader, criterion)
            history.append((valid_loss, valid_acc))
            if valid_loss < best_loss:
                best_loss = valid_loss
                best_state = copy.deepcopy(model.state_dict())
        model.load_state_dict(best_state)
        return history
    

    划分索引应先固定并保存;测试集只在模型、超参数和检查点规则冻结后评价一次。

  6. 断言张量为 \(m\times1\times28\times28\) 且值位于 \([0,1]\)⁠,展平为 \(m\times784\)⁠;标签最小值和最大值位于 0--9;固定生成器后首批索引和初始损失相同;eval()no_grad() 下固定输入预测一致;批量加权损失为 0.308;加载保存状态后预测恢复;每个可训练参数都有同形、有限梯度。还应拒绝错误图像尺寸。

  7. 应比较所有“隐藏层宽度×学习率”组合,并检查学习率的影响是否会随宽度而改变。每个组合使用相同的数据划分、随机种子、批次顺序和训练轮数。宽度增加会提高模型容量,也会增加参数量、训练时间与内存;较合适的学习率可能随宽度改变。结果表必须包含测试精度、多个随机种子下结果的波动、训练秒数、固定批量与单样本预测时间、参数量和峰值内存;各组应在验证集上尝试相同数量的设置,不能给某个宽度额外尝试更多学习率。