引言

LayerNorm 的公式几乎人人都能背出来,但在语音任务里,输入张量通常是 [B, F, T](batch、频率、时间),此时”归一化哪个维度”并没有唯一答案。选 F 还是选 T,会直接改变模型”看得见什么、看不见什么”。

本文从公式出发,先讲清楚 LayerNorm 怎么算,再重点回答一个容易被忽略的问题:把 F 还是 T 当作特征维,本质区别到底是什么? 最后澄清一个常见混淆——“能量”和”音量”。


1. LayerNorm 的基本公式

对输入向量 $x \in \mathbb{R}^d$:

$$ \mu = \frac{1}{d}\sum_{i=1}^{d} x_i $$

$$ \sigma^2 = \frac{1}{d}\sum_{i=1}^{d}(x_i - \mu)^2 $$

$$ \text{LayerNorm}(x) = \gamma \odot \frac{x - \mu}{\sqrt{\sigma^2 + \epsilon}} + \beta $$

其中 $\gamma, \beta$ 是可学习的缩放和偏移参数,$\epsilon$ 是防止除零的小常数。

计算步骤只有四步:

  1. 求均值
  2. 求方差
  3. 减均值、除标准差
  4. 用 $\gamma, \beta$ 做仿射变换

LayerNorm 的关键特点是:在特征维度上归一化,对每个样本独立计算,与 batch 大小无关。这正是它被 Transformer 系列模型(BERT、GPT、Conformer 等)广泛采用的原因——训练和推理行为一致,不依赖 batch 统计量。


2. 语音场景 [B, F, T] 下的几种归一化方式

设输入为 [B, F, T],B 是 batch,F 是频率 bin,T 是时间帧。常见的 LayerNorm 用法有三种。

2.1 对每个时间帧、跨频率归一化(F 当特征维)

对每个 (b, t) 位置,在 F 维度上算均值方差:

$$ \mu_{b,t} = \frac{1}{F}\sum_{f=1}^{F} x_{b,f,t}, \quad \sigma^2_{b,t} = \frac{1}{F}\sum_{f=1}^{F}(x_{b,f,t}-\mu_{b,t})^2 $$

$$ y_{b,f,t} = \gamma_f \cdot \frac{x_{b,f,t}-\mu_{b,t}}{\sqrt{\sigma^2_{b,t}+\epsilon}} + \beta_f $$

  • 归一化维度:F
  • 统计量共 B×T 组,每组 F 个样本
  • $\gamma, \beta$ 形状为 [F]
  • 这是 Transformer/Conformer 语音前端的标准做法

2.2 对每个频率、跨时间归一化(T 当特征维)

对每个 (b, f),在 T 维度上归一化:

$$ \mu_{b,f} = \frac{1}{T}\sum_{t=1}^{T} x_{b,f,t}, \quad \sigma^2_{b,f} = \frac{1}{T}\sum_{t=1}^{T}(x_{b,f,t}-\mu_{b,f})^2 $$

  • 归一化维度:T
  • 统计量共 B×F 组,每组 T 个样本
  • $\gamma, \beta$ 形状为 [T]
  • 传统语音特征里的 CMVN(倒谱均值方差归一化)本质就是这种

2.3 跨 F 和 T 一起归一化

对每个样本 b,在整个时频图上算一组均值方差:

$$ \mu_b = \frac{1}{FT}\sum_{f,t} x_{b,f,t}, \quad \sigma^2_b = \frac{1}{FT}\sum_{f,t} (x_{b,f,t}-\mu_b)^2 $$

  • 归一化维度:F×T
  • 每个样本只有 1 组统计量
  • 对应 nn.LayerNorm((F, T))

2.4 PyTorch 实现要点

nn.LayerNorm(normalized_shape) 归一化的是最后若干个维度,所以:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 输入 [B, F, T]

# 归一化 F 维(每个 (b,t) 跨 F):需要把 F 放最后
x = x.permute(0, 2, 1) # [B, T, F]
ln = nn.LayerNorm(F)
y = ln(x).permute(0, 2, 1) # 回到 [B, F, T]

