快速迭代收缩-阈值算法(FISTA)

文章目录

  • 1. 数学与优化基础
  • 2. FISTA 算法的原理、推导与机制
  • 3. Matlab 实现
  • 4. FISTA 在图像处理与压缩感知中的应用
    • 4.1. 基于小波稀疏先验的图像去噪
    • 4.2 压缩感知图像重建

1. 数学与优化基础

在许多信号处理与机器学习问题中,我们希望获得稀疏解,即解向量中非零元素很少。直接以 L0 “范数” (非零元素个数)作为稀疏性度量会导致非凸优化难题。一个常用的替代是采用 L1 范数(||x||1是各元素绝对值之和)作为正则项,它是 L0的凸松弛,可以鼓励稀疏解。与 L2 正则化不同,L1 正则化对小系数给予恒定的惩罚减少,这使得较小的系数更容易被压缩到0,从而产生稀疏性。简言之,L1 范数由于在零点处的尖锐拐角(梯度不连续)会诱导解的许多分量为零。

假设你有 5 个箱子,里面分别放了 x 1 , x 2 , x 3 , x 4 , x 5 x_1, x_2, x_3, x_4, x_5 x1,x2,x3,x4,x5 个苹果。L0“范数”就是这 5 个箱子里有苹果的箱子的数量。

  • x 2 = 0 , x 4 = 0 x_2 = 0, x_4 = 0 x2=0,x4=0,其它 3 个箱子里苹果不为 0,那么 L0 “范数”就是 3。
  • 想要让 L0 变小,就要“尽量让更多箱子变成空箱子”,从而达到稀疏(空箱子越多,非零元素越少)。
  • L0“范数”本身是不连续、不光滑的(要么 0,要么 1),在数学优化中很难直接求解(优化过程不易“沿着梯度”慢慢变化,一下跳零一下跳非零)。这会导致“最小化 L0”时比较棘手。

L1 范数是一个凸函数,有很好处理的数学性质(可以使用梯度或次梯度等优化算法)。虽然它并不会像 L0 一样“明确地”只算非零数量,但在最小化 L1 范数时,有很多解会自动出现“某些元素被压到正好为 0”——这就是所谓的“稀疏解”。依然用“箱子”来打比方。

  • L1 范数就是把每个箱子里的苹果数量(绝对值)加起来之和,努力让这个总和尽量小。
  • 当某个箱子里的苹果数量比较小,L1 优化就会倾向于“干脆把这个箱子的苹果数量压到 0”,以进一步降低总和。
  • 于是就会出现类似 L0 的“有些箱子空了”的效果(稀疏解)。

L2 范数是各元素平方和的开方,即 ∥ x ∥ 2 = x 1 2 + x 2 2 + ⋯ + x n 2 \|x\|_2 = \sqrt{x_1^2 + x_2^2 + \cdots + x_n^2} x2=x12+x22++xn2 。它可以让解趋向于“总体较小”,但不会把任何一维直接压到完全 0。若还以箱子比方,L2 更像是在“平均地”减小每个箱子的苹果数量,而不会直接把其中某些箱子砍到空箱。

典型例子包括LASSO(最小绝对收缩选择算子)和**基础追踪(Basis Pursuit)**等,它们通过在最小二乘误差目标后加上 L1 范数惩罚来实现稀疏信号的估计。这种 L1 正则化问题属于凸优化,通常可转化为线性规划或二阶锥规划来求解。例如,有噪声情况下的基础追踪去噪(BPDN)和 LASSO 都考虑求解形如
min ⁡ x 1 2 ∥ A x − b ∥ 2 2 + λ ∥ x ∥ 1 , \min_x \frac{1}{2}\|Ax - b\|_2^2 + \lambda \|x\|_1, xmin21Axb22+λx1,
的凸问题,其中 λ 为权衡稀疏度的正则化参数。

像上面这样的目标函数 F ( x ) = f ( x ) + g ( x ) F(x) = f(x) + g(x) F(x)=f(x)+g(x) 中, f ( x ) = 1 2 ∥ A x − b ∥ 2 2 f(x)=\frac{1}{2}\|Ax - b\|_2^2 f(x)=21Axb22 是光滑凸函数,具有Lipschitz连续的梯度,而 g ( x ) = λ ∥ x ∥ 1 g(x)=\lambda\|x\|_1 g(x)=λx1 是连续凸函数但在0点不可微。

凸函数的一个重要性质是局部极小即全局极小,这为设计算法提供了可靠性保障。

