09 输入归一化(Normalizing Inputs)
一、为什么要归一化输入?
在训练神经网络时,如果输入特征的尺度(scale)差异很大(例如一个特征范围是 $[0, 1]$,另一个是 $[1, 1000]$),会导致:
- 代价函数(Cost Function)形状非常“细长” (elongated bowl),等高线呈椭圆形;
- 梯度下降(Gradient Descent)会来回震荡,收敛速度慢;
- 需要使用很小的学习率,否则容易发散。
而归一化后,各特征具有相似的尺度(如均值为 0,方差为 1),代价函数更接近圆形/球形,梯度下降能更快、更直接地收敛到最小值。
💡 直观理解:想象在一个又长又窄的山谷里找最低点 vs 在一个圆形碗底找最低点——后者显然更容易!
二、如何归一化输入?(两步法)
假设训练集有 $m$ 个样本,每个样本的输入特征为 $\mathbf{x}^{(i)} \in \mathbb{R}^n$($n$ 为特征维度)。
第一步:零均值化(Zero-centering)
计算训练集所有样本的均值向量:
\[\boldsymbol{\mu} = \frac{1}{m} \sum_{i=1}^{m} \mathbf{x}^{(i)}\]然后对每个样本减去均值:
\[\mathbf{x}^{(i)} := \mathbf{x}^{(i)} - \boldsymbol{\mu}\]✅ 此时所有特征的均值为 0。
第二步:归一化方差(Normalize Variance)
计算每个特征的方差(注意:此时均值已为 0,所以方差就是平方的均值):
\[\boldsymbol{\sigma}^2 = \frac{1}{m} \sum_{i=1}^{m} \left( \mathbf{x}^{(i)} \right)^2\]这里的平方是逐元素平方(element-wise squaring) ,结果 $\boldsymbol{\sigma}^2$ 是一个 $n$ 维向量,每个元素对应一个特征的方差。
然后对每个样本除以标准差(或方差的平方根):
\[\mathbf{x}^{(i)} := \frac{\mathbf{x}^{(i)}}{\boldsymbol{\sigma}}\]注意:实际实现中通常除以 $\boldsymbol{\sigma}$(标准差),而不是 $\boldsymbol{\sigma}^2$。课程中表述略有简化,但意图是让每个特征的方差变为 1。
✅ 归一化后,每个特征满足:
\[\text{mean} = 0,\quad \text{variance} = 1\]
三、重要实践建议:训练集与测试集必须用相同的 $\boldsymbol{\mu}$ 和 $\boldsymbol{\sigma}$
- $\boldsymbol{\mu}$ 和 $\boldsymbol{\sigma}$ 必须仅从训练集计算得出;
- 测试集(或验证集)必须使用训练集的 $\boldsymbol{\mu}$ 和 $\boldsymbol{\sigma}$ 进行归一化;
- 绝不能分别对训练集和测试集单独计算各自的均值和方差。
❗ 原因:训练和测试数据必须经过完全相同的预处理变换,否则会引入分布偏移(distribution shift),影响模型泛化能力。
四、何时需要归一化?
| 特征尺度情况 | 是否需要归一化 | 说明 |
|---|---|---|
| 所有特征都在相似范围(如 $[-1,1]$, $[0,2]$) | ❌ 可选 | 影响不大,但归一化也无害 |
| 特征尺度差异巨大(如 $[0,1]$ vs $[1,1000]$) | ✅ 强烈推荐 | 能显著加速训练、提升稳定性 |
✅ 经验法则:如果你不确定是否需要归一化,就做归一化!它几乎从不有害,且常常带来好处。
五、对优化过程的影响(直观图示)
- 未归一化:代价函数 $J(\mathbf{w}, b)$ 的等高线是细长椭圆 → 梯度下降路径曲折、缓慢;
- 归一化后:等高线接近圆形 → 梯度下降可沿直线快速收敛。
⚠️ 虽然实际参数 $\mathbf{w}$ 是高维的,无法可视化,但二维类比足以说明核心思想。
六、总结要点(Key Takeaways)
- 输入归一化 = 零均值 + 单位方差;
- 使用训练集统计量($\boldsymbol{\mu}, \boldsymbol{\sigma}$)处理所有数据(包括测试集);
- 归一化使代价函数更“圆”,加速梯度下降收敛;
- 当特征尺度差异大时,归一化至关重要;
- 即使尺度相近,归一化也是安全且推荐的做法。
附:常用归一化公式(标准化 / Z-score Normalization)
对于第 $j$ 个特征:
\[x_j^{(i)} \leftarrow \frac{x_j^{(i)} - \mu_j}{\sigma_j}\]其中:
- $\mu_j = \frac{1}{m} \sum_{i=1}^m x_j^{(i)}$
- $\sigma_j = \sqrt{ \frac{1}{m} \sum_{i=1}^m (x_j^{(i)} - \mu_j)^2 }$
这就是机器学习中最常用的 Standardization(标准化) 方法。
[!NOTE] ✏️ 为什么震荡 当特征尺度差异很大时,代价函数在不同参数方向上的“陡峭程度”极不均衡,导致梯度方向严重偏离最速下降路径,从而产生横向震荡。
一、从代价函数的形状说起
假设你有两个输入特征 x1 和 x2,其中:
- x1∈[0,1000](比如“房屋面积”,单位:平方米)
- x2∈[0,1](比如“房间数量归一化值”)
那么,在神经网络中,对应的权重为 w1 和 w2。
由于 x1 的数值远大于 x2,微小的 w1 变化就会引起输出的巨大变化,而 w2 需要较大变化才能产生同等影响。
这导致代价函数 J(w1,w2) 在 w1 方向非常“陡峭”,而在 w2 方向非常“平缓”。
👉 结果:等高线图是一个非常细长的椭圆,长轴沿 w2 方向,短轴沿 w1 方向。