信号白化是什么?原理、作用以及实现

信号白化(whitening)这个词在自适应滤波、语音增强、阵列处理、机器学习和统计信号处理中都经常出现。很多人第一次看到“白化”时会觉得它像一个经验技巧,但从本质上说,它做的是一件非常明确的事:把原本带相关性的信号,变成“更接近白噪声”的信号。 所谓“更白”,通常有两个标志:

白化本身不是目的,它真正的价值在于:降低相关性、压平特征值扩展、改善数值条件,从而让后续算法更稳定、更快收敛。

本文按下面 5 个部分展开:

  1. 介绍信号白化的原理及作用

  2. 结合数学公式推导为什么信号白化会提升自适应滤波器的效果

  3. 给出信号白化的几种实现代码(Python)

  4. 结合实现代码的仿真结果图说明

  5. 总结及结论

本文完整的仿真代码放在个人网站VoxWorking上了,大家有兴趣免费自取即可。资源库 · VoxWorking

1. 信号白化的原理及作用

1.1 什么是白化

理想白噪声满足:

R_x[k] = σ_x^2 δ[k]

也就是说:当 k = 0 时,自相关为信号功率;当 k != 0 时,自相关为 0。对应到频域,理想白噪声的功率谱密度是常数:

S_x(ω) = 常数

因此白化可以理解为:通过一个变换 W(z),把原始信号 x[n] 变成输出 v[n],使得:

v[n] = W(z) x[n]

并且 v[n] 的统计特性更接近白噪声。

1.2 为什么很多真实信号都不是白的

现实中的信号往往带有很强的相关性。例如:语音信号有明显谱包络,低频能量通常更强;机械振动信号常常有共振峰;回声路径输入常带有长时间相关性;通信中的基带信号经过成形滤波后也会相关;

一旦信号相关性很强,就意味着:自相关矩阵 R_x 的对角占优不明显;特征值分布不均匀;某些方向能量很大,某些方向能量很小;这会给参数估计和自适应更新带来困难。

1.3 白化的常见作用

白化最常见的工程价值有四类:

  1. 提升自适应滤波的收敛速度
  2. 改善线性估计或最小二乘问题的数值稳定性
  3. 减少特征之间的相关性,便于后续建模
  4. 在谱分析、阵列处理、检测问题里突出异常结构

在本文里,我们重点关心第一类:为什么白化能让自适应滤波器更好用。

先看一个仿真里的着色输入信号。本文用一个 AR(1) 模型生成强相关输入:

x[n] = 0.92 x[n-1] + u[n]

其中 u[n] 是白噪声激励。

从图里可以看到:

我们以这个为例去讨论白化(不失普遍性)。

2. 数学公式推导为什么信号白化会提升自适应滤波器的效果?

2.1 自适应滤波器为什么会被输入相关性拖慢

以 LMS 自适应滤波为例,权值更新公式是:

w[n+1] = w[n] + 2μ e[n] x[n]

其中:

如果用最优解 w* 表示目标参数,并定义权值误差向量:

v[n] = w[n] - w*

那么在均值意义下,它的递推近似可以写成:

E[v[n+1]] = (I - 2μR_x) E[v[n]]

这里的关键量就是输入自相关矩阵:

R_x = E[x[n]x^T[n]]

如果把 R_x 做特征分解:

R_x = QΛQ^T

其中:

Λ = diag(λ_1, λ_2, ..., λ_M)

那么在特征空间里,每个方向的收敛速度由下面这个因子决定:

1 - 2μλ_i

这说明:

如果特征值分布很不均匀,即特征值扩展很大,那么某些方向早就收敛了,某些方向却还很慢,整体收敛就会被最慢的方向限制住。通常用条件数来描述这种不均匀程度:

κ(R_x) = λ_max / λ_min

κ(R_x) 越大,LMS 通常越难调、越慢收敛。

2.2 白化为什么会改善这个问题

如果我们对白化后的输入记为:

v[n] = W x[n]

理想情况下,白化后的协方差矩阵满足:

R_v = E[v[n]v^T[n]] ≈ σ_v^2 I

这意味着:

于是均值递推就从:

E[v[n+1]] = (I - 2μR_x) E[v[n]]

变成了一个更接近各向同性的问题。对于 LMS 来说,这通常直接带来两个好处:

  1. 收敛更快
  2. 步长选择更宽松

2.3 为什么对白化前后的输入和期望信号同时处理,不改变目标系统