梯度下降法是求解光滑凸优化的基本一阶方法:反复沿负梯度方向迭代。对于二次损失这样的 f ( x ) f(x) f(x),梯度为 ∇ f ( x ) = A T ( A x − b ) \nabla f(x)=A^T(Ax - b) f(x)=AT(Axb),直接的梯度迭代为 x ← x − η ∇ f ( x ) x \leftarrow x - \eta \nabla f(x) xxηf(x)。然而,当存在非光滑项 g ( x ) g(x) g(x)时(例如 L1 正则化),我们不能简单对其求梯度,而需借助次梯度近端算法

近端梯度(Proximal Gradient)方法通过引入近端算子来处理非光滑项,每步对光滑部分做梯度更新后,对非光滑部分应用一个近端映射(即求解一个带L2范数惩罚的最优问题)。对于 L1 项,其近端映射就是**软阈值(soft-thresholding)**操作,其公式为:
prox ⁡ λ ∥ ⋅ ∥ 1 ( v i ) = { 0 , ∣ v i ∣ ≤ λ , v i − λ sign ⁡ ( v i ) , ∣ v i ∣ > λ , \operatorname{prox}_{\lambda \|\cdot\|_1}(v_i) = \begin{cases}0, & |v_i| \le \lambda,\\ v_i - \lambda\,\operatorname{sign}(v_i), & |v_i| > \lambda~, \end{cases} proxλ1(vi)={0,viλsign(vi),viλ,vi>λ ,
即将向量 v v v 中每个分量按上述规则收缩。软阈值操作也通常写为 S λ ( v ) = sign ⁡ ( v ) ⋅ max ⁡ ( ∣ v ∣ − λ , 0 ) S_{\lambda}(v) = \operatorname{sign}(v)\cdot\max(|v|-\lambda,0) Sλ(v)=sign(v)max(vλ,0),把绝对值低于阈值 λ \lambda λ的系数设为0,其余系数减小 λ \lambda λ。软阈值是 L1 非光滑项的近端,因为它正是最小化 1 2 ∥ x − v ∥ 2 2 + λ ∥ x ∥ 1 \frac{1}{2}\|x-v\|_2^2 + \lambda\|x\|_1 21xv22+λx1 所得的解。这个操作在稀疏信号重建中可视为一种“去噪”步骤:减小信号中的小幅成分,同时保留/突出大幅成分,从而促进稀疏性。

2. FISTA 算法的原理、推导与机制

在引入 FISTA 前,先看其基础算法——迭代收缩阈值算法 (ISTA)。ISTA 是一种近端梯度下降方法,每次迭代包括一个梯度下降步骤和一个近端(软阈值)步骤。对目标 F ( x ) = f ( x ) + g ( x ) F(x)=f(x)+g(x) F(x)=f(x)+g(x),给定梯度Lipschitz常数为 L L L,ISTA 的每步更新可表示为:

  • 梯度步: y k = x k − 1 − 1 L ∇ f ( x k − 1 ) y_{k} = x_{k-1} - \frac{1}{L}\nabla f(x_{k-1}) yk=xk1L1f(xk1),即从上一步解 x k − 1 x_{k-1} xk1 沿负梯度方向前进一步长度 1 / L 1/L 1/L
  • 近端步: x k = prox ⁡ 1 L g ( y k ) x_k = \operatorname{prox}_{\frac{1}{L}g}(y_k) xk=proxL1g(yk),即对 y k y_k yk 应用非光滑项 g g g 的近端算子。如果 g ( x ) = λ ∥ x ∥ 1 g(x)=\lambda\|x\|_1 g(x)=λx1,这一步就是对 y k y_k yk 进行软阈值 S λ / L ( y k ) S_{\lambda/L}(y_k) Sλ/L(yk)

如此迭代产生序列 x k {x_k} xk 收敛于全局最优解。当 f f f 为Lipschitz光滑凸函数且 g g g 为凸函数时,ISTA 可保证 F ( x k ) F(x_k) F(xk) O ( 1 / k ) O(1/k) O(1/k) 的速率逼近最优值。然而,ISTA 在实践中往往收敛较慢,需要大量迭代。

快速迭代收缩-阈值算法 (FISTA) 是 Beck 和 Teboulle (2009) 提出的对 ISTA 的加速改进。它借鉴了Nesterov在1983年提出的加速梯度思想,引入了动量项来加速收敛。具体来说,FISTA并不直接对上一次的解 x k − 1 x_{k-1} xk1 进行近端梯度,而是构造一个加速序列 y k y_k yk,使其包含了前两次迭代解的线性组合信息。FISTA 的迭代步骤如下:

  1. 初始化: 取初始解 x 0 x_0 x0(可取零向量),设 y 1 = x 0 y_1 = x_0 y1=x0,并设动量参数 t 1 = 1 t_1 = 1 t1=1
  2. 循环迭代: 对于 k = 1 , 2 , 3 , … k = 1, 2, 3, \dots k=1,2,3,:
    • (近端梯度步) 先对当前辅助变量 y k y_k yk 执行与 ISTA 相同的近端梯度更新: x k = prox ⁡ 1 L g ⁣ ( y k − 1 L ∇ f ( y k ) ) . x_k = \operatorname{prox}_{\frac{1}{L}g}\!\Big(y_k - \frac{1}{L}\nabla f(y_k)\Big). xk=proxL1g(ykL1f(yk)). 对于 L1 情况,这一步仍是 x k = S λ / L ( y k − 1 L ∇ f ( y k ) ) x_k = S_{\lambda/L}\Big(y_k - \frac{1}{L}\nabla f(y_k)\Big) xk=Sλ/L(ykL1f(yk))
    • (动量更新步) 计算新的动量系数: t k + 1 = 1 + 1 + 4 t k 2 2 t_{k+1} = \frac{1 + \sqrt{1+4t_k^2}}{2} tk+1=21+1+4tk2 。然后更新加速序列: y k + 1 = x k + t k − 1 t k + 1 ( x k − x k − 1 ) . y_{k+1} = x_k + \frac{t_k - 1}{\,t_{k+1}\,}\,(x_k - x_{k-1}). yk+1=xk+tk+1tk1(xkxk1). 这一步利用了当前解 x k x_k xk和前一步解 x k − 1 x_{k-1} xk1的线性组合来得到新的搜索点 y k + 1 y_{k+1} yk+1

可以看出,与 ISTA 每次仅利用 x k − 1 x_{k-1} xk1 来迭代不同,FISTA 在 y k + 1 y_{k+1} yk+1 中加入了 ( x k − x k − 1 ) (x_k - x_{k-1}) (xkxk1)项,也就是利用最近两次迭代的解的差值作为“动量”。这种设计看似“魔法般”, 实则源自对迭代过程几何性质的精巧分析。通过恰当选择 t k t_k tk 序列( t k t_{k} tk 的递推形式来源于求解二次方程,保证后续分析中一个递推不等式的最优收敛速率),FISTA 能在理论上将收敛速度提升一个数量级。

FISTA 保持了与 ISTA 相近的每步计算复杂度,但其全局收敛速率提高到 O ( 1 / k 2 ) O(1/k^2) O(1/k2)。也就是说,达到同样精度所需的迭代次数大大减少。具体定理表明:对于 k ≥ 1 k\ge1 k1 F ( x k ) − F ( x ∗ ) ≤ 2 L ∥ x 0 − x ∗ ∥ 2 ( k + 1 ) 2 , F(x_k) - F(x^*) \le \frac{2L \,\|x_0 - x^*\|^2}{(k+1)^2}, F(xk)F(x)(k+1)22Lx0x2, 其中 x ∗ x^* x为最优解, L L L ∇ f \nabla f f的Lipschitz常数。相较之下,ISTA只有 O ( 1 / k ) O(1/k) O(1/k) 的渐进速率。因此在大量迭代后,FISTA 会显著优于 ISTA。

引入的辅助序列 y k y_k yk 可以看作在常规梯度下降基础上添加了一种“加速动量”策略,类似于物理中的动量累积,使算法在谷底附近不至于过于保守地缓慢逼近,而是带着惯性前进,从而快速逼近最优解。这与Nesterov加速梯度法在纯光滑优化中的作用类似。

下面用伪代码总结 FISTA 的核心步骤:

% 给定A, b, 正则权重lambda, Lipschitz常数L, 初始化x0
x = x0; 
y = x0;
t = 1;
for k = 1:MaxIter% 近端梯度步:梯度下降 + 软阈值grad = A'*(A*y - b);                  % 计算∇f(y) = A^T(Ay - b)x_new = sign(y - grad/L) .* max(abs(y - grad/L) - lambda/L, 0);% 动量更新步t_new = (1 + sqrt(1 + 4*t^2)) / 2;y = x_new + ((t - 1) / t_new) * (x_new - x);% 更新迭代变量x = x_new;t = t_new;
end

上述代码实现了不带回溯的 FISTA 算法框架:首先计算基于当前 y y y 的梯度下降点,然后对其应用软阈值(对应 prox ⁡ λ / L \operatorname{prox}_{\lambda/L} proxλ/L 操作),接着根据动量公式更新 y y y。经过多次迭代, x x x 将收敛到稀疏解。值得注意的是,该算法需要估计合理的 L L L(例如,可取 L = ∣ A T A ∣ L=|A^T A| L=ATA 的最大特征值)。若 L L L 不易获得,也可以在每步迭代中采用回溯线搜索调整步长,这也是 FISTA 论文中提到的变体,但基本思想不变。

FISTA 的详尽收敛性证明较为复杂,涉及构造恰当的辅助序列和能量函数。其核心在于证明 y k y_k yk 的选取使得 F ( x k ) − F ( x ∗ ) F(x_k) - F(x^*) F(xk)F(x) 符合所需的 O ( 1 / k 2 ) O(1/k^2) O(1/k2) 上界。这里不赘述完整推导,但强调两点:(1) t k t_{k} tk 的递推形式 1 + 1 + 4 t k 2 2 \frac{1+\sqrt{1+4t_k^2}}{2} 21+1+4tk2 是精心设计的,使得动量项权重逐渐减小,避免过冲;(2) FISTA 的形式也可从将 Nesterov 加速应用于 ISTA 的等价形式推导得到,一些后续研究表明FISTA可以被视为对近端梯度法在最坏情况下加速的“最优”方法。

3. Matlab 实现

假设我们要解决一个简单的压缩感知重建问题: A x ≈ b Ax \approx b Axb,其中 A A A 是测量矩阵, b b b 是观测到的信号,我们希望通过最小化 F ( x ) = 1 2 ∥ A x − b ∥ 2 2 + λ ∥ x ∥ 1 F(x)=\frac{1}{2}\|Ax-b\|_2^2 + \lambda\|x\|_1 F(x)=21Axb22+λx1 来求得稀疏解 x x x。FISTA 可高效地求解此问题。

Matlab 函数构造:

function x = FISTA_L1(A, b, lambda, L, maxIter)% 初始化x = zeros(size(A,2), 1);    % 初始解 x0y = x;                     t = 1;                     for k = 1:maxIter% 计算梯度并执行梯度下降一步grad = A' * (A * y - b);z = y - (1/L) * grad;% 执行 L1 近端(软阈值)操作x_new = sign(z) .* max(abs(z) - lambda/L, 0);% 更新动量系数和辅助变量t_new = (1 + sqrt(1 + 4 * t^2)) / 2;y = x_new + ((t - 1) / t_new) * (x_new - x);% 准备下次迭代x = x_new;t = t_new;end
end

上述函数 FISTA_L1 实现了 FISTA 的主要迭代流程。其中:

  • 初始化部分,将初始解设为全零向量,并初始化辅助变量 y = x y=x y=x 及动量参数 t = 1 t=1 t=1
  • 每次迭代首先计算当前 y y y 下的梯度 grad,对应 ∇ f ( y ) = A T ( A y − b ) \nabla f(y)=A^T(Ay - b) f(y)=AT(Ayb)
  • 然后令 z = y - (1/L)*grad,这一步是普通梯度下降的结果。
  • 接着对 z 执行软阈值:x_new = sign(z).*max(abs(z)-lambda/L, 0),得到当前迭代的稀疏估计 x k x_k xk
  • 计算新的动量系数 t_new 并更新辅助变量:y = x_new + ((t-1)/t_new)*(x_new - x),对应 y k + 1 = x k + t k − 1 t k + 1 ( x k − x k − 1 ) y_{k+1} = x_k + \frac{t_k-1}{t_{k+1}}(x_k - x_{k-1}) yk+1=xk+tk+1tk1(xkxk1)
  • 循环更新直到达到最大迭代次数(或其它收敛判据,如迭代前后 ∣ x ∣ |x| x相对变化很小)。

使用该函数时,需要提供合理的 L L L(一般可取为 A T A A^TA ATA 的最大特征值近似)。这里我们可以测试一个小例子:生成随机高斯矩阵 A A A 以及稀疏的真实信号 x true x_{\text{true}} xtrue,计算 b = A x true b=A x_{\text{true}} b=Axtrue(可加噪声),然后调用 FISTA_L1(A,b,lambda,L,maxIter) 重建,并与真值比较。

%% FISTA_L1_demo.m
% 使用 FISTA + L1 进行稀疏信号重建。clear; clc; close all;%% 准备数据
rng('default');             % 固定随机种子,方便复现
m = 80;                     % 测量数
n = 100;                    % 信号长度
A = randn(m, n);           % 随机生成测量矩阵 A% 生成一个稀疏的 x_true
k0          = 10;          % 希望的非零项数
permIdx     = randperm(n); % 随机打乱下标
supp        = permIdx(1:k0);  
x_true      = zeros(n,1);
x_true(supp)= randn(k0,1); % 在这 k0 个位置上放一些随机值% 生成观测 b
b = A * x_true;%% 设置 FISTA 参数
lambda  = 0.1;             % L1 惩罚系数
[U, S, ~] = svd(A, 'econ');
L       = max(diag(S))^2;  % 步长倒数,近似取 A 的最大奇异值平方
maxIter = 100;             % 最大迭代次数%% 调用 FISTA_L1 求解
x_est = FISTA_L1(A, b, lambda, L, maxIter);%% 比较结果
recovery_error = norm(x_est - x_true) / norm(x_true);
fprintf('重建相对误差 = %.4e\n', recovery_error);%% 作图比较 x_true 与 x_est
figure('Name', 'FISTA-L1 Reconstruction', 'NumberTitle', 'off');
plot(1:n, x_true, '-o', 'LineWidth', 1.5); 
hold on;
plot(1:n, x_est, '--', 'LineWidth', 1.5);grid on;
legend('x\_true', 'x\_est', 'Location', 'best');
xlabel('Index (n)');
ylabel('Signal Value');
title('FISTA + L1 Sparse Reconstruction');% 设置坐标轴字体
set(gca, 'FontName', 'Times New Roman', 'FontSize', 13);

用到的函数如下

function x = FISTA_L1(A, b, lambda, L, maxIter)
% FISTA_L1 使用 FISTA 迭代来求解 
%    min_x  0.5*||A*x - b||^2 + lambda * ||x||_1
%
% 输入:
%    A, b       线性系统和观测 
%    lambda     L1 惩罚系数
%    L          步长因子,通常可取近似的最大特征值 A'*A 
%    maxIter    最大迭代次数
%
% 输出:
%    x          稀疏重建后的解向量% 初始化x = zeros(size(A,2),1);  % 初始解 x0y = x;                   % 初始化辅助变量 yt = 1;                   % 动量参数 t0for k = 1:maxIter% 计算梯度 grad = A'*(A*y - b)grad = A' * (A*y - b);% 常规梯度下降一步: z = y - (1/L)*gradz = y - (1/L)*grad;% 执行软阈值(shrinkage)操作,得到 x_newx_new = sign(z) .* max(abs(z) - lambda/L, 0);% 更新动量参数 t_newt_new = (1 + sqrt(1 + 4*t^2)) / 2;% 更新辅助变量 yy = x_new + ((t - 1)/t_new) * (x_new - x);% 准备下一次迭代x = x_new;t = t_new;end
end

结果如下:

在这里插入图片描述

4. FISTA 在图像处理与压缩感知中的应用

FISTA 自提出以来已在图像处理领域的诸多逆问题中显示出强大能力,包括去去噪、欠采样重建等。其优势在于算法简单、易于实现,却又兼具接近于最优的一阶收敛速度,使其非常适合求解大规模问题。下面结合具体应用谈几点:

4.1. 基于小波稀疏先验的图像去噪

我们将把去噪问题写成
min ⁡ x 1 2 ∥ x − y ∥ 2 2 + λ ∥ W x ∥ 1 \min_{x}\;\frac12\|x - y\|_2^2 \;+\;\lambda\|W x\|_1 xmin21xy22+λWx1
其中

  • y y y 是加噪图像
  • W W W 是二维小波变换算子
  • λ \lambda λ 是稀疏惩罚参数

对于这个问题,

  • f ( x ) = 1 2 ∥ x − y ∥ 2 f(x)=\frac12\|x-y\|^2 f(x)=21xy2,梯度 ∇ f ( x ) = x − y \nabla f(x)=x-y f(x)=xy,Lipschitz 常数 L = 1 L=1 L=1
  • g ( x ) = λ ∥ W x ∥ 1 g(x)=\lambda\|W x\|_1 g(x)=λWx1,其近端算子就是对小波系数做软阈值。

实现上述去噪问题的主函数为

function x = fista_wavelet_denoise(y, lambda, waveletName, levels, maxIter)
%FISTA_WAVELET_DENOISE 用 FISTA+小波稀疏做图像去噪
%   输入:
%     y           - 加噪图像(二维灰度,double)
%     lambda      - 惩罚系数
%     waveletName - 小波类型,如 'db4'
%     levels      - 分解层数
%     maxIter     - 最大迭代次数
%   输出:
%     x           - 去噪后图像% 参数检查if nargin<5, maxIter = 200; end% 初始化xk = y;yk = xk;tk = 1;L = 1;  % f 的 Lipschitz 常数% 预分解一次(仅获取尺寸)[C0, S] = wavedec2(yk, levels, waveletName);for k = 1:maxIter% —— 1. 梯度步 —— grad = yk - y;          % ∇f(yk)zk   = yk - (1/L)*grad; % 梯度下降% —— 2. 近端步 —— 小波域软阈值 —— C    = wavedec2(zk, levels, waveletName);Cthr = soft_thresh(C, lambda/L);x_next = waverec2(Cthr, S, waveletName);% —— 3. FISTA 加速步 —— t_next = (1 + sqrt(1 + 4*tk^2))/2;y_next = x_next + ((tk-1)/t_next)*(x_next - xk);% 更新xk = x_next;yk = y_next;tk = t_next;endx = xk;
end

上面用到的软阈值函数为:

function z = soft_thresh(v, thresh)
%SOFT_THRESH 对向量 v 执行元素级软阈值z = sign(v) .* max(abs(v) - thresh, 0);
end

然后我们就可以测试这个去噪程序了,如下

%% demo_fista_denoise.m
clc; clear; close all;% 1. 读取并归一化
I = im2double(imread('cameraman.tif'));% 2. 加高斯噪声
sigma = 0.05;
yn = I + sigma*randn(size(I));% 3. 参数设置
lambda      = 0.1;       % 惩罚强度,可根据噪声调节
waveletName = 'db4';     % Daubechies4 小波
levels      = 3;         % 分解层数
maxIter     = 100;       % 迭代次数% 4. 运行 FISTA 去噪
xd = fista_wavelet_denoise(yn, lambda, waveletName, levels, maxIter);% 5. 显示对比
figure('Position',[100 100 800 300]);
subplot(1,3,1);
imshow(I); title('原始图像');
subplot(1,3,2);
imshow(yn); title(['加噪图像 (σ=',num2str(sigma),')']);
subplot(1,3,3);
imshow(xd); title('FISTA+小波 去噪结果');

在这里插入图片描述

4.2 压缩感知图像重建

压缩感知(Compressed Sensing, CS)框架中,我们以远低于奈奎斯特采样率的线性测量来重建图像。经典CS理论指出,当图像在某种域(如小波)是稀疏的时,可以通过求解 L1 正则化的凸优化精确重建图像。FISTA 正是求解这类问题的理想算法之一。举例来说,在MRI成像中采集不完备k空间数据时,常建立 min ⁡ x 1 2 ∥ A x − b ∥ 2 + λ ∥ W ( x ) ∥ 1 \min_x \frac{1}{2}\|Ax-b\|^2 + \lambda \|W(x)\|_1 minx21Axb2+λW(x)1 W ( x ) W(x) W(x)表示小波变换系数)模型来重建图像;实践表明利用FISTA求解该模型能够在保持高重建质量的同时大幅减少迭代时间。即使在深度学习蓬勃发展的今天,研究者仍关注传统CS重建的潜力,通过合理优化,经典L1-范数重建在某些情况下仍然有竞争力。这也证明了FISTA等算法在成像领域的持久价值。

我们以最简单的“稀疏先验+小波变换”为例,解决
min ⁡ x 1 2 ∥ Φ x − y ∥ 2 2 + λ ∥ W x ∥ 1 , \min_{x}\;\frac12\|\Phi x - y\|_2^2 \;+\;\lambda\|W x\|_1, xmin21∥Φxy22+λWx1,
其中

  • x ∈ R N x\in\mathbb{R}^N xRN 是待重建的灰度图像(展开成向量),
  • Φ ∈ R M × N \Phi\in\mathbb{R}^{M\times N} ΦRM×N 是测量矩阵( M ≪ N M\ll N MN),
  • y ∈ R M y\in\mathbb{R}^M yRM 是测量向量,
  • W W W W − 1 W^{-1} W1 分别是二维小波变换算子和其逆算子。

实现上述稀疏重建的主函数为

function x_rec = fista_cs_wavelet(Phi, y, lambda, waveletName, levels, imgSize, opts)
%FISTA_CS_WAVELET 用 FISTA+小波稀疏做压缩传感重建
%  输入:
%    Phi         - M×N 测量矩阵
%    y           - M×1 测量向量
%    lambda      - 稀疏惩罚系数
%    waveletName - 小波类型,如 'db4'
%    levels      - 小波分解层数
%    imgSize     - [h, w] 原图高宽
%    opts        - 可选结构体
%        .maxIter (默认 200)
%        .tol     (默认 1e-4)
%  输出:
%    x_rec       - 重建后图像(h×w)if nargin<7, opts = struct(); endif ~isfield(opts,'maxIter'), opts.maxIter = 200; endif ~isfield(opts,'tol'),     opts.tol     = 1e-4; end% 初始化N      = prod(imgSize);xk     = zeros(N,1);yk     = xk;tk     = 1;L      = norm(Phi,2)^2;    % Lipschitz 常数% 预计算小波分解结构[~, S] = wavedec2(reshape(yk,imgSize), levels, waveletName);for k = 1:opts.maxIter% 1) 梯度下降grad = Phi'*(Phi*yk - y);z    = yk - (1/L)*grad;% 2) 小波软阈值Cz   = wavedec2(reshape(z,imgSize), levels, waveletName);Cthr = soft_thresh(Cz, lambda/L);x_next = waverec2(Cthr, S, waveletName);x_next = x_next(:);% 3) FISTA 加速t_next = (1 + sqrt(1 + 4*tk^2)) / 2;y_next = x_next + ((tk - 1)/t_next)*(x_next - xk);% 收敛判断if norm(x_next - xk) < opts.tolxk = x_next; break;end% 更新xk = x_next;yk = y_next;tk = t_next;end% 输出重建图像x_rec = reshape(xk, imgSize);
end

