Loading [MathJax]/jax/element/mml/optable/BasicLatin.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >正交匹配追踪

正交匹配追踪

作者头像
卡尔曼和玻尔兹曼谁曼
发布于 2023-12-01 00:53:00
发布于 2023-12-01 00:53:00
2570
举报

这篇博文是在对Koredianto Usman《Introduction to Orthogonal Matching Pursuit》文章的翻译,后面附带了一些总结.

这篇文章是前面《Matching Pursuit (MP)》文章的继续. (注:原文中还是有一些小细节错误,请大家睁大眼睛阅读)

简介

考虑下面的问题:给定

,计算

.

这相当简单!

现在是比较困难的部分!给定

,如何找到原始的

(或者尽可能接近原始的

)?

在压缩感知(Compressive Sensing)术语中,从

中得到

叫做压缩,反之,从

得到

叫重建(个人感觉原文中好像说反了,还是我理解错了?). 重建问题不是一个很简单的问题。

一般地,

被称为original signal或者original vector,

被称为compression matrix或者sensing matrix,

称为compressed signal或者compressed vector.

基本概念

和前面在MP算法中讨论过的一样,感知矩阵

可以看做列向量的集合:

其中,

这些列被称为基(basis)或者原子(atom).

现在,我们令

,则

.

从该方程可以看出

是使用

中的稀疏对原子的线性组合. 实际上,我们知道

x1=1.2

x2=1

x3=0

. 换言之,对于得到

y

值,

b1

的贡献值为-1.2,

b2

为1,而

b2

为0.

OMP算法和MP算法类似,都是从字典中找出哪一个原子对

y

值的贡献最大,接下来是哪个原子的贡献值大,以此类推. 我们现在知道这个过程需要

N

次迭代,

N

是字典中原子的个数. 在该例子中,

N

等于3.

计算原子的贡献值

字典中有三个原子,

b1=[0.7070.707],b2=[0.80.6],b1=[01]

y=[1.650.25]

因此,各原子对

y

的贡献值为

<b1,y>=[0.7070.707]T[1.650.25]=0.7071.65+0.7070.25=1.34
<b2,y>=1.17

<script type="math/tex" id="MathJax-Element-41"> = 0.25</script>

显然,原子

b1

y

值的贡献最大为-1.34(按绝对值计算).

在第一次迭代过程中,我们选择

b1

作为基,基的系数为-1.34.

当然,我们也可以使用矩阵的形式计算点积:

w=ATy=0.7070.7070.80.601[1.650.25]=1.341.170.25

原子和

y

的几何意义如图1:

计算残差

现在已经选定了第一个基

b1=[0.7070.707]

,贡献值系数为

λ1=1.34

. 将该部分贡献值从

y

中减去,残差为

r=yλ1b1=[1.650.25](1.34)[0.7070.707]=[0.70.7]

残差的几何意义如图2:

重复迭代

经过第一次迭代,我们选择出了基

b1

. 将选择出的基加入新的矩阵

Anew

,即:

Anew=[b1]=[0.7070.707]

贡献系数矩阵可以写成

xrec=1.3400

第一个元素是第一个贡献值-1.34,对应着第一个第一个基

b1

.

残差值为

r=[0.70.7]

现在需要从剩下的基

b2

b3

中选择对残差

r

贡献最大的.

w=[b2b3]Tr=[0.980.7]

所以,

b2

的贡献值更大一些是0.98.

我们将选择的基

b2

添加到

Anew

得到

Anew=[b1b2]=[0.7070.80.7070.6]

接下来的步骤和MP算法稍微有些不同. 这里,我们需要计算

Anew

y

的贡献(而不是

b2

r

的贡献)

我们使用最小二乘法(Least Square Problem)解决该该贡献值问题:

如何求得

λ1

λ2

的值使得

λ1[0.7070.707]+λ2[0.80.6]

最接近

y=[1.650.25]

表示成数学语言为:

minAnewλy2

在这个例子中,即

min[b1b2]=[0.7070.80.7070.6][λ1λ2][1.650.25]2

对于

minAnewλy2

的解可以直接使用公式:

λ=A+newy

其中,

A+new

Anew

的谓逆,

A+new=(ATnewAnew)1ATnew

(注:可参看我的博文《Moore-Penrose广义逆矩阵》和《矛盾方程的最小二乘解法》)

在我们的例子中

A+new=[0.7070.80.7070.6]+=[0.60620.80820.71430.7143]

可以使用MATLAB中的内置函数pinv()进行伪逆的计算.