# 归一化 T 维(每个 (b,f) 跨 T):
ln = nn.LayerNorm(T) # T 是最后一维
y = ln(x) # [B, F, T]

# 归一化 F×T:
ln = nn.LayerNorm((F, T))
y = ln(x) # [B, F, T]

3. 核心问题:F 当特征 vs T 当特征,区别到底在哪?

公式本身不变,变的只是”求均值和方差的轴”。但这一变,模型看到的信息结构就完全不同了。

3.1 先手算一个 2×3 的例子

假设 B=1,F=2,T=3:

1
2
3
       t1   t2   t3
f1 1 2 3
f2 3 4 5

做法 A:F 当特征(沿竖线,每列算)

t1 列是 [1, 3]:均值 2,减均值得 [-1, 1],方差 1,归一化后 [-1, 1]。

t2 列是 [2, 4]:均值 3,归一化后 [-1, 1]。

t3 列是 [3, 5]:均值 4,归一化后 [-1, 1]。

结果:

1
2
3
       t1    t2    t3
f1 -1 -1 -1
f2 1 1 1

三个时刻结果一模一样。因为每帧都是”f2 比 f1 大 2”,这个形状没变;而 t1 整体小、t3 整体大,这个整体电平被减掉了。

做法 B:T 当特征(沿横线,每行算)

f1 行是 [1, 2, 3]:均值 2,减均值 [-1, 0, 1],标准差 ≈ 0.816,归一化后 ≈ [-1.22, 0, 1.22]。

f2 行是 [3, 4, 5]:均值 4,归一化后同样 ≈ [-1.22, 0, 1.22]。

结果:

1
2
3
       t1     t2     t3
f1 -1.22 0 1.22
f2 -1.22 0 1.22

两个频带结果一模一样。因为两行都是”随时间线性上升”,这个走势没变;而 f2 整体比 f1 高 2,这个频带整体高低被减掉了。

3.2 本质:哪些数被放进同一组

LayerNorm 做的事就一句:把一组数拉到均值 0、方差 1。

所以关键不是”怎么拉”,而是:你把哪些数放进同一组?

  • F 归一化:把同一时刻的所有频率放进一组。
  • T 归一化:把同一频率的所有时刻放进一组。

放进的组不同,被抹平的东西就不同。

3.3 抹平了什么,保留了什么

用”归一化后还能问什么问题”来区分最清楚。归一化前有两个问题:

  • 问题 A:t3 时刻是不是比 t1 时刻整体更响?
  • 问题 B:f2 频带是不是比 f1 频带整体更强?
问题 A(时刻间整体强弱) 问题 B(频带间整体强弱) 保留的是
F 归一化 不能问了(每帧被拉到同一水平) 还能问 每帧内部的频谱形状
T 归一化 还能问 不能问了(每个频带被拉到同一水平) 每个频带内部的时间走势

一句话:

F 归一化抹掉”时刻之间的整体电平差”,保留”同一帧内频率之间的相对结构”。

T 归一化抹掉”频带之间的整体电平差”,保留”同一频带内时间上的走势”。

3.4 为什么这个区别对下游任务重要

语音识别关心”这一帧是什么音素”。 音素主要由频谱形状(共振峰位置)决定,而不是这一帧录得多响。

  • F 归一化:去掉帧级电平差异,保留频谱形状 → 适合 ASR / Transformer 前端。
  • T 归一化:每个频带各自按时间标准化,当前帧的频谱形状会依赖该频带整段的历史统计,绝对频谱被扭曲 → 不利于音素判别。

去除麦克风/通道的频带偏差,关心”每个频带整体偏了多少”。 这正是 T 归一化擅长的(CMVN 就是每个频带跨时间减均值除方差)。

  • T 归一化:适合前端通道归一化。
  • F 归一化:不跨时间聚合,对频带级偏差无能为力。

3.5 与模型结构的耦合