然后我们就可以用于演示一个采样率为50%的图像重建,

% demo_fista_cs.m
clc; clear; close all;% 1. 原始图像及展平
I        = im2double(imread('cameraman.tif'));
I        = imresize(I, 0.25);
imgSize  = size(I);
x_true   = I(:);% 2. 构造测量矩阵 Φ(随机高斯或 0/1 伯努利)
M        = round(0.5 * numel(x_true));  % 50% 采样率
Phi      = randn(M, numel(x_true));
Phi      = bsxfun(@rdivide, Phi, sqrt(sum(Phi.^2,2)));  % 每行归一化% 3. 生成测量 y
noise_sigma = 1e-3;
y           = Phi * x_true + noise_sigma*randn(M,1);% 4. 重建参数
lambda      = 0.01;
waveletName = 'db4';
levels      = 3;
opts.maxIter= 300;
opts.tol    = 1e-5;% 5. 调用 FISTA-CS 重建
tic;
x_rec = fista_cs_wavelet(Phi, y, lambda, waveletName, levels, imgSize, opts);
toc;% 6. 显示结果
figure('Position',[100 100 900 300]);
subplot(1,2,1);
imshow(I); title('原始图像');
subplot(1,2,2);
imshow(x_rec,[]); title('FISTA-CS 重建');

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/77489.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微服务之间打通用户上下文