很多人会问:如果把输入拿去白化了,那原来要辨识的系统会不会变掉?

如果原系统满足:

d[n] = h[n] * x[n]

再对输入和期望信号同时通过同一个线性白化滤波器 W(z)

x_w[n] = W(z)x[n]
d_w[n] = W(z)d[n]

由于卷积满足交换律:

d_w[n] = W(z)(h[n] * x[n]) = h[n] * (W(z)x[n]) = h[n] * x_w[n]

所以只要对白化前后的两路信号做一致处理,目标系统 h[n] 并没有变。变化的只是输入统计特性,而这正是我们想要的。

3. 给出信号白化的几种实现代码(Python)

本文配套完整脚本见:

signal_whitening_demo.py

这里给出三种很典型的白化实现思路。

3.1 一阶差分白化

如果信号低频相关性很强,一阶差分是最简单的近似白化方式:

def first_difference_whiten(x):
    return np.convolve(x, np.array([1.0, -1.0]), mode="full")[: len(x)]

它的本质相当于一个简单高通:

它的优点是便宜、稳定、容易在线实现;缺点是白化能力有限,而且会改变频谱形状较多。

3.2 基于 AR 预测误差滤波的白化

如果信号可以近似看成 AR 过程:

x[n] + a_1 x[n-1] + ... + a_p x[n-p] = e[n]

那么预测误差 e[n] 往往就更接近白噪声。对应代码写法是:

def ar_whiten(x, order=6):
    a = estimate_ar_coeffs_yw(x, order)
    filt = np.concatenate(([1.0], -a))
    y = np.convolve(x, filt, mode="full")[: len(x)]
    return y, filt

这种方法比一阶差分更“贴合数据模型”,在语音、回声路径建模、时间序列处理中都很常见。

3.3 基于频谱幅度均衡的白化

还有一种直观做法是在频域里对谱幅度做归一化:

def spectral_whiten(x):
    n = len(x)
    x0 = x - np.mean(x)
    spec = np.fft.rfft(x0)
    mag = np.abs(spec)
    smoothed = np.convolve(mag, np.ones(17) / 17, mode="same")
    white_spec = spec / (smoothed + 1e-6)
    y = np.fft.irfft(white_spec, n=n)
    y /= np.std(y) + 1e-12
    return y

它的思想是:

这种方法非常直观,但在线实现和因果实现通常没有 FIR/IIR 方法那么直接。

4. 结合实现代码的仿真结果图说明

4.1 三种白化方法对白化程度的影响

下面这张图对比了原信号、一阶差分白化、AR 白化和频域白化后的统计特性:

从图里可以看到:

本文脚本输出的部分指标如下:

raw_lag1_autocorr=0.9204
diff_lag1_autocorr=-0.0442
ar_lag1_autocorr=0.0001
spectral_lag1_autocorr=-0.0052

数值的含义:它们衡量的是白化前后相邻样本的一阶相关性。越接近 0,通常说明“越白”。

4.2 白化前后,自适应滤波器收敛速度的差异

为了展示白化对自适应滤波的帮助,本文做了一个 LMS 系统辨识实验:

结果如下:

从学习曲线和失配曲线可以清楚看到:

这也对应了上一节推导里的核心观点:白化减小了特征值扩展,因此改善了收敛条件。

4.3 白化前后,输入协方差矩阵的特征值分布变化

为了把“特征值扩展”这件事可视化,本文还画了白化前后输入协方差矩阵特征值的分布:

这张图的意义非常直接:

本文仿真里,这两个条件数分别约为:

colored_condition_number=275.24
prewhitened_condition_number=1.18

这也是为什么白化会让 LMS 更容易训练。如果从工程角度做一句概括:

白化并不是“让信号更好看”,而是“让优化问题更好解”。

5. 总结及结论

本文可以压缩成 5 个结论:

  1. 信号白化的目标,是让信号的自相关更接近冲激、功率谱更接近平坦。
  2. 白化的核心价值,是降低输入相关性,减小协方差矩阵的特征值扩展。
  3. 对 LMS 这类自适应滤波器来说,白化后不同特征方向的收敛速度更一致,因此整体收敛通常更快。
  4. 常见白化实现包括一阶差分、AR 预测误差白化、频域谱均衡白化,它们复杂度和适用场景不同。
  5. 工程上应记住:白化不是目的,改善后续估计、检测、滤波和优化问题的条件数,才是它真正的作用。

附:运行方式

在当前目录执行:

python signal_whitening_demo.py

脚本会生成: