改善深层神经网络 | Improving Deep Neural Networks

Based on notes from Professor Andrew Ng's Deep Learning Specialization. Course 2 weeks 1-2 notes.

周日 5月 10 2026
2635 字 · 10 分钟

本文是我学习吴恩达(Andrew Ng)《Deep Learning Specialization》后整理的笔记,记录第二门课前两周 Improving Deep Neural Networks 的核心内容。

前一篇已经把深层神经网络的基本记号、前向传播、反向传播和向量化形式固定下来。这一部分主要处理训练结果该如何诊断,过拟合如何控制,深层网络数值上为什么会不稳定,以及参数更新怎样做得更快。

训练诊断

数据划分与判断顺序

深层网络进入实践阶段后,先要解决的不是再换一个模型,而是先判断问题出在哪里。训练集、开发集、测试集在这里承担的是不同角色:

  • 训练集用于拟合参数;
  • 开发集用于选择结构、超参数和训练策略;
  • 测试集只在最后用于评估最终泛化效果。

这个划分本身并不新,但在深层网络里更值得强调。网络规模、超参数和训练技巧都明显变多,如果没有单独的开发集,很多调节动作就会直接污染最终评估。

判断顺序通常也是固定的。先看训练误差,再看开发误差。若训练误差已经偏高,问题更接近高偏差;若训练误差不高,但开发误差明显更高,问题更接近高方差。若两者都高,说明模型拟合能力和泛化能力都还不够稳定。

因此,这一部分真正建立的是一套诊断框架,而不是单独某个公式。后面的正则化、dropout、初始化和优化算法,都应放在这套诊断顺序之后理解。

偏差 方差 与基本处理配方

偏差和方差在机器学习课程中已经出现过,这里不再重复定义。

高偏差表示模型对训练集本身的拟合还不够。常见处理方向包括:

  • 增大网络容量;
  • 训练更久;
  • 改善优化过程;
  • 调整网络结构。

高方差表示模型已经把训练集学得比较好,但泛化到开发集时误差上升明显。常见处理方向包括:

  • 增加数据;
  • 使用更强的正则化;
  • 调整开发集分布;
  • 控制模型复杂度。

这里更重要的是处理顺序。先判断是偏差问题还是方差问题,再决定后续动作。若这个顺序颠倒,很多技巧会被用错位置,例如高偏差阶段过早加强正则化,往往只会让训练更难。

稳定训练

L2 正则化

L2 正则化是在原有代价函数基础上加入权重惩罚项。若第 ll 层的参数记为 W[l]W^{[l]},则正则化后的目标函数写成

J=1mi=1mL(y^(i),y(i))+λ2ml=1LW[l]F2J = \frac{1}{m}\sum_{i=1}^{m}\mathcal{L}\bigl(\hat{y}^{(i)}, y^{(i)}\bigr) + \frac{\lambda}{2m}\sum_{l=1}^{L}\left\|W^{[l]}\right\|_F^2

其中:

  • mm 是样本数;
  • L\mathcal{L} 是单样本损失;
  • λ\lambda 是正则化强度;
  • W[l]F2\|W^{[l]}\|_F^2 是第 ll 层权重矩阵的 Frobenius 范数平方。

这一项直接约束的是权重规模,因此反向传播时,每层梯度会相应多出一项:

dW[l]dW[l]+λmW[l]dW^{[l]} \leftarrow dW^{[l]} + \frac{\lambda}{m}W^{[l]}

代入梯度下降以后,参数更新写成

W[l]:=W[l]α(dW[l]+λmW[l])W^{[l]} := W^{[l]} - \alpha\left(dW^{[l]} + \frac{\lambda}{m}W^{[l]}\right)

这个式子里,α\alpha 是学习率。若只看更新效果,会发现每一步都在把权重往更小的范围压,因此课程里也常把它和 weight decay 联系起来。

Dropout

dropout 不是改损失函数,而是在训练阶段对隐藏单元做随机稀疏化。设第 ll 层激活为 A[l]A^{[l]},保留概率为 keep_prob,则训练时可写成

D[l]Bernoulli(keep_prob)D^{[l]} \sim \text{Bernoulli}(\text{keep\_prob})A[l]:=A[l]D[l]A^{[l]} := A^{[l]} * D^{[l]}

若采用 inverted dropout,还需要再除以保留概率:

A[l]:=A[l]D[l]keep_probA^{[l]} := \frac{A^{[l]} * D^{[l]}}{\text{keep\_prob}}