微服务之间打通用户上下文 打通上下文步骤需求&#xff1a;1、gateway网关登录拦截器&#xff1a;【LoginFilter】解释&#xff1a;代码 2、SpringMVC全局处理&#xff1a;【GlobalConfig】解释&#xff1a;代码&#xff1a; 3、自定义登录拦截器&#xff1a;【LoginIntercepto…

Hutool之DateUtil:让Java日期处理变得更加简单

前言 在Java开发中&#xff0c;日期和时间的处理是一个常见问题。为了简化这个过程&#xff0c;许多开发者会使用第三方工具包&#xff0c;如Hutool。Hutool是一个Java工具包&#xff0c;提供了许多实用的功能&#xff0c;其中之一就是日期处理。日期时间工具类是Hutool的核心包…

ES中常用的Query和查询作用,以及SpringBoot使用实例

ES中常用的Query和查询作用&#xff0c;以及 SpringBoot 使用实例 文章目录 ES中常用的Query和查询作用&#xff0c;以及 SpringBoot 使用实例MatchAllQueryTermQueryBoolQueryRangeQueryMatchQueryMultiMatchQueryTermsQueryPrefixQueryWildcardQueryRegexpQueryFuzzyQueryDis…

Flutter 自定义插件基础

1、Flutter插件是什么&#xff1f;官方插件库 在开发Flutter应用过程中会涉及到平台相关接口调用&#xff0c;例如数据库操作、相机调用、外部浏览器跳转等业务场景。其实Flutter自身并不支持直接在平台上实现这些功能&#xff0c;而是通过插件包接口去调用指定平台API从而实现…

