压缩感知中的测量矩阵(Measurement Matrix)详解
目录
引言
在压缩感知(Compressed Sensing, CS)框架中,测量矩阵(Measurement Matrix)起着至关重要的“压缩”作用。它能够在“信号还没有被完整采样”之前,就先将信号映射到一个更低维的测量空间中,从而极大地降低所需采样点的数量。测量矩阵经常被记为 Φ \mathbf{\Phi} Φ,尺寸为 M × N M \times N M×N,其中:
- N N N 表示原始信号或向量的维度;
- M M M 则表示所获得的压缩观测的维度(且一般 M ≪ N M \ll N M≪N)。
本篇我们将从基础概念、作用、关键性质到常见构造方法,对测量矩阵进行深入而通俗的解析。
测量矩阵的基本概念
设有一个原始信号向量
x
∈
R
N
\mathbf{x} \in \mathbb{R}^N
x∈RN,我们所做的“压缩采样”即用一个
M
×
N
M \times N
M×N 的矩阵
Φ
\mathbf{\Phi}
Φ 将
x
\mathbf{x}
x 映射成一个只有
M
M
M 维的向量
y
\mathbf{y}
y:
y
=
Φ
x
,
y
∈
R
M
.
\mathbf{y} = \mathbf{\Phi} \mathbf{x}, \quad \mathbf{y} \in \mathbb{R}^M.
y=Φx,y∈RM.
之所以能够“用比N小得多的M”来观测到足够多的信息,是因为压缩感知假设
x
\mathbf{x}
x 在某个域是稀疏或可压缩的,并且
Φ
\mathbf{\Phi}
Φ 要满足一定的随机性和不相干性,使得在少量观测的情况下,依然可以通过后续的重建算法,高概率地重构出原始信号。
测量矩阵的主要作用
- 减少采样点:传统的奈奎斯特采样需要至少与信号带宽或尺寸相当的采样点数,而CS中的测量矩阵让我们可以使用远少于 N N N 的测量来获取关于 x \mathbf{x} x 的“主要信息”。
- 保证可重建性:如果测量矩阵满足特定的性质(例如RIP、不相干性),就能使得在一定条件下通过 ℓ 1 \ell_1 ℓ1最小化或贪婪算法从 y \mathbf{y} y 反推出 x \mathbf{x} x。
- 应对高维数据:如图像、视频或高维传感器数据,测量矩阵提供了一种“先压缩后重建”的思路,降低存储和传输开销。
测量矩阵的核心性质
不相干性(Incoherence)
概念:当测量矩阵与信号的稀疏基(或变换域基)之间互不相关时,少量的测量也能捕获到足够的稀疏系数信息。若二者高度相关,就需要更多测量才能有效区分这些系数。
用数学方式简单表示,若信号在基
Ψ
\mathbf{\Psi}
Ψ 下是稀疏的,则
x
=
Ψ
α
\mathbf{x} = \mathbf{\Psi}\boldsymbol{\alpha}
x=Ψα。我们在测量
x
\mathbf{x}
x 时,相当于:
y
=
Φ
x
=
Φ
Ψ
α
.
\mathbf{y} = \mathbf{\Phi x} = \mathbf{\Phi \Psi}\boldsymbol{\alpha}.
y=Φx=ΦΨα.
这里
Φ
Ψ
\mathbf{\Phi \Psi}
ΦΨ 应当与
α
\boldsymbol{\alpha}
α 低相关度(或不相干),这样少量观测也能区分开不同的稀疏分量。
RIP(Restricted Isometry Property)
简要回顾:RIP的含义是——对所有
K
K
K-稀疏向量
x
\mathbf{x}
x,测量后信号的长度(
ℓ
2
\ell_2
ℓ2范数)与原信号长度大致相同:
(
1
−
δ
)
∥
x
∥
2
2
≤
∥
Φ
x
∥
2
2
≤
(
1
+
δ
)
∥
x
∥
2
2
.
(1 - \delta)\|\mathbf{x}\|_2^2 \le \|\mathbf{\Phi x}\|_2^2 \le (1 + \delta)\|\mathbf{x}\|_2^2.
(1−δ)∥x∥22≤∥Φx∥22≤(1+δ)∥x∥22.
只要
δ
\delta
δ 较小(通常称其为RIP常数),就说明
Φ
\mathbf{\Phi}
Φ 对所有
K
K
K-稀疏向量几乎是一个等距映射,它不会把不同稀疏向量折叠到同一个测量结果中。这就使得后续的信号重建成为可能。
典型的测量矩阵构造方法
下面我们列举几种常见的、在理论和实践中都颇具代表性的构造方式。
随机高斯矩阵
- 构造: Φ \mathbf{\Phi} Φ 的每个元素独立抽取自正态分布 N ( 0 , 1 / M ) \mathcal{N}(0, 1/\sqrt{M}) N(0,1/M) 或 N ( 0 , 1 ) \mathcal{N}(0,1) N(0,1)(有时需要对列或行做归一化)。
- 优点:满足RIP的概率非常高;不相干性往往也比较好。
- 缺点:存储量大(要存下 M × N M \times N M×N 个随机数),对硬件实现有时不够友好。
随机伯努利矩阵
- 构造: Φ \mathbf{\Phi} Φ 的元素独立取 ± 1 \pm 1 ±1 或 { 0 , 1 } \{0,1\} {0,1} 等离散分布;有时也需要均值为零、方差归一。
- 优点:存储简化,尤其是 ± 1 \pm 1 ±1 形式容易在数字电路或光学系统中实现。
- 缺点:需要关注对稀疏基的兼容性,某些情况下随机伯努利矩阵的实际测量噪声容忍度可能比高斯略差。
部分傅里叶矩阵(Partial Fourier)
- 构造:先写出 N × N N \times N N×N 的离散傅里叶变换(DFT)矩阵,然后随机抽取其中的 M M M 行,组成 M × N M \times N M×N 的“部分傅里叶矩阵”。
- 常见应用:MRI成像(医学中的磁共振),因为对应的观测天生就是傅里叶域的数据。
- 优点:无需大量随机数;对自然图像或信号(常在傅里叶域稀疏)十分有效;
- 缺点:实现上要确保行选择的随机性,同时也要考虑噪声场景下的稳定性。
其他随机构造方式
- 随机Toeplitz或Circulant矩阵:只需生成一行随机数,通过卷积结构实现测量,硬件实现更高效。
- 随机稀疏矩阵:在某些场合考虑硬件效率,可让测量矩阵的部分元素为0,从而减少乘法运算。
- 行或列分块随机化:在大规模问题中常被采用,兼顾RIP和计算效率。
测量矩阵的维度与稀疏度的关系
- 信号稀疏度 K K K:假设信号在某个基下最多只有 K K K 个非零系数。
- 测量数 M M M:如果选取的测量数太少,则根本不足以区分所有可能的 K K K-稀疏信号;反之,如果选取的 M M M 足够大,就能确保满足一定重建概率。
- 理论界:压缩感知理论表明,若 M ≥ C ⋅ K ⋅ log ( N K ) M \ge C \cdot K \cdot \log(\frac{N}{K}) M≥C⋅K⋅log(KN)(其中C是常数),则有高概率可恢复原始信号。该不等式经常出现在Candès、Donoho等人的经典论文中。
测量矩阵中的噪声与稳定性
- 在实际中, y = Φ x + ϵ \mathbf{y} = \mathbf{\Phi x} + \mathbf{\epsilon} y=Φx+ϵ,其中 ϵ \mathbf{\epsilon} ϵ 代表噪声。
- 一旦有噪声,测量矩阵需要尽可能满足RIP等性质,以使得重建结果对噪声具有鲁棒性。
- 对于噪声模型,也可使用 ℓ 2 \ell_2 ℓ2 范数约束或加入正则化形式(如 Lasso)来进行稳健的稀疏重建。
总结
- 测量矩阵 是压缩感知中的“关键魔术”,能用少量测量来完整“感知”到一个高维稀疏信号的主要信息。
- 其核心要求是满足不相干性与RIP,并且尺寸 M M M 通常与信号的稀疏度 K K K 密切相关;
- 常见实现包括随机高斯、随机伯努利、部分傅里叶等;
- 在硬件或实际应用中,兼顾存储、计算开销与对稀疏基的“兼容性”,才能发挥测量矩阵在压缩感知中的强大威力。
示例代码(Python)
下面给出一个简单的演示示例,展示了如何用随机高斯测量矩阵对一个稀疏信号进行采样。然后简单打印测量结果以及测量矩阵的某些特性。
注意:这只是一段小示例,用来说明测量矩阵的生成与使用,未含完整的重建流程。
import numpy as np
# 1. 设置参数
N = 100 # 原始信号长度
M = 30 # 测量数 (M < N)
K = 5 # 稀疏度
# 2. 构造稀疏信号 x_true
x_true = np.zeros(N)
nonzero_indices = np.random.choice(N, K, replace=False)
x_true[nonzero_indices] = np.random.randn(K) * 5 # 加大幅度以看得更明显
# 3. 随机高斯测量矩阵 Phi
# 每个元素是 N(0,1),也可做一些归一化
Phi = np.random.randn(M, N)
# 4. 获取观测值 y = Phi * x_true
y = Phi.dot(x_true)
# 5. 打印信息
print("测量矩阵 Phi (部分展示):\n", Phi[:5,:5]) # 仅显示前5行、前5列
print("原始信号 x_true:\n", x_true)
print("观测向量 y:\n", y)
print("观测向量长度:", len(y))
# (可选) 观察测量矩阵行的范数、统计特性
row_norms = np.linalg.norm(Phi, axis=1)
print("各行范数 (前10个):", row_norms[:10])