Double Sparsity: Learning Sparse Dictionaries for Sparse Signal Approximation

本文介绍了一种新的双稀疏字典学习方法,该方法结合了隐性字典和显性字典的优点,旨在提高字典的复杂度和适应性。通过引入参数化的字典模型,使得字典更加灵活,能够更好地适用于不同的图像处理任务。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

from:http://rabbit3306.diandian.com/post/2012-06-14/40027417022


12-14是Ron Rubinstein, Student Member, IEEE, Michael Zibulevsky, and Michael Elad, Senior Member, IEEE. 2010.2.10

字典分两种,一种是隐性字典,implicit dictionary,这种主要是由它们的算法表现出来的,而不是矩阵结构,比如wavelet,curvelet,contourlet,等等。另一种是通过机器学习来从样本中获取字典,这种字典表现为一种显性矩阵,explicit matrix,而算法是用来适应矩阵的,比如PCA,GPCA,MOD,K-SVD等等,这种字典的好处在于比前一种灵活,表现也好,坏处就是耗费时间和运算资源,另外复杂的约束限制了字典的大小以及需要处理的信号的维度(所以论文提出的这个算法最后用3D图像去噪来表现优越性)。

本文提出的方法跨越了这两种字典的鸿沟。

之前存在的算法,一种是正交基的归一化组合,这种方法通过块协调松弛(Block-coordinate-relaxation BCR)可以稀疏表发,并且算法简单有效(有效是指的是字典收敛得快?),但是缺点是字典结构太严格了,并且表现不好。一种是半多层次结构算法,硬性地将子字典排列成一种稀疏的形式,本文的方法就是吸收了这种稀疏字典的形式。还有一种是Signature字典,这种字典来源于一个紧致的Signature图像,图像的没一个子块构成了字典的一个原子。这种字典的好处是几乎是translation-invariance,减少过重叠,当用相邻信号块的关系的时候编码很快,但是这种字典的参数很少,每个原子一个系数也导致字典更严格,这篇论文提出的方法就是增加了参数,每个原子的系数1到p之间。

字典的两个主要性质:复杂度和适应性,第一个性质是指操作性,需要多复杂的操作步数,比如OMP等等;第二个性质是指适用性,是否在不同图像上普遍表现好。第二个性质的代表就是小波。

怎样兼顾这两者呢?这就需要一个带参数的字典模型提供足够的自由度。从K-SVD方法提取出来的字典中可以看到,字典本身是有结构的,原子本身是规则的,因此或许可以假设字典本身在某个更基础的字典上是稀疏的。

因此之前的D就可以代换成Fai*A,A是一个稀疏矩阵。Y=Fai*A*X;双稀疏字典的算法就是在已知Y的情况下计算出稀疏矩阵A和稀疏表示X。Fai其实和训练字典一样,随便选个初始化的值,会随着迭代变化,最后变成理想字典,若用最后的Fai做字典,那么稀疏表示是A*X,若用Fai*A做字典,那么稀疏表示是X。

算法解释:大体上就是两次K-SVD的嵌套,如果按照论文的步骤,12-14步是一次K-SVD,只更新了稀疏表示a,没有更新字典的原子;5-15步是一次K-SVD,更新了稀疏表示X,字典的原子更新是通过稀疏表示a的更新实现的。初始化各个值之后,把Fai*A看做一体,用K-SVD求X,然后注意力集中在A的一行上,以及X的对应一列上,计算这一行和这一列的贡献,用K-SVD求这个贡献在Fai上的稀疏表示,求出来的稀疏表示替代了A原来那一行,同时更新X的一列。

clear all

%% 初始化,和前面很多一样的地方,因为我懒,借用了,

if not(exist('w'))

w = 10;

end

n = w*w;

p = 2*n; % 字典中原子的个数

m = 20*p; % 训练用块数的多少

sp1 = 4; % 稀疏表示X的稀疏度

sp2=3; % 稀疏矩阵A的稀疏度

if not(exist('f'))

f = rescale( crop(load_image('barb'),256) ); % 截取原图像的中心区域

end

n0 = size(f,1);

q = 3*m;% Overlapping

x = floor( rand(1,1,q)*(n0-w) )+1; % 随机选取块的中心像素位置,x坐标

y = floor( rand(1,1,q)*(n0-w) )+1; % 随机选取块的中心像素位置,y坐标

[dY,dX] = meshgrid(0:w-1,0:w-1);

Xp = repmat(dX,[1 1 q]) + repmat(x, [w w 1]);

Yp = repmat(dY,[1 1 q]) + repmat(y, [w w 1]);

Y = f(Xp+(Yp-1)*n0);

Y = reshape(Y, [n q]);

Y = Y - repmat( mean(Y), [n 1] );

[tmp,I] = sort(sum(Y.^2), 'descend'); % 按照递减排列

Y = Y(:,I(1:m)); % 取前m个作为训练样本