极狐GitLab 外部授权控制机制是怎样的?

极狐GitLab 是 GitLab 在中国的发行版&#xff0c;关于中文参考文档和资料有&#xff1a; 极狐GitLab 中文文档极狐GitLab 中文论坛极狐GitLab 官网 外部授权控制 (BASIC SELF) 在高度控制的环境中&#xff0c;访问策略可能需要由外部服务控制&#xff0c;该服务允许基于项目…

Linux系统之----冯诺依曼结构

1.简要描述 冯诺依曼体系结构是现代计算机的基本设计思想&#xff0c;其核心理念是将计算机的硬件和软件统一为一个整体&#xff0c;通过存储程序的方式实现计算。冯诺依曼体系结构的核心思想是通过存储程序实现自动计算&#xff0c;其五大部件协同工作&#xff0c;奠定了现代…

【八股】计算机网络

1 概述 1.1 网络的网络 网络把主机连接起来,而互连网(internet)是把多种不同的网络连接起来,因此互连网是网络的网络。而互联网(Internet)是全球范围的互连网。 1.2 ISP 互联网服务提供商 ISP 可以从互联网管理机构获得许多 IP 地址,同时拥有通信线路以及路由器等联…

基于VS Code 为核心平台的python语言智能体开发平台搭建

以下是基于 VS Code 为核心平台&#xff0c;整合 Node-RED、Gradio、Docker Desktop 的智能体可视化开发平台优化方案&#xff0c;聚焦工具链深度集成与开发效率提升&#xff1a; 一、核心架构设计 #mermaid-svg-f8l9kYPAlJ2TlpGF {font-family:"trebuchet ms",verd…

