简介:压缩感知稀疏贝叶斯算法代码包,专门面向信号处理与压缩感知研究方向的工程师、高校学生和科研人员,完整提供SBL、TSBL与TMSBL三种贝叶斯重构算法的Matlab实现,可解决欠采样条件下稀疏信号恢复与动态结构建模问题,特别适合做算法对比和经验调参的读者。包内共15个文件,以11个Matlab核心源码为主体,附带PDF和Word版的“三分钟上手指南”、ReadMe提示文档,压缩包整体仅479KB,轻量且目录内容清晰。资源已有929人学习/下载,作者自述已测试可用,属于高性价比的小型算法工具箱。除了SBL/TSBL/TMSBL主函数之外,包中还有多个demo示例、性能对比脚本和逐段用法说明,方便读者快速重启实验,亦可结合图像处理、医学成像、通信信号检测等实际任务进行二次开发。
1. 压缩感知重构:为什么稀疏贝叶斯算法值得自己跑一遍代码
在雷达成像、核磁共振稀疏重建这类场景里,采样率压到奈奎斯特定律的 20% 以下仍能恢复出完整信号,这个反直觉的结论在实际工程中经常被质疑。但真正在降采样数据上做过重构的人会告诉你,前提是信号在某组基底下足够稀疏,且重构算法对支撑集的选择足够稳定。传统贪婪算法如 OMP、CoSaMP 在低信噪比下容易错选原子,误差会随迭代累积;而压缩感知稀疏贝叶斯算法(Sparse Bayesian Learning, SBL)把稀疏性编码成层次先验,通过贝叶斯推理同时估计支撑集、超参数和噪声方差,在相干字典和低信噪比条件下往往比 L1 范数类方法更稳。这份源码包恰好把 SBL、TSBL、TMSBL 三个层次的 Matlab 实现放在一起,从单测量向量到时间序列再到多尺度时序,足够串起一条从理论到横向对比的完整线索,适合想搞清楚贝叶斯重构内在机制、又不想只调工具箱的人。
2. SBL 与 MSBL 的贝叶斯推导:从单测量向量到多测量向量
2.1 稀疏贝叶斯学习中的层次先验与超参数估计
SBL 的核心并不是直接对信号施加 L1 范数约束,而是为每个信号分量引入独立的方差超参数。对单测量向量模型y = Φx + n,信号x的每个元素x_i服从零均值高斯先验,方差为γ_i,而每个γ_i又服从 Inverse-Gamma 超先验。这种两层结构是稀疏贝叶斯算法的关键:当某个γ_i在迭代中趋于零时,对应的x_i也会被压到零附近,从而实现自动稀疏化。
这个方法在压缩感知里的名字是 SBL,但在多测量向量(MMV)模型里,Y = ΦX + N,每一列是一个时间快拍,此时需要所有列共享同一个支撑集。MSBL.m 实现了这一扩展。代码里不再单独估计每个时刻的方差,而是为每一行信号引入一个超参数γ_i,代表该行在所有快拍上的共同稀疏性。
% MSBL 核心更新的简化片段,来自 MSBL.m 的 EM 风格迭代 for iter = 1:maxIter % 由当前 X 和 Gamma 计算后验协方差 Sigma = inv(Phi' * Phi / sigma2 + diag(1 ./ gamma)); % 后验均值 Mu = Sigma * Phi' * Y / sigma2; % 更新超参数 gamma,即每行信号能量的均值 gamma = mean(Mu.^2, 2) + diag(Sigma); % 更新噪声方差(省略细节,按残差能量估计) sigma2 = norm(Y - Phi * Mu, 'fro')^2 / (M * T); end上面这段是去掉了边界条件处理的简化逻辑,实际 MSBL.m 里还包含对sigma2的 MAP 估计和数值保护。gamma更新公式里第一项mean(Mu.^2, 2)是后验均值的能量,第二项diag(Sigma)是后验方差,二者一起构成二阶矩估计,保证超参数收敛路径平稳。sigma2的更新需要除的是M * T,即测量维度乘以快拍数,因为残差是矩阵而非向量。
2.2 MFOCUSS 与 MSBL 的对比:快速算法与贝叶斯算法的取舍
压缩包里的 MFOCUSS.m 是 FOCUSS 族算法的稀疏扩展,它和 MSBL 在迭代格式上很相似,最大的区别在于 MFOCUSS 直接把权重矩阵W作为变量反复调整,而 MSBL 从贝叶斯后验推导出同一形式的更新式。实际运行时,MFOCUSS 的收敛速度更快,但对初值更敏感;MSBL 多了一层超参数平滑,收敛略微慢一点,却更抗噪。
2.3 信号重构中的参数初始化与收敛控制
使用 MSBL.m 时,通常只需关心三个参数:测量矩阵Phi、观测矩阵Y和迭代停止条件。源码里maxIter默认在 100 到 300 之间,停止条件除最大迭代次数外,还会判断前后两次gamma变化的相对误差是否小于某个阈值。需要特别注意的是Phi应该做列归一化,否则不同列的原子能量差异会直接影响gamma的初始估计,导致支撑集选择偏向高能列。常见做法是在预处理时计算Phi_norm = Phi ./ vecnorm(Phi),稀疏系数恢复后在对应维度上乘回原尺度。
3. TSBL 时间稀疏贝叶斯:块稀疏先验与时序相关性的引入
3.1 时间连续性先验的建模思路
TSBL 解决的是多测量向量模型里时间维度被忽略的问题。在 MMV 模型里,各列之间只是共享支撑集,但时间序列数据往往还满足相邻时刻的幅值变化是平滑的。TSBL 在 SBL 的基础上引入了块内相关矩阵B,对每一行信号施加 Matrix Gaussian 先验,行的稀疏性由gamma_i控制,列之间的时序相关性由B矩阵编码。
% TSBL 迭代中 B 矩阵与 gamma 的交替更新 for iter = 1:maxIter % 更新后验协方差(稀疏贝叶斯学习中的核心) Sigma = inv( (1/sigma2) * (Phi'*Phi) + diag(1./gamma) ); Mu = (1/sigma2) * Sigma * Phi' * Y; % 学习时间相关性矩阵,通过后验均值和协方差重构 B = ( (Mu'*Mu) / L + Sigma ) / T; B = B / trace(B) * L; % 归一化,保持尺度稳定 gamma = sum(Mu.^2, 2)/T + diag(Sigma); end上式中Sigma的维度是信号行数乘信号行数,与常规 SBL 一致;B的维度是时间快拍数乘时间快拍数。B = B / trace(B) * L这行是做迹归一化,防止时间相关矩阵的尺度漂移导致gamma的更新失去约束。trace(B)相当于矩阵的总能量,把它固定为L(信号维度),相当于把时间维度的能量总量约束住了。
3.2 TSBL 相对于 SBL 的重构精度提升
考虑一个简单的仿真:随机生成 20 个传感器的频域信号,每个传感器在 120 个时间快拍上共享稀疏支撑集,但幅值随时间线性变化。分别用 MSBL 和 TSBL 重构,TSBL 的重构误差通常会低一个数量级甚至更多。原因在于 MSBL 把每一列当成独立样本,行相关性信息完全丢失;而 TSBL 显式地用B矩阵捕获了时间结构。需要特别注意B矩阵只在信号幅值连续变化的场景下有增益,如果时间维上信号完全是随机切换的,B反而会成为约束,此时不如退回 MSBL。
3.3 参数选择的边界条件
demo_time_varying.m里展示的就是时变场景,运行前可以确认B矩阵的初始化方式。源码中B初始化为单位阵,这相当于假设时间维度上各快拍不相关,迭代后B会逐步学习出真实的相关结构。时间快拍数T较小时,B的估计方差会偏大,可以考虑把B初始化为 Toeplitz 结构或加上对角加载项避免奇异。
4. TMSBL 多尺度时序贝叶斯重构的核心改进
4.1 多尺度稀疏模型中矩阵先验的作用
TMSBL 的全称是 Temporal Multiple-Scale Sparse Bayesian Learning,它在 TSBL 的基础上进一步强调B矩阵的实际含义:时间维上的相关结构可能不止一种尺度。TSBL 强制所有行共用同一个B,TMSBL 则允许部分行共享相关结构、部分行独立,从而在模型层面实现了多尺度。在实现上,TMSBL.m 通过交替更新gamma和B,并在B的估计上做自动收缩,避免过拟合。
% TMSBL 在 TSBL 基础上的罚函数调整 for iter = 1:maxIter % 后验均值与协方差,公式同 TSBL Sigma = inv( A + diag(gamma .* invB_diag) ); Mu = Sigma * Phi' * Y / sigma2; % 引入对角加载的 B 更新,数值上更稳定 B = (Mu' * Mu) / L + Sigma / T + lambda * eye(T); B = B / trace(B) * L; gamma = sum(Mu.^2, 2)/T + diag(Sigma); endlambda * eye(T)是对角加载项,lambda取 1e-4 到 1e-2 之间即可,作用是防止B矩阵在快拍数较少时退化成低秩矩阵。如果B低秩,invB会爆炸,导致gamma更新出现 NaN。在低快拍数场景中,这个对角加载项几乎是必须的,源码里也对这一项做了自适应调整。
4.2 TMSBL.m 的代码走读与文件组织
整个压缩包的解压后目录以TMSBL_code为根,核心文件是MSBL.m、TSBL.m、TMSBL.m三个算法文件,加上一组以demo_前缀命名的测试脚本。ReadMe.txt解释了基本调用方式;Master the Usage of TSBL in 1 Minute.pdf和Master the Usage of TMSBL in 3 Minutes.docx是逐行说明,适合先跑通再细看。
三个算法的调用签名高度一致,基本形式都是[X, gamma] = TMSBL(Phi, Y, options)。其中Phi为测量矩阵,Y为多快拍观测矩阵,options里可配置maxIter、tol、learnB等参数。learnB设为 0 时,TMSBL 会退化为 MSBL,这可以用来做对比实验。
4.3 三个算法与 demo 脚本的对应关系
demo.m是总入口,依次演示三个算法的基本用法;demo_identicalVector.m验证相同波形条件下的对比;demo_time_varying.m专门测试时变信号;demo_fig3.m、demo_fig6_SNR10.m、demo_fig8.m分别复现论文里的图 3、信噪比 10dB 下的图 6 以及图 8。perfSupp.m是支撑集正确率的评估函数,返回预测支撑集与真实支撑集的匹配度。跑demo_fig6_SNR10.m时如果画面出现横线状的错误峰,通常是因为B矩阵估计过拟合,回到对角加载参数的调整上即可。
5. demo 脚本复现实验与支撑集正确率验证
demo_identicalVector.m给出的是一组完全相同时间波形的合成数据:信号共有 20 个通道、100 个快拍,稀疏度为 5,测量矩阵由随机高斯矩阵生成,信噪比设置在 10dB 左右。运行前脚本会打印当前支撑集的重构结果。切换算法的方式是注释掉MSBL(Phi, Y, options),换成TSBL(Phi, Y, options)或TMSBL(Phi, Y, options),无需修改其他代码。
% demo_identicalVector.m 中的核心评估逻辑 X_est = MSBL(Phi, Y, options); correct_rate = perfSupp(X_est, X_true, thr); fprintf('Support recovery rate: %.2f%%\n', correct_rate * 100);perfSupp的第三个参数thr是支撑集判定阈值,通常取 1e-3,即信号幅值大于该值的索引视为支撑集元素。该函数只做索引集合的比对,不感知幅值恢复精度,因此在评估时还要单独计算norm(X_est - X_true, 'fro') / norm(X_true, 'fro')。实操中一个有用技巧是:跑完 MSBL 之后,把得到的gamma向量按降序排列,观察排在稀疏度之后的值是否出现数量级跳变。如果跳变明显,说明支撑集选择稳定;如果只是缓慢下降,说明测量矩阵相干性过高,这时改跑 TSBL,借助时间维的相关性可以显著改善排序分布。
demo_fig6_SNR10.m提供了 SNR=10dB 的精确条件,我一般会在这个脚本上反复测试B矩阵的两组配置:learnB=1时让算法自由学习时间相关结构;learnB=0时退化为 SBL 基线。对比两条重构误差曲线,就能直观判断当前数据到底适不适合上 TSBL 或 TMSBL。如果误差差距在 5% 以内,说明时间相关性并不强,直接用 MSBL 反而是最简单的选择;如果差距超过 30%,说明B矩阵确实捕获了关键结构,值得花精力调对角加载系数和迭代收敛阈值。通过这种量化验证方式,这三个算法就不再是黑盒代码,而是能针对不同信号形态做出合理选型的工具。
本文还有配套的精品资源,点击获取