Transformer 把每个时间帧当成一个 token,LayerNorm(F) 正好对每个 token 的特征维归一化,与文本 Transformer 的 LayerNorm(d_model) 语义一致。

如果用 T 当特征,等于把”时间顺序”塞进 token 内部的特征维去归一化,与注意力的 token 结构不匹配,一般不这么做。


4. 常见混淆澄清:”能量”和”音量”不是一回事

讨论 LayerNorm 时,常听到”F 归一化去掉每帧的整体音量””T 归一化去掉每个频带的整体能量”。这两个说法都是直观比喻,严格说都不准确。

4.1 两者的区别

  • 能量(energy):客观的物理/数学量。短时能量 = 一帧内采样点平方和;频谱能量 = 各频点幅度平方。有明确定义,与人耳无关。
  • 音量(volume / loudness):严格意义是主观感知量(心理声学中的响度),依赖人耳、频率加权、持续时间;日常口语中常指播放音量/录音电平/增益。
能量 音量
性质 客观物理/数学量 主观感知量(或口语中的增益/电平)
定义 幅度平方和 人耳响度;口语中常指 level
依赖 只看信号本身 依赖人耳、频率、上下文

4.2 回到 LayerNorm 的准确表述

LayerNorm 去掉的是该归一化轴上的均值(整体偏移/DC)和方差(整体尺度),与物理能量没有严格对应。

而且实际输入往往是 log-mel、MFCC、线性谱等特征:

  • 对 log-mel 做 F 方向减均值 ≈ 去掉”这一帧的平均 log 能量”,即一种帧级增益归一化——这才是”去掉整体音量”比喻的真实含义。
  • 对 log-mel 做 T 方向减均值 ≈ 去掉”这个频带在整句上的平均 log 能量”,即频带级增益/通道偏差归一化——这才是”去掉频带整体能量”比喻的真实含义。

注意:log 域下平方和不是物理能量;归一化操作的是特征统计量,不是物理能量本身。


5. 两个工程上的硬区别

除了”抹平什么”,F/T 归一化在工程行为上还有两个关键差异。

5.1 逐帧独立 vs 依赖整段

  • F 归一化:每帧独立计算,当前帧结果只依赖当前帧 → 天然适配变长输入、流式、因果场景。
  • T 归一化:需要看完一段时间的统计才能算,当前帧结果依赖整段 → 非因果,结果随句长变化,流式场景麻烦。

5.2 统计量稳定性

  • F 归一化:每组有 F 个样本(F 通常 80~512),统计量稳定。
  • T 归一化:每组有 T 个样本,短语音时 T 很小,均值和方差估计噪声大。

6. 实践建议

场景 推荐 原因
Transformer / Conformer 语音前端 F 当特征维 与 [B, T, F] 的 token 结构一致,逐帧独立,适配变长
去除麦克风/通道频带偏差 T 归一化 或 CMVN 每个频带跨时间减均值除方差,专门对付频带级偏移
两者都需要 先 T 方向 CMVN,再模型内 F 方向 LayerNorm 各司其职:前端去通道,模型内去帧级增益

核心原则:问自己”哪种变化是干扰、我想消掉它?”

  • 干扰是帧级整体电平(录音音量忽大忽小)→ 用 F 归一化。
  • 干扰是频带级整体偏移(不同麦克风频响)→ 用 T 归一化。

7. 总结

LayerNorm 的公式很简单,难的是想清楚”沿哪个轴聚合”。

  • F 归一化:让”不同时刻”变得不可比(电平被拉平),让”同一时刻内的频率结构”保持可比。
  • T 归一化:让”不同频带”变得不可比(能量被拉平),让”同一频带内的时间走势”保持可比。

选哪个,取决于你希望模型忽略哪种差异、保留哪种结构。Transformer 语音模型选 F,是因为它把每帧当一个 token,要忽略的是帧级电平,要保留的是频谱形状;前端通道归一化选 T,是因为要消除的是频带级增益偏差。

理解了”哪些数被放进同一组”,F/T 归一化的区别就不再抽象了。