STM32G0单片机自带RTC

STM32有个自带RTC外设&#xff0c;外接32.768KHz的晶振后可得到相对精确的计时功能。 实测了一个一小时快个1秒多。 1 cubeMX设置了RTC后自动生成的初始化代码如下 static void MX_RTC_Init(void) {/* USER CODE BEGIN RTC_Init 0 *//* USER CODE END RTC_Init 0 */RTC_TimeT…

细说STM32单片机FreeRTOS任务管理API函数及多任务编程的实现方法

目录 一、FreeRTOS任务管理API函数 1、任务管理API函数 2、获取任务的句柄 &#xff08;1&#xff09;函数xTaskGetCurrentTaskHandle() &#xff08;2&#xff09;函数xTaskGetIdleTaskHandle() &#xff08;3&#xff09;函数xTaskGetHandle() 3、单个任务的操作 &a…

星露谷物语 7000+ 大型MOD整合包

衣服美化、家具美化、地图美化、人物肖像美化 全地图装修存档、人物美化、扩展包、环境美化、家具、动植物、通用前置包、新增NPC、功能、服装发饰妆 帽子发型农场小镇美化大型玩法拓展实用功能mod 动漫人物形象MOD 地点/动物/地图/功能/机械/家具/建筑/界面美化/扩展/农场/食谱…

