matching pursuit笔记

本文详细介绍了非负正交匹配追踪(NOMP)算法,包括其基本原理、步骤以及与正交匹配追踪(OMP)的区别。NOMP通过约束组合系数为非负数来提高算法的稳定性和准确性。文章提供了NOMP的Python实现,并展示了如何逐步逼近输入特征向量的分解。此外,还提到了匹配追踪的其他变种,如标准的OMP和全逆向正交匹配追踪(full backward orthogonality)的概念。

给定一个 Hilbert space 中的向量 f f f 和一个称为字典的向量组 D = { x 1 , … , x n } D=\{x_1,\dots,x_n\} D={x1,,xn},且 ∥ x i ∥ = 1 \parallel x_i \parallel=1 xi=1,想用 D D D 中的某些元素的组合尽量逼近 f f f,反过来说,是将 f f f 拆成 D D D 中元素的组合。

Matching Pursuit

MP [1] 的思路是递归地增量逼近。当随便拿一个 x i x_i xi 近似时,MP 只取 f f f x i x_i xi 上正交投影,此时 f 可以拆成: f = f ^ + R f = < f , x i > x i + R f \begin{aligned} f&=\hat f + Rf \\ &=<f,x_i>x_i + Rf \end{aligned} f=f^+Rf=<f,xi>xi+Rf 其中 f ^ \hat f f^ 是近似值, < ⋅ , ⋅ > <\cdot,\cdot> <,> 是内积, R f Rf Rf 表示 f ^ \hat f f^ f f f 之间的误差。
orthogonal projection

为了使近似效果最好,应选一个使得 ∣ < f , x i > ∣ |<f,x_i>| <f,xi> 最大的 x i x_i xi,[1] 中说有时需要将这个限制松弛成 ∣ < f , x i > ∣ ≥ α ⋅ sup ⁡ j ∣ < f , x j > ∣ , 0 < α < 1 |<f,x_i>|\geq\alpha\cdot\sup_j|<f,x_j>|,\quad 0<\alpha<1 <f,xi>αjsup<f,xj>,0<α<1