这里:

  • D[l]D^{[l]} 是与 A[l]A^{[l]} 同维度的随机掩码矩阵;
  • 每个元素取 0011
  • keep_prob 控制该层保留单元的比例。

这种写法对应的含义很直接。训练时,同一层并不是每次都让所有单元参与计算,而是随机保留其中一部分。inverted dropout 再用 keep_prob\text{keep\_prob} 做缩放,使测试时不需要额外调整输出尺度。

如果把它放进实现里,最容易写错的不是原理,而是掩码维度和缩放位置。dropout 只在训练阶段使用,测试阶段应关掉;做梯度检查时也应先关掉 dropout,否则前向传播本身带有随机性,数值近似会失去可比性。

其他稳定训练的做法

除了正则化和 dropout,第一周还补了几项更偏训练过程的处理。

第一项是输入归一化。若输入特征写成 xx,均值为 μ\mu,标准差为 σ\sigma,常见形式是

x:=xμσx := \frac{x-\mu}{\sigma}

这个式子并不新,但在深层网络里很实用。不同特征量级差距过大时,参数空间里的更新会很不均匀,归一化能够让训练更平稳。

第二项是梯度消失和梯度爆炸。深层网络反向传播时,梯度会沿层连续相乘。若乘到很多层以后整体量级越来越小,就会出现梯度消失;若整体量级越来越大,就会出现梯度爆炸。这个问题和层数、激活函数以及初始化方式都有关系。

第三项是权值初始化。初始化不能全部为零,否则同一层各单元会保持完全相同的更新轨迹。更合理的做法,是让参数以较小随机值开始,同时让不同层的尺度尽量保持在合理范围内。课程这一部分主要是在给后面的 Xavier 和 He 初始化作铺垫,因此这里先把目标固定住即可:既要打破对称性,又要避免激活值和梯度在传播中迅速失控。

梯度近似与梯度检查

梯度检查是一类调试工具。若把所有参数压成一个向量 θ\theta,对其中某一维做很小的扰动 ε\varepsilon,则数值梯度近似可以写成

JθJ(θ+ε)J(θε)2ε\frac{\partial J}{\partial \theta} \approx \frac{J(\theta+\varepsilon)-J(\theta-\varepsilon)}{2\varepsilon}

这里:

  • θ\theta 表示待检查的参数;
  • ε\varepsilon 是很小的扰动量;
  • 右边是中心差分近似。

若把反向传播得到的梯度记为 dθd\theta,数值梯度记为 dθapproxd\theta_{\text{approx}},则二者差异常写成

difference=dθdθapprox2dθ2+dθapprox2\text{difference} = \frac{\left\|d\theta-d\theta_{\text{approx}}\right\|_2} {\left\|d\theta\right\|_2+\left\|d\theta_{\text{approx}}\right\|_2}

这个比值足够小时,说明反向传播实现大体正确。梯度检查只适合调试,因为代价很高,不能放进日常训练循环里。

优化算法

小批量梯度下降

标准梯度下降每次更新都使用全部训练样本。若样本数很大,这种做法在深层网络里会很慢。mini-batch 的思路,是把训练集拆成若干批小样本,每次只用其中一个 batch 做前向传播、反向传播和参数更新。

若一个批次包含 BB 个样本,则这一轮更新中用到的是

X{t}Rnx×B,Y{t}Rny×BX^{\{t\}} \in \mathbb{R}^{n_x \times B}, \qquad Y^{\{t\}} \in \mathbb{R}^{n_y \times B}

这里花括号上标 {t}{\{t\}} 只表示第 tt 个 mini-batch。公式本身和整批训练完全一致,只是把样本子集换成了更小的一块。

小批量训练以后,代价函数曲线通常不再像整批梯度下降那样平滑,而会有一定抖动。这一点不表示算法错了,而是因为每一步看到的数据子集不同。课程里这一段的重点,就是让读者从整批更新过渡到更快的批量更新。

指数加权平均

指数加权平均是后面一串优化器的基础。若序列写成 xtx_t,其滑动平均写成 vtv_t,则有

vt=βvt1+(1β)xtv_t = \beta v_{t-1} + (1-\beta)x_t

其中 β[0,1)\beta \in [0,1) 控制平滑程度。β\beta 越大,平均结果越平滑,也越依赖更久以前的历史值;β\beta 越小,结果对当前值更敏感。