C++ `unique_ptr` 多线程使用

C unique_ptr 多线程使用 一、核心结论 操作同一个 unique_ptr&#xff1a;必须加锁&#xff08;所有权转移是非原子操作&#xff09;访问被管理对象&#xff1a;若对象非线程安全&#xff0c;仍需额外同步独立 unique_ptr 实例&#xff1a;不同线程操作不同实例时无需加锁 二…

Android audio系统六 AudioEffect音效加载

对于Android系统智能硬件设备&#xff0c;音效处理的实现方式有以下几种&#xff1a; AudioEffect – android系统音效处理 优点&#xff1a;纯软件实现&#xff0c;移植调试简单方便 缺点&#xff1a;cpu上运行&#xff0c;容易因为资源竞争而出现卡顿 DSP/ADSP – 数字信号处…

深度学习总结(21)

超越基于常识的基准 除了不同的评估方法&#xff0c;你还应该了解的是利用基于常识的基准。训练深度学习模型&#xff0c;你听不到也看不到。你无法观察流形学习过程&#xff0c;它发生在数千维空间中&#xff0c;即使投影到三维空间中&#xff0c;你也无法解释它。唯一的反馈…

接口自动化测试(二)

一、接口测试流程&#xff1a;接口文档、用例编写 拿到接口文档——编写接口用例以及评审——进行接口测试——工具/自动化框架进行自动化用例覆盖(70%)——输出测试报告 自动化的目的一般是为了回归 第一件事情&#xff1a;理解需求&#xff0c;学会看接口文档 只需要找到我…