ProjC = @(D)D ./ repmat( sqrt(sum(D.^2)), [w^2, 1] );% 归一化

sel = randperm(m);

sel = sel(1:p);

D0 = ProjC( Y(:,sel) ); % 取p个归一化后的训练样本作为初始字典

D = D0;

It=15; % 循环次数

A0 = eye(200,200); % 初始化A0,这里有点不懂,论文上关于A也没说太清感觉,是我没看太懂吧还是,反正A是可以随便选的,当然前提是要稀疏,我开始选了ones,明显就不行

A=A0; % 初始化A,

for i=1:It % 总的循环次数

Xs=zeros(p,m);

%% OMP求稀疏表示

D1=D*A; % 固定D和A,把D*A看做字典

F = omp_m(m,Y,p,D1,n,sp1,Xs); % 用OMP的子函数算出稀疏表示X

X=F;

%% 计算稀疏矩阵A

for ite = 1:p

eff = A(ite,:)*X;

A(ite,:)=A0(ite,:)*0; % 抽取A的一行,取一行而非一列的原因和K-SVD一样,

Pos = find(eff); % A的一行被值为零,若eff中有不为零的,即为用到了A的这一行

if ~isempty(Pos) % 有时候A的这一行根本就没用着……

G=X(ite,Pos);

moG = G*G'; % 问题就在这里,有时候2范数为0!!

G = G/moG; % 求出的X的一行的归一化,

Yi=Y(:,Pos); % Y=D*A*X,X的一行当中不为0的数,反映在Y中就是Y的列

z=Yi*G'-D*A*X(:,Pos)*G'; % 计算A的一行和X的一行的贡献,本来A的一行的贡献为(Yi-D*A*X(:,Pos)),这个贡献再乘以G,就是再缩减到X的一行的贡献

Di=1;Xo = zeros(p,1);

a = omp_m(Di,z,p,D,sp2,Xo); % 用OMP的子函数计算出稀疏表示a,

auni=D*a;

auni=auni'*auni;

a=a/auni;

A(ite,:)=a; % 更新稀疏表示,这里用这种方法替代了SVD

Y2 = D*A*X(:,Pos);

X2 = Yi'*D*a-Y2'*D*a;

X(ite,Pos) = X2'; % 这里更新了外面一层的稀疏表示

end

end

end


### 解决 Matlab 中稀疏矩阵水平拼接时行数不匹配的报错问题 当尝试在 MATLAB 中对两个或多个稀疏矩阵进行水平拼接(`horzcat`),如果这些矩阵的行数不同,则会遇到错误提示:“Mismatching number of rows”。为了有效处理这一情况,可以采取以下几种方法: #### 方法一:验证并调整输入矩阵尺寸 确保所有参与拼接操作的稀疏矩阵拥有相同的行数是一个基本前提。可以通过检查各个矩阵的具体维度来确认这一点。 ```matlab % 假设有两个稀疏矩阵 A 和 B 需要被水平拼接 [mA, ~] = size(A); [mB, ~] = size(B); if mA ~= mB error('Matrix dimensions do not match'); end C = horzcat(A,B); % 或者使用方括号表示法 C = [A,B]; ``` 此段代码首先获取了 `A` 和 `B` 的行数,并进行了比较;如果不相等则抛出异常终止程序执行[^1]。 #### 方法二:填充缺失行以实现一致化 对于那些确实存在结构差异的情况——即某些矩阵可能缺少部分行的数据,在这种情况下可以选择通过适当的方式填补空白区域使得它们具备相同数量的行再继续后续的操作。 ```matlab function paddedSparseMatrix = padRowsToMatch(sparseMatrices) maxRows = max(cellfun(@(m)size(m,1), sparseMatrices)); paddedSparseMatrix = cell(size(sparseMatrices)); for idx = 1:length(sparseMatrices) currentMatrix = sparseMatrices{idx}; [~, numCols] = size(currentMatrix); if size(currentMatrix, 1) < maxRows paddingSize = maxRows - size(currentMatrix, 1); zeroPadding = sparse(paddingSize, numCols); paddedSparseMatrix{idx} = vertcat(currentMatrix, zeroPadding); else paddedSparseMatrix{idx} = currentMatrix; end end end ``` 上述函数接收一个包含若干个待处理稀疏矩阵的单元数组作为参数,计算其中的最大行数后依次遍历每一个成员对象并向其追加必要的零值填充直至达到统一标准为止[^2]。 #### 方法三:利用元胞数组间接完成组合 另一种思路是先将各独立组件存入到同一个元胞内然后再一次性转换成最终目标形式的大规模稀疏阵列。 ```matlab cellArray = {sparse(3,4), sparse(3,5)}; combinedSparseMatrix = cell2mat(cellArray); ``` 这种方法适用于已知所有子块都具有兼容性的场景下快速构建复合体而不必显式关心内部细节上的微调工作。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值