选定上述的最优 x i x_i xi 之后,可以继续用 D D D 拆误差 R f Rf Rf R f = < R f , x i ′ > x i ′ + R ( R f ) Rf=<Rf,x_{i'}>x_{i'}+R(Rf) Rf=<Rf,xi>xi+R(Rf) 于是原来的近似可以修正成: f = < f , x i > x i + R f = < f , x i > x i + < R f , x i ′ > x i ′ ⏟ f ^ + R ( R f ) \begin{aligned} f &= <f,x_i>x_i + Rf \\ &=\underbrace{<f,x_i>x_i + <Rf,x_{i'}>x_{i'}}_{\hat f} + R(Rf) \end{aligned} f=<f,xi>xi+Rf=f^ <f,xi>xi+<Rf,xi>xi+R(Rf) 此时有 ∥ R f ∥ 2 = ∣ < R f , x i ′ > ∣ 2 + ∥ R ( R f ) ∥ 2 ≥ ∥ R ( R f ) ∥ 2 \parallel Rf \parallel^2=|<Rf,x_{i'}>|^2+\parallel R(Rf) \parallel^2\geq\parallel R(Rf) \parallel^2 Rf2=<Rf,xi>2+R(Rf)2R(Rf)2 即近似误差更小了。这可以导出一个迭代算法,表示成: f ≈ f ^ m = ∑ i = 1 m < R i − 1 f , x σ i > x σ i + R m f f\approx\hat f_m=\sum_{i=1}^m<R_{i-1}f,x_{\sigma_i}>x_{\sigma_i}+R_mf ff^m=i=1m<Ri1f,xσi>xσi+Rmf 其中 x σ i x_{\sigma_i} xσi 是第 i 步选的向量, R i f R_if Rif 是第 i 步的误差, R 0 f = f R_0f=f R0f=f

V = span { x 1 , … , x n } ‾ V=\overline{\text{span}\{x_1,\dots,x_n\}} V=span{x1,,xn} D D D 张成的空间(closed linear span of the dictionary vectors),则当 V = H V=H V=H 时, f f f 必能被 D D D 组合得出即 lim ⁡ m → + ∞ f ^ m = f lim ⁡ m → + ∞ R m f = 0 \lim_{m\rightarrow + \infty}\hat f_m=f \\ \lim_{m\rightarrow + \infty}R_mf=0 m+limf^m=fm+limRmf=0

注意,MP 中每个 x i x_i xi 允许多次被选中。

Orthogonal Matching Pursuit

OMP [2] 表示 MP 只保证 R i f ⊥ x σ i R_if \perp x_{\sigma_i} Rifxσi,想收敛可能需要很多步迭代。当限制迭代次数 m m m 时,MP 得出的结果不是最优的。

OMP 增加了对 R i f R_if Rif 的约束,使其与所有 x σ j ( j = 1 , … , i − 1 ) x_{\sigma_j}(j=1,\dots,i-1) xσj(j=1,,i1) 都正交(full backward orthogonality)。

假设在第 k 步的拆分为: f = ∑ i = 1 k a i k x σ i + R k f (1) f=\sum_{i=1}^ka^k_ix_{\sigma_i}+R_kf \tag{1} f=i=1kaikxσi+Rkf(1) 其中 a i k a^k_i aik 是第 k 步中的组合系数, R k f R_kf Rkf 满足 R k f ⊥ x σ j , j = 1 , … , k R_kf\perp x_{\sigma_j},\quad j=1,\dots,k Rkfxσj,j=1,,k,即 full backward orthogonality。在第 k + 1 步,按 MP 的方式选 x σ k + 1 x_{\sigma_{k+1}} xσk+1,新的拆分为: f = ∑ i = 1 k + 1 a i k + 1 x σ i + R k + 1 f (2) f=\sum_{i=1}^{k+1}a^{k+1}_ix_{\sigma_i}+R_{k+1}f \tag{2} f=i=1k+1aik+1xσi+Rk+1f(2) 约束 R k + 1 f R_{k+1}f Rk+1f 同样满足 full backward orthogonality。为了确定系数 a i k + 1 a^{k+1}_i aik+1,先将 x σ k + 1 x_{\sigma_{k+1}} xσk+1 同样用 { x σ 1 , … , x σ k } \{x_{\sigma_1},\dots,x_{\sigma_k}\} {xσ1,,xσk} 拆成: x σ k + 1 = ∑ i = 1 k b i k x σ i + γ k (3) x_{\sigma_{k+1}}=\sum_{i=1}^kb^{k}_ix_{\sigma_i}+\gamma_k\tag{3} xσk+1=i=1kbikxσi+γk(3) 其中 b i k b^k_i bik γ k \gamma_k γk 都是用某种方法算出来的。 γ k \gamma_k γk x σ k + 1 x_{\sigma_{k+1}} xσk+1 中用 { x σ 1 , … , x σ k } \{x_{\sigma_1},\dots,x_{\sigma_k}\} {xσ1,,xσk} 组合不出的成分,所以 γ k ⊥ x σ j , j = 1 , … , k \gamma_k\perp x_{\sigma_j},\quad j=1,\dots,k γkxσj,j=1,,k。将 (3) 代入 (2) 与 (1) 对比系数: f = ∑ i = 1 k a i k x σ i ⏟ 1 + R k f ⏟ 2 = ∑ i = 1 k a i k + 1 x σ i + a k + 1 k + 1 x σ k + 1 + R k + 1 f = ∑ i = 1 k a i k + 1 x σ i + a k + 1 k + 1 [ ∑ j = 1 k b j k x σ j + γ k ] + R k + 1 f = ∑ i = 1 k [ a i k + 1 + a k + 1 k + 1 ⋅ b i k ] x σ i ⏟ 1 + a k + 1 k + 1 γ k + R k + 1 f ⏟ 2 \begin{aligned} f & =\underbrace{\sum_{i=1}^ka^k_ix_{\sigma_i}}_{1}+\underbrace{R_kf}_{2} \\ &=\sum_{i=1}^{k}a^{k+1}_ix_{\sigma_i}+a^{k+1}_{k+1}x_{\sigma_{k+1}}+R_{k+1}f \\ &=\sum_{i=1}^{k}a^{k+1}_ix_{\sigma_i}+a^{k+1}_{k+1}\left[\sum_{j=1}^kb^k_jx_{\sigma_j}+\gamma_k\right]+R_{k+1}f \\ &=\underbrace{\sum_{i=1}^{k}[a^{k+1}_i+a^{k+1}_{k+1}\cdot b^k_i]x_{\sigma_i}}_{1}+\underbrace{a^{k+1}_{k+1}\gamma_k+R_{k+1}f}_{2} \end{aligned} f=1 i=1kaikxσi+2 Rkf=i=1kaik+1xσi+ak+1k+1xσk+1+Rk+1f=i=1kaik+1xσi+ak+1k+1[j=1kbjkxσj+γk]+Rk+1f=1 i=1k[aik+1+ak+1k+1bik]xσi+2 ak+1k+1γk+Rk+1f 所以 a i k + 1 = a i k − a k + 1 k + 1 ⋅ b i k R k + 1 f = R k f − a k + 1 k + 1 ⋅ γ k a^{k+1}_i=a^k_i-a^{k+1}_{k+1}\cdot b^k_i \\ R_{k+1}f=R_kf-a^{k+1}_{k+1}\cdot\gamma_k aik+1=aikak+1k+1bikRk+1f=Rkfak+1k+1γk 只要确定 a k + 1 k + 1 a^{k+1}_{k+1} ak+1k+1 就可以。又由 R k + 1 f ⊥ x σ k + 1 R_{k+1}f\perp x_{\sigma_{k+1}} Rk+1fxσk+1 的限制,有: 0 = < R k + 1 f , x σ k + 1 > = < R k f , x σ k + 1 > − a k + 1 k + 1 ⋅ < γ k , x σ k + 1 > \begin{aligned} 0&=<R_{k+1}f,x_{\sigma_{k+1}}> \\ &=<R_kf,x_{\sigma_{k+1}}>-a^{k+1}_{k+1}\cdot<\gamma_k,x_{\sigma_{k+1}}> \end{aligned} 0=<Rk+1f,xσk+1>=<Rkf,xσk+1>ak+1k+1<γk,xσk+1> 所以 a k + 1 k + 1 = < R k f , x σ k + 1 > < γ k , x σ k + 1 > a^{k+1}_{k+1}=\frac{<R_kf,x_{\sigma_{k+1}}>}{<\gamma_k,x_{\sigma_{k+1}}>} ak+1k+1=<γk,xσk+1><Rkf,xσk+1>

这样在保证 R k + 1 f ⊥ x σ k + 1 R_{k+1}f\perp x_{\sigma_{k+1}} Rk+1fxσk+1 的限制的同时,因为 R k f ⊥ x σ j ∧ γ k ⊥ x σ j R_kf\perp x_{\sigma_j}\wedge \gamma_k\perp x_{\sigma_j} Rkfxσjγkxσj,所以 R k + 1 f = R k f − γ k ⊥ x σ j , j = 1 , … , k R_{k+1}f=R_kf-\gamma_k\perp x_{\sigma_j},\quad j=1,\dots,k Rk+1f=Rkfγkxσj,j=1,,k,所以 R k + 1 f R_{k+1}f Rk+1f 也满足 full backward orthogonality。

Non-negative Orthogonal Matching Pursuit

NOMP [3] 限制组合系数非负,说是可以提高稳定性。

[4] 是一份参考实现。下面是我改写的版本,跟 [4] 对拍过,结果一致。

# nomp.py
import numpy as np
import scipy.io as sio
import scipy.linalg
import scipy.optimize
from sklearn.preprocessing import normalize


"""Non-negative Orthogonal Matching Pursuit

ref:
- Stable and efficient representation learning with nonnegativity constraints
- Supplementary Materials: Compositional Zero-Shot Learning via Fine-Grained Dense Feature Composition
- https://github.com/hbdat/neurIPS20_CompositionZSL/blob/main/omp/omp.py#L43
"""


def to_pos(X):
    """X -> [max(0, X), max(0, -X)]
    把含有负值的向量映射成全是非负的向量
    相当于用多一倍的维度代偿原本负值的空间
    """
    X_inv = - X
    X_pos = np.concatenate([
        np.where(X > 0, X, 0),
        np.where(X_inv > 0, X_inv, 0),
    ], axis=1)
    print(X_pos.shape)
    return X_pos


def cos(A, B=None):
    """cosine"""
    An = normalize(A, norm='l2', axis=1)
    if (B is None) or (B is A):
        return np.dot(An, An.T)
    Bn = normalize(B, norm='l2', axis=1)
    return np.dot(An, Bn.T)


def spherical_kmeans(X, k=-1):
    """select a subset for dictionary using spherical k-means
    X: [n, d]
    k: # of cluster

    - https://github.com/jasonlaska/spherecluster
    """
    from spherecluster import SphericalKMeans
    n = X.shape[0]
    if (k <= 0) or (k > n):
        k = max(1, n // 2)
    skm = SphericalKMeans(n_clusters=k)
    skm.fit(X)
    return skm.cluster_centers_


def norm2(x):
    """x: [d] vector"""
    return np.linalg.norm(x) / np.sqrt(len(x))


def NOMP(D, f, k=-1, non_neg=True, max_iter=200, tol_res=1e-3, tol_coef=1e-12, verbose=False):
    """Non-negative Orthogonal Matching Pursuit
    Input:
        D: [m, d], dictionary (assumed to have been l2-normalised)
        f: [d], feature to decompose
        k: max # of selected component from dictionary,
            default to the whole dictionary size
        non_neg: to enforce non-negative coefficients
        tol_res: residual tolerance,
            exit if ||Rf|| < tol_res * ||f|| (error is small enough)
        tol_coef: residual covariance threshold,
            exit if coef_i < tol_coef * ||f|| for all i
    Output:
        active: [n] (n <= k), id of the selected components in the dictionary
        coef: [n], composition weights of the selected components
        Rf: [d], redidual vector
    """
    assert (2 == D.ndim) and (1 == f.ndim)
    assert D.shape[1] == f.shape[0], "dimension mismatch"
    m = D.shape[0]
    if (k <= 0) or (k > m):
        k = m

    f_norm = norm2(f)
    if verbose:
        print("initial residual:", f_norm)
    # tol_res = tol_res * f_norm
    tol_coef = tol_coef * f_norm
    Rf = f  # (initial) residual vector
    D_col = D.T  # [d, m], arrange as column vector
    active = []  # meta id of the selected components
    coef = np.zeros([m], dtype=np.float32)

    # degenerate solution
    if f_norm < tol_res:
        return active, coef

    if non_neg:
        get_candidate = lambda score: np.argmax(score)
        calc_coef = lambda _D, _f: scipy.optimize.nnls(_D, _f)[0]
    else:
        get_candidate = lambda score: np.argmax(np.abs(score))
        calc_coef = lambda _D, _f: scipy.linalg.lstsq(_D, _f)[0]

    for _it in range(max_iter):
        # print("---", _it, "---")
        # neglect the numerator cuz `Dict` is already normalised
        score = cos(Rf[np.newaxis, :], D)[0]  # [m]
        d_id = get_candidate(score)
        max_socre = score[d_id]
        if max_socre < tol_coef:
            break

        if d_id not in active:
            active.append(d_id)

        _coef = calc_coef(D_col[:, active], f)
        coef[active] = _coef

        f_hat = D_col[:, active].dot(_coef).flatten()
        Rf = f - f_hat

        err_rate = norm2(Rf) / f_norm
        # print("residual error rate:", err_rate)
        if err_rate < tol_res:
            break
        if len(active) >= k:
            break

    f_hat = D_col[:, active].dot(coef[active]).flatten()
    Rf = f - f_hat
    err = norm2(Rf)
    err_rate = err / f_norm
    if verbose:
    	# print("residual:", np.linalg.norm(res))
        print("final residule: {:.4f}, error rate: {:.4f}".format(err, err_rate))
    return active, coef, f_hat, Rf

References

  1. Matching Pursuits With Time-Frequency Dictionaries
  2. Orthogonal Matching Pursuit: Recursive Function Approximat ion with Applications to Wavelet Decomposition
  3. Stable and Efficient Representation Learning with Nonnegativity Constraints
  4. hbdat/neurIPS20_CompositionZSL/omp/omp.py
  5. jasonlaska/spherecluster
### 回答1: 正交匹配追踪算法 (Orthogonal Matching Pursuit, 简称OMP)。是一种信号处理和机器学习中用于高维数据稀疏表示的算法。其基本思想是在原始高维数据中,选取尽量少的维度,通过线性组合来表示出所有的数据。可以应用于图像处理、信号处理、压缩感知等领域。 ### 回答2: Orthogonal matching pursuit(OMP)是一种基于贪心算法的稀疏信号恢复方法,主要用于从部分观测信号中恢复原信号。它利用信号稀疏性假设和最小二乘原则,通过选择相互正交的原子逐步逼近原信号。该算法具有简单易懂,易于实现,且收敛速度快的特点,在计算机视觉、机器学习等领域得到广泛应用。 该算法的主要思想是:从一个较大的原子集中,选择与观测信号最相关的原子,使得观测信号能够最好地逼近原信号。在每次迭代中,首先计算残差,然后寻找与残差最相关的原子,再将其投影到残差上,重复此过程直到残差足够小或选取的原子个数达到预设值为止。因为原子是相互正交的,所以每一步选择的原子不会重复,这保证了算法的稀疏性。另外,通过对残差与选取原子的内积进行比较,算法可以自适应地选择原子,适用于各种类型的信号。 虽然OMP算法的时间复杂度为O(NK^2),其中N为信号维数,K为原子个数。但是,该算法可以通过简单的优化得到更优的时间复杂度,比如迭代式OMP,用于处理高维数据时的OMP-C块版本等。此外,算法还可以结合其他方法使用,比如基于二次规划的正则化方法,以更好地处理信号噪声和完整性问题。 与其他稀疏恢复算法相比,OMP算法具有以下优点:对于稀疏度较高的信号,性能相对较好;简单易懂,易于实现,收敛速度快。缺点是当信号稀疏度较低、噪声较大时,会出现误匹配或过拟合现象,需要加入其他算法进行处理。 ### 回答3: 正交匹配追踪,英文名为 Orthogonal Matching Pursuit (OMP),是一种稀疏表示技术,被广泛应用于信号处理、图像处理、机器学习、计算机视觉等领域。其基本思想是在高维数据中找到少数重要特征向量,通过迭代的方式找到这些向量,实现数据降维的目的。 OMP算法的核心是贪心策略,它通过选择当前最佳候选向量来逼近目标信号。具体来说,算法每次选取一个内积值最大的原子,并将其添加到估计信号中。然后,将这个向量从候选字典中删除,并根据估计信号和误差信号的内积进行更新,此过程被称为正交匹配。接着,将选取下一个内积最大的向量并重复此步骤,直到达到预设的稀疏度或精度要求。 由于OMP算法运行效率高、易于实现,并且能够快速准确地逼近信号,因此在信号重构、模式识别和机器学习中被广泛应用。例如,在图像压缩中,可以使用OMP算法将一个稀疏的图像表示为一组稀疏系数。在语音识别中,OMP算法可以识别出一个人的关键语音特征,并将其表示为一组稀疏向量。总之,正交匹配追踪算法为信号分析和模式识别提供了重要的工具和方法。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值