Linux上位机开发实践(以MCU小系统入门嵌入式电路)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 一直都主张嵌入式软件工程师&#xff0c;也要会做一点电路设计的工作。哪怕自己做的是嵌入式linux上层开发&#xff0c;一个会硬件设计&#xff0c…

浏览器的存储机制 - Storage

浏览器的存储机制 - Storage 前言一、核心概念与区别二、常用 API1、存储数据&#xff08;setItem(key, value)&#xff09;2、 获取数据&#xff08;getItem(key)&#xff09;3、删除单个数据&#xff08;removeItem(key)&#xff09;4、清空所有数据&#xff08;clear()&…

考研单词笔记 2025.04.18

chance n机会&#xff0c;风险&#xff0c;冒险&#xff0c;可能性&#xff0c;巧合&#xff0c;意外a偶然的&#xff0c;意外的 opportunity n机会&#xff0c;时机 crisis n危机&#xff0c;危急关头 the economic crisis 经济危机 danger n危险&#xff0c;可能性&#…

第三方API——Spring Boot 集成阿里云短信发送功能

目录 一. 创建阿里云OSS服务并获取密钥&#xff0c;开通短信服务 1.1 注册阿里云服务器 1.2 开通短信服务 1.3 创建对象存储OSS服务 1.4 RAM用户授权短信权限 1.5 新增用户并授权用户短信权限 1.6 获取 AccessKey ID 和 AccessKey Secret 二. 创建项目集成短信发送 2.1…

b站PC网页版视频播放页油猴小插件制作

文章目录 前言需求分析实施观察页面起始渲染编码效果展示 总结 前言 新手上路,欢迎指导 需求分析 想要一个简约干净的界面,需要去除推荐栏和广告部分. 想要自由调节视频播放速率,需要在视频控制栏加一个输入框控制视频倍速 实施 观察页面起始渲染 因为要使用MutationObse…