得到

A+new

后,可以计算

λ
λ=A+newy=[0.60620.80820.71430.7143][1.650.25]=[1.21]

得到

λ

以后,更新系数矩阵

xrec

xrec=1.210

同样的,

λ

xrec

第一个元素和第二个元素对应着选择出来的第一个和第二个基.

得到

Anew

λ

以后,我们可以计算残差

r=yAnewλ=[1.650.25][0.7070.80.7070.6][1.21]=[00]

此时,残差值为

[00]

,我们可以停止计算或者继续下一步计算(这里停止,可以节省一些计算工作).

最后一次迭代

这一步不是必须的,因为残差已经完全消除了(很多实现OMP的软件都需要输入稀疏度

K

参数,这样经过

K

次迭代以后,无论残差大小都会停止迭代).

重新组织信号系数

xrec=1.210

,这刚好是原始的系数.

其他例子

给定

x=⎢ ⎢ ⎢0312⎥ ⎥ ⎥

A=0.80.310.40.20.40.30.40.210.10.8

求得

y=Ax=2.70.14.5

现在给定

A

y

,使用OMP算法求解

x

.

  1. 我们有4个基(原子):
b1=0.80.20.2b2=0.30.41b3=10.30.1b4=0.40.40.8
  1. 由于基向量的长度不是1,所以我们首先进行标准化.
^b1=b1/b1=0.80.20.2/(0.8)2+(0.4)2+(0.2)2=0.94280.23570.2357
^b2=b2/b2=0.26800.35780.8940
^b3=b3/b3=0.95350.28600.0953
^b2=b2/b2=0.40820.40820.8165
  1. 标准化的基向量对
y

的贡献

w
w=^ATy=0.94280.26800.95350.40820.23570.35780.28600.40820.23570.98400.09530.8165T2.70.14.5=⎢ ⎢ ⎢1.50854.78522.11674.7357⎥ ⎥ ⎥
  1. 第二个基向量
b2

贡献值最大,所以将

b2

加入到

Anew
Anew=b2=0.30.41
  1. 利用最小二乘法计算
xrec
Lp=A+newy=[4.28]

因为

Lp

对应着第二个基向量,所以

xrec=⎢ ⎢ ⎢04.2800⎥ ⎥ ⎥
  1. 接下来计算残差
r=yAnewLp=2.70.14.50.30.414.28=1.4161.6120.22
  1. 接下来重复第3步,计算
^b1

^b1

^b1

r

的贡献.

w=^ATr=0.94280.95350.40820.23570.28600.40820.23570.09530.8165T1.4161.6120.22=0.90321.79021.4158

选择第二个贡献最大的基

b3

,其贡献值为1.7902.

  1. 将选择的
b3

加入到

Anew

Anew=[b1b2]=0.310.40.310.1
  1. 用最小二乘法计算
Lp=A+newy=[4.17021.7149]

这个

Lp

对应着

b2

b3

,因此

xrec=⎢ ⎢ ⎢04.1721.71490⎥ ⎥ ⎥
  1. 接着计算残差
r=yAnewLp=2.70.14.50.310.40.310.1[4.1721.7149]=0.2661.05360.5012
  1. 重复步骤2,进行最后一次迭代
  2. 计算
b1

b4

的贡献值

w=[^b1^b2]r=0.94280.40820.23570.40820.23570.8165T0.2661.05360.5012=[0.61720.7308]

这里

b4

提供了最大贡献值0.7308.

b4

加入

Anew=0.310.40.40.30.410.10.8
  1. 利用最小二乘计算

,对应的

  1. 接着计算残差
  1. 我们的迭代到此为止,因为此时残差已经为0,重建的

,和原来的信号相同.

需要注意的问题

通过上面的迭代计算过程,我们应该注意如下几点:

  1. OMP中最大贡献值的计算需要对基向量进行标准化处理,不是由原始基得到的.
  2. 如果给定的基向量已经是单位向量,则不需要进行标准化.
  3. 基向量对

值的贡献的计算是通过标准化以后的基向量和残差的点积进行计算的.

  1. 在MP算法中,重建系数

的计算是通过基向量和残差的点积进行计算的,在OMP算法中,

的计算是通过最小二乘法得到

相对于

的系数得到的,即

的计算.

向量中的值直接对应于

的相应位置.

通过每次对基向量的选择得到. 这个过程是需要时间的,因此OMP比MP慢. (不是应该OMP收敛的快吗?)

  1. 残差

的计算通过原始的

值和

得到.

  1. 迭代的次数最多等于

