ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

压缩感知实战:用OMP从欠定数据中识别稀疏滤波器冲激响应

压缩感知实战:用OMP从欠定数据中识别稀疏滤波器冲激响应 我第一次体会到压缩感知Compressed Sensing的威力是在一次滤波器识别任务里。系统标称阶数是64阶按奈奎斯特的惯性思维我得准备至少几百组输入输出数据用最小二乘才能把冲激响应估出来。可测试结果出来的时候我愣住了真正系数不为零的抽头只有四五个整个滤波器几乎就是稀疏的。后来换用压缩感知思路只用了不到三分之一的数据量就把非零位置和幅度都找出来了。这篇文章不打算绕着理论走而是直接用“冲激响应识别”这个场景讲清楚压缩感知到底在干什么、滤波器识别怎么转化成压缩感知问题、用什么算法求解以及真实项目里我踩过的坑。无论你是做信号处理、通信、控制还是刚接触这个方向的学生都可以照着思路复现一套自己的实验。1. 从奈奎斯特到压缩感知一次采样观念的转变1.1 传统采样为什么“浪费”奈奎斯特-香农采样定理是信号处理教科书里的铁律采样率必须大于信号最高频率的两倍否则频谱混叠信息就永久丢掉了。这条规则统治了将近一个世纪也塑造了所有ADC/DAC、通信系统设计的底层逻辑。但仔细想一下它其实是一个“对所有信号都成立”的最保守条件完全没有利用信号本身的结构。很多实际信号比如图像、音频、射频信道响应在某个变换域里只有很少几个大系数其余全是接近零的小系数。按传统流程我们是先把完整的N个点采下来再做压缩编码丢掉不重要的部分JPEG和MP3就是这么干的。这相当于花掉了全部采样成本然后扔掉了大部分信息在资源受限的场合非常不划算。核磁共振成像就是一个典型例子。医学上采集的k空间数据量巨大如果逐行采完再压缩患者躺在扫描仪里的时间会非常长。压缩感知之所以能在这里落地就是因为图像的梯度或小波系数天然稀疏可以用远少于奈奎斯特要求的观测次数重建出可用的图像。这个观察改变了很多工程技术人员的思路与其采样后压缩不如在采样时刻就只获取“足够恢复信息”的线性测量。1.2 稀疏性压缩感知的基石压缩感知的核心洞察是如果信号本身是稀疏的那就可以在采集阶段只做少量的线性测量而不是等到全采完再压缩。稀疏性通俗讲就是“有效自由度很少”信号在某个域的表示向量x中非零元个数K远小于向量长度N。比如一个回声路径的冲激响应虽然在一个窗口内看起来很长但真正的大抽头只有几个再比如多径信道的冲激响应就是少数几条路径的叠加。这种信号在物理上非常普遍问题只在于你是否选对了表达域。要在M远小于N的欠定条件下恢复这个稀疏向量不能随便设计测量矩阵。Candes、Romberg和陶哲轩他们给出了一个关键条件测量矩阵Φ必须满足约束等距性英文叫Restricted Isometry Property简称RIP。通俗理解就是Φ不能把两个不同的K稀疏信号映射到几乎一样的观测值。如果违反了这个性质你看到观测y根本分不清它是来自x1还是x2再好的算法也白搭。满足RIP的典型矩阵是随机高斯矩阵和随机伯努利矩阵这也是压缩感知论文里满天飞随机矩阵的原因。1.3 压缩感知三要素稀疏基、测量矩阵、重建算法任何压缩感知方案都绕不开三个要素。第一是稀疏基或者字典让原始信号在某个变换域下稀疏第二是测量矩阵它决定了观测向量怎么从信号生成第三是重建算法它负责从欠定方程中找回稀疏解。这三者缺一个都不行但重要性并不相同。我的经验排序是稀疏性 测量矩阵 算法。原因很简单如果信号根本不稀疏压缩感知就失去了“可恢复”的理论基础算法选得差一点顶多多跑几次迭代或者换个思路就能补齐。在滤波器识别这个场景里有一个很大的便利稀疏基就是单位阵。因为我们要估计的是未知冲激响应h而很多真实滤波器的冲激响应本身就近似稀疏不需要额外做傅里叶变换或小波变换。这给我省去了一大步。所以整套方案里真正要花心思的只剩测量矩阵怎么构造、稀疏恢复算法怎么调以及工程实现时怎么避坑。2. 滤波器识别问题的数学建模从输入输出到稀疏恢复2.1 滤波器识别的标准形式一个数字滤波器如果用FIR模型描述输出y(n)只由当前和过去L-1个输入决定y(n) h(0)u(n) h(1)u(n-1) ... h(L-1)u(n-L1) v(n)其中h(k)是未知的冲激响应v(n)是测量噪声。把n从L到ML-1共M个方程写成矩阵形式y U h v这里的U是M乘L的卷积矩阵每一行由输入u在不同时刻的值构成也叫Toeplitz结构矩阵。信道估计、回声消除、声学路径建模本质上都是这个模型。传统辨识方法比如最小二乘就是最小化||y - U h||²。当M大于等于L且输入信号充分激励时有闭式解h_LS (UᵀU)⁻¹Uᵀy但这个式子隐藏着一个问题当未知抽头数L很大而观测数M不够时UᵀU不可逆解不稳定即便M够大如果输入信号不是白噪声UᵀU也会病态。2.2 稀疏冲激响应什么时候出现在移动通信里多径信道的冲激响应就是一组时延各异的路径路径数目远小于采样点个数所以它是一个稀疏向量。声学回声路径在稀疏环境里也只有少数明显反射峰。超宽带雷达的回波同样可以看成是少数几个目标反射叠加的结果。这些场景的共同点是物理上只有少数几个散射体或反射路径对应的冲激响应“有效抽头数”很少但采样分辨率给得很高于是势必要用很长的向量来表示。如果用普通的LS去做估计不仅需要的观测次数多而且未知向量一长噪声会被摊到所有抽头上估计方差随之变大。更麻烦的是系统辨识里经常出现“欠定”情况你没法拿到无限长的观测或者激励信号带宽受限能用的方程数M比未知数L还少。这时LS基本失效但压缩感知告诉我们只要h是稀疏的欠定并不是绝路。2.3 为什么能直接套用压缩感知现在把滤波器识别和压缩感知对应起来。未知稀疏向量是h测量矩阵是U观测是y。从压缩感知的角度任务就是min ||h||₀约束条件 ||y - U h||₂ ≤ ε这里L₀范数表示h中非零元素的个数。如果U满足RIP那么用远小于L的观测数M也能恢复出h。我最初有一个困惑U是由输入信号生成的卷积矩阵并不是一个随机高斯矩阵它也能满足RIP吗后来的理解是如果输入采用随机白噪声或随机二值序列卷积矩阵的每一行就是输入的一段随机切片行与行之间近似独立整体性质接近随机矩阵所以可以有条件地期望它满足RIP。理论上有专门工作分析过Toeplitz和循环矩阵的RIP结论是输入充分随机时稀疏恢复保证仍然成立。所以压缩感知滤波器识别的方案可以概括成三步设计一个充分随机的激励信号采集M组输入输出用稀疏恢复算法解出h。后面的章节就围绕这三步展开。3. 求解算法从L0到L1以及我常用的贪心实现3.1 从L0到L1为什么凸松弛可行最小化L₀范数直观上就是想找“非零项数最少”的解这是问题的原始目标。但L₀约束不是凸集直接求解是NP难的。压缩感知理论最重要的成果之一就是把L₀松弛成L₁范数min ||h||₁约束条件 ||y - U h||₂ ≤ εL₁球是凸的问题变成了凸优化可以用现成工具求解。为什么L₁能带来稀疏解可以看一个几何直观。在二维情况下L₁约束是一个菱形等值线如果和这个菱形相切很容易切在顶角上而顶角正好对应某个坐标为0L₂约束是圆形切点大概率不在坐标轴上因此L₂解通常不稀疏。理解了这一点就明白为什么历史上Lasso能天然具备特征选择能力。不过凸优化虽然理论优美对工程人员来说迭代求解器内部细节像黑盒参数调节并不直观。我的一般做法是离线对比时用凸优化作为精度参考实际工程里用贪心算法也就是下面要说的OMP。3.2 正交匹配追踪OMP贪心但足够好用正交匹配追踪的思路特别像“剥洋葱”每次从字典里挑一个与当前残差最相关的原子把该原子加入支撑集再用最小二乘重新估计支撑集上的系数更新残差重复直到满足停止条件。它不直接优化L₀而是逐步逼近。因为实现简单、计算量可控在支撑原子相关性不高的很多场景下恢复效果能和凸优化打得有来有回。下面这段是我常用的一段Python实现顺手做了一点工程化处理比如原子归一化避免某列能量过大导致相关性判断被误导。import numpy as np def omp(U, y, KNone, tol1e-6): M, L U.shape # 归一化原子提升相关性判断的数值稳定性 norm_cols np.linalg.norm(U, axis0) Phi U / norm_cols x np.zeros(L) r y.copy() support [] for _ in range(L): if K is not None and len(support) K: break # 1. 选择与残差最相关的原子 corr Phi.T r idx np.argmax(np.abs(corr)) if idx in support: # 理论上不会发生但数值上可能重复 break support.append(idx) # 2. 最小二乘更新支撑集系数 Us U[:, support] x_s, _, _, _ np.linalg.lstsq(Us, y, rcondNone) # 3. 更新残差 r y - Us x_s if np.linalg.norm(r) tol: break if support: x[support] x_s return x代码里用np.linalg.lstsq做最小二乘小规模问题下足够稳定。如果你处理的是超大维矩阵建议把这一步换成QR增量更新否则每次迭代都重新做一次完整最小二乘成本偏高。3.3 停止条件与稀疏度未知怎么办OMP需要知道何时停止。如果噪声很小且稀疏度K已知直接迭代K次即可但工程上K很少先验已知。我惯用的方法有两个一个是设定残差阈值当残差能量小于噪声能量的某个比例就停另一个是观察残差下降曲线。通常真实支撑集找全之前残差快速下降一旦找全接下来的下降会明显变缓那个拐点就是很好的停止位置。如果噪声是零均值高斯白噪声标准差为σ可以用一个启发式阈值ε σ√(M 2√(2M))。这个式子来自高维随机向量的范数集中性质意思是M维高斯噪声的L₂范数大概率被限制在这个范围。在SNR超过15dB的场景下这个阈值挺稳。但要注意它只是一个经验起点实际用的时候最好根据你的数据和噪声统计量再校准一遍。3.4 调参经验迭代次数不是越多越好我踩过的一个坑是在噪声环境下把OMP迭代次数设得很大。有一次我天真地设成20次结果前4次正确选出了真实抽头后面几次开始选噪声原子重建的归一化均方误差反而变差了。原因很简单OMP每选一个原子都是在“啃”残差里剩余的能量真实信号能量选完后残差里就只剩噪声和模型失配此时继续选原子就是纯过拟合。所以我的经验是“宁少勿多”。如果真实稀疏度未知先用残差下降曲线估一个乐观值再在它附近扫几个候选K用交叉验证或验证集选最小的重建误差。这种朴素的做法往往比硬套一个复杂贝叶斯模型更可控。4. 实验设计与结果对比用压缩感知识别一个稀疏滤波器4.1 仿真场景与参数为了验证这套方法我做过一组仿真。设未知滤波器长度为L64只有4个非零抽头位置分别在第5、12、28、51个抽头幅度为0.8、-0.5、0.3、0.2。激励信号u(n)采用零均值方差为1的高斯白噪声观测数M从16扫到40。观测噪声添加高斯白噪声使整体信噪比SNR20dB。对比算法包括普通最小二乘和OMP。普通最小二乘只在M大于等于64时能求出唯一解所以它在欠定阶段直接退出。每个M下做500次蒙特卡洛恢复成功标准定义为支撑集位置完全正确且估计幅度相对误差小于0.1。我用归一化均方误差NMSE来评估整体重建质量。4.2 需要多少观测数才够结果很有意思。M16时OMP恢复成功率不到50%M24时上升到约88%M32时超过96%M40时基本接近100%。这和理论公式M ≈ C·K·log(N/K)是对得上的。K4N64N/K16ln(N/K)约2.77如果C取1.5M的理论值大约16.6。但实际因为输入信号构造的卷积矩阵不是理想随机矩阵所需常数C更大M到30左右才稳定。观测数M成功概率%平均NMSEdB1645.6-12.32488.2-20.53296.8-26.14099.4-31.2所以我给工程估算的建议是理论值先算出来然后乘上两到三倍作为工程余量。如果理论说M需要20实际设计按40到60准备否则换一个稍微复杂的实际场景就容易翻车。4.3 噪声的影响与阈值设定噪声环境直接决定你该设多少停止阈值。在SNR10dB时固定迭代次数K4的做法已经不可靠因为噪声会引入虚假相关峰OMP可能选错位置。把停止条件改成残差阈值后成功率有所回升但整体还是比20dB时差不少。我进一步降低到SNR5dB时OMP基本失效即使位置选对了幅度估计的偏差也很大。另一个观察是阈值设置和M有关。M越大噪声的L₂范数越集中阈值越容易估计M越小噪声能量方差越大固定阈值的风险就越高。所以低信噪比、短观测条件下我更倾向于用L1凸优化或者后面会提到的稀疏贝叶斯学习而不是硬上OMP。4.4 与最小二乘和LMS自适应滤波的横向对比我把三种传统方法拉出来对比。最小二乘在M大于等于L时发挥不错但需要的数据量远大于压缩感知而且输入相关时UᵀU容易病态。LMS自适应滤波不需要矩阵求逆能在线迭代但收敛速度受特征值扩散度影响很大在稀疏滤波器场景下LMS完全没有利用稀疏性收敛需要大量迭代。方法数据需求是否利用稀疏性在线能力计算复杂度最小二乘LSM ≥ L否批处理低LMS自适应多否是极低OMP稀疏恢复约2到4倍C·K·log(N/K)是难中L1凸优化同左是可滑窗中高一个工程结论是离线辨识、稀疏结构明显、样本受限的场合压缩感知有显著优势实时跟踪、非稀疏结构、硬件资源紧张的场景传统自适应滤波依然更实用。5. 工程落地时的坑我踩过的几个注意点5.1 输入激励信号别再拍脑袋我踩过的第一个坑是输入信号设计。有一次为了省事给滤波器输入一个正弦扫频信号结果恢复出来的h惨不忍睹。后来才明白压缩感知对测量矩阵有个隐含要求各行尽可能不相干。正弦扫频信号的卷积矩阵行与行之间高度相关感知矩阵的互相关性非常大RIP很难满足稀疏恢复自然失效。解决办法很简单用高斯白噪声、均匀随机数或伪随机二进制序列PRBS做激励。PRBS在工程系统里尤其好用因为二值序列对功率放大器友好、可重复性强。注意激励信号的带宽要覆盖滤波器通带且尽量把能量打散到各个频率这样卷积矩阵才能“混合”好稀疏向量里的各个位置。5.2 卷积矩阵的条件数怎么快速判断能不能用在实际动手之前我习惯先算一个指标感知矩阵Φ U的互相关数。定义是格拉姆矩阵G Φ̂ᵀΦ̂列归一化后的非对角元绝对值的最大值。如果这个值接近1说明至少有两个字典原子长得几乎一样恢复就会困难。对于Toeplitz结构化矩阵我一般先用随机输入做一次预测试生成一个仿真用的未知稀疏向量看OMP能不能恢复。如果恢复失败先调整输入信号再调整参数而不是上来就怪算法。这也是我想强调的一点压缩感知不是万能药它要求观测过程真的把信息混合起来。随机卷积、随机子采样都是常见办法。如果现场条件不允许你改变输入至少可以增加观测长度或者改变采样策略比如非均匀采样间隔也能有效降低测量矩阵的相关性。5.3 滤波器不是严格稀疏怎么办实际滤波器的冲激响应常常不是精确稀疏而是“高度可压缩”的大部分抽头很小但不为零。这时候直接用L₁或OMP会得到一个近似稀疏解那些小幅值抽头可能被丢掉。如果要做高精度建模需要在稀疏度和拟合残差之间权衡。我的实践是先跑一遍OMP画出残差下降曲线看前多少个抽头贡献了绝大部分能量然后在那附近截断。如果应用要求更大的动态范围可以改用加权L₁最小化第一次估计出大致位置后对大系数位置给较弱的惩罚对小系数位置给较强的惩罚迭代两三次能恢复得更准。这个做法在贝叶斯视角下相当于用了一个“重尾”先验工程上效果不错。5.4 压缩感知只适用于线性观测模型最后提醒一个边界y U h v本质上是一个线性观测假设所以直接套压缩感知只适用于线性时不变滤波器的识别。如果系统里带了非线性环节比如功放饱和、ADC量化严重、死区、迟滞那么线性模型本身就不成立第一步应该是先对信号做预处理或者把非线性项显式建模再考虑用稀疏恢复。我见过不止一个人把压缩感知套到非线性系统上失败后怀疑算法有问题。问题不在压缩感知而在建模阶段。如果你怀疑系统存在非线性可以先做一个输入输出相干性检查或者估计线性部分的残差是否还有明显结构。残差如果有结构说明模型欠拟合不是增加稀疏恢复迭代次数能解决的。6. 扩展方向从离线批处理到在线识别与进阶方法6.1 在线识别滑动窗口与动态支撑集以上都是批处理识别但很多场景需要在线跟踪时变滤波器比如无线信道随移动变化。一种思路是滑动窗口每来一个新样本丢掉最老的一个在窗口内重新做一次OMP或LASSO。这个做法直观但计算量大。更聪明的方法是用上一帧的支撑集作为先验把搜索范围限制在支撑集附近这就是动态支撑OMP的基本思想。我在滑动窗场景里试验过把上一帧支撑集作为初始集合然后用残差修正计算速度能快不少稀疏位置缓慢变化时跟踪效果也不错。如果支撑集突变就需要设置一个“重启机制”检测到残差持续偏大就重新做一次完整搜索。在线算法的核心就是平衡“相信历史”和“快速响应变化”这两件事。6.2 稀疏贝叶斯学习不想调阈值时的选择如果不喜欢OMP的停止阈值也没有先验稀疏度可以试试稀疏贝叶斯学习。SBL给每个系数加上一个零均值高斯先验但每个系数的方差参数不同通过最大似然更新这些方差方差趋近于零的项就自动被“剪掉”。它不需要知道K在字典原子强相关的场合也比OMP稳健代价是计算量高。在离线分析场景我常用SBL作为基准先用SBL跑出h再对比OMP结果两者的差异能帮助我判断观测数据质量是否足够。如果两者恢复出来的支撑集不一致大概率是数据信噪比不够或者输入激励设计有问题。这种对比方法比单纯看重建误差更直接。6.3 嵌入式实现存储是个隐形坑如果把整套流程部署到FPGA或DSP上第一个发现的问题往往是测量矩阵存不下。好在压缩感知的测量矩阵不需要每次重新生成可以用随机种子配合线性反馈移位寄存器或查表方式动态生成随机行运行时占内存很小重建时也能复现相同矩阵。第二个问题是OMP里的最小二乘求逆每次支撑集更新后重新求逆很浪费资源工程实现时通常用QR分解增量更新或者换成CoSaMP等对硬件更友好的算法。另外要注意如果目标是降低ADC采样率前端需要随机解调或随机采样架构配合软件再怎么处理也无法绕开物理采样的瓶颈。压缩感知这套方法论真正解决的是“想测却测不全”的痛点滤波器识别只是其中一个缩影。我先用OMP快速验证可行性再用更精细的算法打磨这套工作流比一上来就套一个大型模型可靠得多。如果你也做识别、估计类的问题不妨从这篇的思路开始搭一个最小实验再根据实际数据情况加余量大概率能少走不少弯路。
返回列表