A3 · DEEP NETWORKS

模块化反向传播与卷积网络

把 layer cache、optimizer state、normalization 与 convolution 当成可审计的对象生命周期。

Layer contractsOptimizer stateCNN debugging

Review Lab,不是作业答案。阅读现有实现,先预测,再运行小实验并解释证据;原始仓库快照是代码事实来源。

阶段 01

网络层的契约

为 affine、ReLU、normalization 建立 forward/backward 对偶契约。

为什么需要它

模块化只在 cache 身份和 shape 可追踪时才减少复杂度。

开始前应该已经会回答

  • 能解释 upstream gradient
  • 会推 bias gradient reduction

输入、输出与契约

输入
x,w,b + upstream dout
输出
out + dx,dw,db
不变量
  • 每个 gradient 对应原对象 shape
  • backward 使用同一次 forward cache
不成立的假设
  • 用全局可变状态偷传 cache
  • 广播后忘记按被广播轴求和

用最小例子检查

用 N=2,D=3,C=2 手推 affine backward 的三个输出 shape。

如果你看到……

db 带 batch 维

优先检查:broadcast reduction

单层对、组合错

优先检查:cache 顺序与接口

预测 → 实验 → 证据

先预测
组合层的数值梯度应与逐层链式组合一致。
做实验
对 affine-ReLU composite 做 sparse gradient check。
留证据
  • 每个参数 relative error
  • 非光滑点处理
  • 输入规模

渐进提示

先独立排查 10–15 分钟,再按需展开。

提示 1

先测独立 layer

提示 2

再测 sandwich

提示 3

打印 cache 类型与 shape

闭卷检查 · 网络层的契约

  • 每层独立通过
  • 组合通过
  • 能从计算图解释三条梯度
阶段 02

优化器状态

区分 gradient、momentum、second moment 与 parameter update。

为什么需要它

Adam/SGD 的差异来自状态和缩放,不是“更聪明”的标签。

开始前应该已经会回答

  • 能手算一维 momentum
  • 能区分优化状态与模型参数

输入、输出与契约

输入
w,dw,config
输出
next_w,next_config
不变量
  • 状态 shape 与参数一致
  • step 计数单调且每次只增一次
不成立的假设
  • 跨参数共享同一 mutable config
  • 把 weight decay 与 L2 gradient 永远视为等价

用最小例子检查

一个参数 w=1、g=2,手算两步 momentum,再运行实现。

如果你看到……

第二步像第一步

优先检查:状态没有持久化

不同参数互相污染

优先检查:config aliasing

预测 → 实验 → 证据

先预测
momentum 在同向梯度下累积速度;梯度反向时会有惯性。
做实验
用预设梯度序列 [2,2,-2] 比较 SGD/momentum/Adam 的 update。
留证据
  • 每步 state
  • 每步 delta w
  • 超参数

渐进提示

先独立排查 10–15 分钟,再按需展开。

提示 1

先用标量

提示 2

打印 state identity

提示 3

检查 step 增量位置

闭卷检查 · 优化器状态

  • 标量轨迹一致
  • 能解释状态记忆
  • 不同参数状态隔离
阶段 03

卷积的形状与局部性

沿 N,C,H,W、filter 与 stride/pad 推导输出及反向。

为什么需要它

CNN 把空间局部性和权重共享写进参数结构。

开始前应该已经会回答

  • 会从一个窗口手算 dot product
  • 能解释 parameter sharing

输入、输出与契约

输入
x [N,C,H,W], w [F,C,HH,WW]
输出
out [N,F,Hout,Wout]
不变量
  • 同一 filter 在所有位置共享
  • 输出尺寸满足整数滑动窗口
不成立的假设
  • 把 channel 当空间轴
  • 只记公式不检查边界窗口

用最小例子检查

N=C=F=1,3×3 输入配 2×2 filter,stride=1,无 padding,手算 2×2 输出。

如果你看到……

输出错一格

优先检查:边界与 stride 起点

每个位置参数不同

优先检查:是否丢失权重共享

预测 → 实验 → 证据

先预测
stride 增大降低空间分辨率;padding 可保持尺寸但引入边界假设。
做实验
固定 filter 比较 stride/pad 四种配置的 shape 与一个角落值。
留证据
  • 公式预测
  • 实际 shape
  • 边界值来源

渐进提示

先独立排查 10–15 分钟,再按需展开。

提示 1

先画窗口坐标

提示 2

确认 NCHW 次序

提示 3

只看左上输出单元

闭卷检查 · 卷积的形状与局部性

  • toy 输出正确
  • shape 预测正确
  • 能解释共享与局部性
阶段 04

CNN 证据检查

用 activation、gradient 与 timing 解释网络是否正确且值得。

为什么需要它

更深或更快都不是单一结论;必须知道改变了什么资源和表示。

开始前应该已经会回答

  • 知道 GPU timing 需同步
  • 能解释 activation distribution

输入、输出与契约

输入
baseline CNN + one controlled change
输出
correctness/performance evidence
不变量
  • 相同数据与训练预算
  • 同时记录模型行为和运行配置
不成立的假设
  • 把 wall time 差异归因于 kernel 而不 warmup
  • 只挑最好一次

用最小例子检查

先让单 batch 过拟合,再比较一个 architecture change。

如果你看到……

train loss NaN

优先检查:normalization、learning rate、gradient norm

速度反而慢

优先检查:shape、warmup、kernel overhead

预测 → 实验 → 证据

先预测
改变 normalization 可能改善训练稳定性,但不会自动减少 FLOPs。
做实验
固定 seed/batch/steps,记录 loss、gradient norm、latency。
留证据
  • baseline/config
  • 重复次数
  • 机制解释

渐进提示

先独立排查 10–15 分钟,再按需展开。

提示 1

正确性先于 benchmark

提示 2

tiny overfit 后再 profile

提示 3

用 profiler 验证瓶颈

闭卷检查 · CNN 证据检查

  • 能过拟合小 batch
  • 性能测量条件完整
  • 结论区分优化与统计效果

复盘与迁移