矩阵的行数M,或者如果给定了稀疏度

,则迭代

次. 如果

,则已知的

可以加快计算结束,如果

未知,则迭代

次.

说明总结

在正交匹配追踪OMP中,残差总是与已经选择过的原子正交的。这意味着一个原子不会被选择两次,结果会在有限的几步收敛。

OMP算法 步骤描述:

输入:字典矩阵

,采样向量

,稀疏度

.

输出:

稀疏逼近

.

初始化:残差

,索引集

.

循环执行步骤1-5:

  1. 找出残差

和字典矩阵的列

积中最大值所对应的脚标

,即

.

  1. 更新索引集

,记录找到的字典矩阵中的重建原子集合

.

  1. 由最小二乘得到

.

  1. 更新残差

.

  1. 判断是否满足

,若满足,则迭代停止;若不满足,则继续执行步骤1.

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-12-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
翻译 | 更快的Python(一)
更快的Python(Python Faster Way)使用代码示例来说明如何书写Python代码能带来更高的性能。本文对代码进行了讲解,从性能和可读性等角度来选择出最适合的写法。
一墨编程学习
2019/05/08
6850
翻译 | 更快的Python(一)
翻译 | 更快的Python(二)
更快的Python使用代码示例来说明如何书写Python代码能带来更高的性能。本文对代码进行了讲解,从性能和可读性等角度来选择出最适合的写法。
simpleapples
2018/12/06
7370
翻译 | 更快的Python(二) simpleapples
更快的Python(Python Faster Way)使用代码示例来说明如何书写Python代码能带来更高的性能。本文对代码进行了讲解,从性能和可读性等角度来选择出最适合的写法。
一墨编程学习
2019/05/08
5580
翻译 | 更快的Python(二) simpleapples
可能是最全面的 Python 字符串拼接总结
在 Python 中字符串连接有多种方式,这里简单做个总结,应该是比较全面的了,方便以后查阅。
小小科
2018/07/31
3120
这里是最全面的 python 字符串拼接总结,赶快收藏!
在 Python 中字符串连接有多种方式,这里简单做个总结,应该是比较全面的了,方便以后查阅。
猫咪编程
2018/07/26
9800
你所不知道的Python | 字符串连接的秘密
字符串连接,就是将2个或以上的字符串合并成一个,看上去连接字符串是一个非常基础的小问题,但是在Python中,我们可以用多种方式实现字符串的连接,稍有不慎就有可能因为选择不当而给程序带来性能损失。
simpleapples
2018/10/16
5790
你所不知道的Python | 字符串格式化的演进之路
字符串格式化对于每个语言来说都是一个非常基础和常用的功能,学习Python的同学大概都知道可以用%语法来格式化字符串。然而为了让我们更方便的使用这个常用功能,语言本身也在对字符串格式化方法进行迭代。
simpleapples
2018/10/16
5990
Python字符串格式化技巧
几乎每个使用不同编程语言编写的计算机程序中都有字符串。这种数据类型很常见,Python中有许多操作和格式化字符串的方法。今天分享几种优雅格式化字符串的方法。
TalkPython
2022/11/21
4920
Python 工匠:使用数字与字符串的技巧
序言 这是 “Python 工匠”系列的第 3 篇文章。 数字是几乎所有编程语言里最基本的数据类型,它是我们通过代码连接现实世界的基础。在 Python 里有三种数值类型:整型(int)、浮点型(float)和复数(complex)。绝大多数情况下,我们只需要和前两种打交道。 整型在 Python 中比较让人省心,因为它不区分有无符号并且永不溢出。但浮点型仍和绝大多数其他编程语言一样,依然有着精度问题,经常让很多刚进入编程世界大门的新人们感到困惑:"Why Are Floating Point Number
腾讯蓝鲸助手
2022/04/24
6450
Python中最快的格式化字符串方式
第一种是传承自C语言printf函数的使用%占位符格式化字符串,如'%d' % 100,这种方式严格来说是使用%作为算数运算符进行的二元运算,而且有一个限制是只能进行数字和字符串的格式化输出。
杜逸先
2018/08/29
2K0
Python 工匠:使用数字与字符串的技巧
数字是几乎所有编程语言里最基本的数据类型,它是我们通过代码连接现实世界的基础。在 Python 里有三种数值类型:整型(int)、浮点型(float)和复数(complex)。绝大多数情况下,我们只需要和前两种打交道。
用户2196567
2018/12/05
6720
Python学习入门到精通:字符串格式化
你应当注意到,字符串a当中有一些内容用了一些特殊表示形式,%s, %d ,这样做的目的是为了通过格式化字符串来填充这部分内容,以便于生成想要的字符串内容。
python学习教程
2020/02/14
4150
Python学习入门到精通:字符串格式化
Python 格式化字符串的最佳姿势
对于用 Python 处理数据和文本的同学一定经常要和字符串格式化打交道,少不了要打一堆 %。
Crossin先生
2020/02/24
1K0
Python 格式化字符串的最佳姿势
Python 3.8 即将到来,这是你需要关注的几大新特性
2018 年 6 月底,Python 3.7 问世,之后 Python 3.8 的开发和测试工作也已经展开。近日,Python 软件基金会公开了 3.80b2 的说明文档,向公众展示了 beta 版本的测试进展,以及 Python 3.8 版本的新特性和功能改进。
昱良
2019/07/19
3650
Python工匠:数字与字符串(上)
“ 编程某种意义上是一门『手艺』,因为优雅而高效的代码,就如同完美的手工艺品一样让人赏心悦目。 ” 致“匠人” 数字是几乎所有编程语言里最基本的数据类型,它是我们通过代码连接现实世界的基础。在 Python 里有三种数值类型:整型(int)、浮点型(float)和复数(complex)。绝大多数情况下,我们只需要和前两种打交道。 整型在 Python 中比较让人省心,因为它不区分有无符号并且永不溢出。但浮点型仍和绝大多数其他编程语言一样,依然有着精度问题,经常让很多刚进入编程世界大门的新人们感到困惑:"W
腾讯NEXT学位
2019/05/20
5940
Python工匠:数字与字符串(上)
Python全网最全基础课程笔记(十一)——字符串所有操作,跟着思维导图和图文来学习,爆肝2w字,无数代码案例!
请注意,title()方法在处理包含标点符号的字符串时,会将标点符号后面的第一个字母也转换为大写,这可能与某些预期不同。比如,在英文中,标点符号(如逗号、句号)后面通常跟随小写字母开始的单词,但title()方法会将这些字母也转换为大写。如果你需要更精细地控制大小写转换,可能需要根据具体情况编写自定义的函数来处理字符串。
小白的大数据之旅
2024/11/20
1290
Python全网最全基础课程笔记(十一)——字符串所有操作,跟着思维导图和图文来学习,爆肝2w字,无数代码案例!
Python 3.8 即将到来,这是你需要关注的几大新特性
从事计算机领域工作的读者朋友对 Python 编程语言应该非常熟悉了。这是一门广受好评的动态编程语言,其灵活和语法简易的特点使得这门语言在脚本工具、数据分析、Web 后端都有广泛的应用。Python 开发社区也非常活跃,3.x 的版本迭代速度非常快。2018 年 6 月底,Python 3.7 问世,之后 Python 3.8 的开发和测试工作也已经展开。近日,Python 软件基金会公开了 3.80b2 的说明文档,向公众展示了 beta 版本的测试进展,以及 Python 3.8 版本的新特性和功能改进。
Python数据科学
2019/07/19
3560
Python 3.8 即将到来,这是你需要关注的几大新特性
Python 格式化字符串,这个方法真的即丝滑又舒服!
按理说我应该对这种重复性的动作很烦,起初确实是这样,但是现在我乐在其中,为什么呢?肯定不是脑子坏了,因为我最近学会了一个超好用的格式化字符串的方法,那是相当的丝滑,所以我又迫不及待的来分享啦!
数据森麟
2020/02/20
3190
Python 格式化字符串,这个方法真的即丝滑又舒服!
Python 格式化字符串,这个方法真的即丝滑又舒服!
按理说我应该对这种重复性的动作很烦,起初确实是这样,但是现在我乐在其中,为什么呢?肯定不是脑子坏了,因为我最近学会了一个超好用的格式化字符串的方法,那是相当的丝滑,所以我又迫不及待的来分享啦!
AI算法与图像处理
2019/11/09
4700
Python 格式化字符串,这个方法真的即丝滑又舒服!
按理说我应该对这种重复性的动作很烦,起初确实是这样,但是现在我乐在其中,为什么呢?肯定不是脑子坏了,因为我最近学会了一个超好用的格式化字符串的方法,那是相当的丝滑,所以我又迫不及待的来分享啦!
编程文青李狗蛋
2019/11/07
3430
Python 格式化字符串,这个方法真的即丝滑又舒服!
推荐阅读
相关推荐
翻译 | 更快的Python(一)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文