0%

机器学习-PyTorch训练循环

从 batch 张量出发,逐节拼出完整训练循环。

张量 tensor (1)

前一篇的第5小节(例3)中,为了清晰地展示前向计算与后向求导的数学过程,计算全部采用标量(0维tensor)。实际上,PyTorch 使用矩阵(多维tensor)一次性处理一个 Batch,即 $B$ 个样本组成一个 $B \times N$ 的矩阵(其中 $N$ 是一个样本的特征数),前向计算从”逐样本循环”变成”一次矩阵运算”。回顾那个例子,2个样本(图1中红色的$\boldsymbol{x}^1$ 和 绿色的$\boldsymbol{x}^2$),每个样本2个特征,标量形式的计算图如下:

figure1

图1:DAG标量

改成向量形式(PyTorch真实情况):

figure2

图2:DAG向量

对账:图2中 $Y$ 的两行 $1.5362$ 和 $1.4915$ 即前一篇第 5.5 小节的 $\hat{y}^1$ 和 $\hat{y}^2$;再跑 backward,$w_{11}$ 的梯度是 $0.006731$ 与第 5.7 小节手算的一致。

用 nn.Module 搭网络 (2)

  • 手写 20 个 torch.tensor(…, requires_grad=True) 的痛点
  • nn.Linear + nn.Sigmoid 拼出 3-2-1 网络,参数自动收集进 parameters()
  • 对账:state_dict() 里的 20 个数 = 第一篇 5.2 的初始值表

损失函数 (3)

  • 第一篇手写 $\frac{1}{2}\sum(\hat{y}-y)^2$ → 换成 nn.MSELoss
  • 系数辨析:MSELoss 默认是均值,与第一篇的 $\frac{1}{2}$ 和差一个常数倍——梯度同比例缩放,正好用第一篇的手算功底验证(0.00673 × 换算系数)

优化器 (4)

  • 拿到 .grad 之后呢:$\boldsymbol{\theta}^{N+1} = \boldsymbol{\theta}^{N} - \eta \cdot \boldsymbol{\nabla}L$
  • optim.SGD:zero_grad() → backward() → step() 三件套
  • 回扣第一篇 3.2 的注(叶子 +=` 累加 → 必须zero_grad);学习率 η 直观演示(太大 loss 爆炸/太小不收敛)

数据加载 (5)

  • Dataset / DataLoader:batch、shuffle
  • 真实数据登场:从 tsar.data.hdd.1 读磁盘延迟数据(特征→标签的构造)
  • 时间序列的特殊性:不能随机 shuffle,按时间切分

训练循环 (6)

  • 五件套拼合:epoch × (zero_grad → forward → loss → backward → step)
  • 观察 loss 曲线下降;第 1 个 epoch 的梯度与第一篇手算值对账(闭环验证)
  • 推理模式:model.eval() / torch.no_grad()——回扣最小信息原则(不记图、不存 saved tensors,省显存)

保存与恢复 (7)

  • state_dict() 落盘 / 加载 / 断点续训

下一步 (8)

GPU 加速(.to(device));过拟合与 train/val/test 划分(时序场景的注意点)——为第三篇埋伏笔

写的不错,有赏!