若初始时取 v0=0v_0 = 0,早期会有偏小问题,因此可做偏差修正:

vtcorrected=vt1βtv_t^{\text{corrected}} = \frac{v_t}{1-\beta^t}

这一步在迭代初期更有意义,因为随着 tt 增大,βt\beta^t 会趋近于 00,修正项影响会越来越弱。

Momentum 与 RMSprop

Momentum 先对梯度做指数加权平均,再用这个平滑后的方向更新参数。若第 ll 层权重梯度为 dW[l]dW^{[l]},则常写成

VdW[l]=βVdW[l]+(1β)dW[l]V_{dW^{[l]}} = \beta V_{dW^{[l]}} + (1-\beta)dW^{[l]}W[l]:=W[l]αVdW[l]W^{[l]} := W^{[l]} - \alpha V_{dW^{[l]}}

偏置 b[l]b^{[l]} 也有完全对应的写法。这里的 VdW[l]V_{dW^{[l]}} 可以看成梯度的平滑轨迹。参数不再只看当前一步的梯度,而是综合最近一段时间的方向。

RMSprop 则对梯度平方做指数加权平均。常见写法为

SdW[l]=βSdW[l]+(1β)(dW[l])2S_{dW^{[l]}} = \beta S_{dW^{[l]}} + (1-\beta)\bigl(dW^{[l]}\bigr)^2W[l]:=W[l]αdW[l]SdW[l]+εW^{[l]} := W^{[l]} - \alpha \frac{dW^{[l]}}{\sqrt{S_{dW^{[l]}}}+\varepsilon}

其中 ε\varepsilon 是很小的常数,用来避免分母为零。RMSprop 的作用是根据梯度历史尺度,对不同方向的更新幅度做自适应缩放。

Adam

Adam 可以看成 Momentum 和 RMSprop 的合并形式。它同时维护一阶矩和二阶矩。对第 ll 层参数,有

VdW[l]=β1VdW[l]+(1β1)dW[l]V_{dW^{[l]}} = \beta_1 V_{dW^{[l]}} + (1-\beta_1)dW^{[l]}SdW[l]=β2SdW[l]+(1β2)(dW[l])2S_{dW^{[l]}} = \beta_2 S_{dW^{[l]}} + (1-\beta_2)\bigl(dW^{[l]}\bigr)^2

然后分别做偏差修正:

VdW[l]corrected=VdW[l]1β1tSdW[l]corrected=SdW[l]1β2tV_{dW^{[l]}}^{\text{corrected}} = \frac{V_{dW^{[l]}}}{1-\beta_1^t} \qquad S_{dW^{[l]}}^{\text{corrected}} = \frac{S_{dW^{[l]}}}{1-\beta_2^t}

最终更新式为

W[l]:=W[l]αVdW[l]correctedSdW[l]corrected+εW^{[l]} := W^{[l]} - \alpha \frac{V_{dW^{[l]}}^{\text{corrected}}} {\sqrt{S_{dW^{[l]}}^{\text{corrected}}}+\varepsilon}

偏置参数同样完全对应。这里:

  • β1\beta_1 控制一阶矩平滑;
  • β2\beta_2 控制二阶矩平滑;
  • ε\varepsilon 保证分母稳定;
  • tt 是当前迭代步数。

课程里给出的常用默认值是 β1=0.9\beta_1=0.9β2=0.999\beta_2=0.999ε108\varepsilon\approx10^{-8}。这组写法也是后面很多深度学习实现中的常见默认起点。

学习率衰减与参数空间

优化器之外,学习率本身也可以随训练过程变化。学习率衰减的目标很直接:前期更新步子可以大一些,后期接近较优区域时再逐渐减小。一个常见形式是

αt=α01+decay_ratet\alpha_t = \frac{\alpha_0}{1+\text{decay\_rate}\cdot t}

其中 α0\alpha_0 是初始学习率,αt\alpha_t 是第 tt 轮使用的学习率。不同衰减策略形式不完全一样,但核心都一样:让训练后期的更新更稳。

至于局部最优,课程里更强调高维参数空间中的另一类现象。深层网络训练时,更常见的问题往往不是掉进一个很差的严格局部极小点,而是停在鞍点附近,或者落进很平坦的区域,使优化速度明显变慢。这一节的作用,是修正对参数空间形状的直觉,而不是再引入新的更新公式。


Thanks for reading!

改善深层神经网络 | Improving Deep Neural Networks

周日 5月 10 2026
2635 字 · 10 分钟