创建大尺寸矩阵时内存不足

Low memory when creating big size matrix

此代码 selects 从输入图像 x 中随机抽取 J=R*T 个样本。 x 是 MxN 图像。PHi_2 运算符首先 selects 从 M 中随机 R 行,然后 selects 从 N 中随机 T 列,并保留常见 M 和 N 像素的样本并设置其他零。 此代码适用于小尺寸图像,但对于大尺寸图像 (512x512),matlab 会出现内存不足错误(创建 Phi2=zeros(J,S1*S2); 时的第四行)。你能帮我解决这个问题吗?还有我 select R=T=362;

function [ y2,Phi2 ] = Phi2_operator( x,R,T )
J=R*T;
[S1,S2]=size(x);
z=zeros(size(x));
y2=zeros(size(x));
Phi2=zeros(J,S1*S2);
k = randperm(S1);
a=k(1:R);
b=sort(a);
l=length(b);
for i=1:l
z(b(i),:)=x(b(i),:);
end
clear i
K=randperm(S2);
A=K(1:T);
B=sort(A);
L=length(B);
for i=1:L
y2(:,B(i))=z(:,B(i));
end
X=find(y2);
for i=1:J
Phi2(i,X(i))=1;
end
end

您可以稍微优化一下代码:

1. 你可以用两个参数调用 randpermrandperm(n,k),它从区间 [=17] 中随机选择 k 个样本=].这样你就不需要创建变量 a.

2. 除了在 for 循环中将值分配给 zy2,您可以使用矢量化方法:z(k,:) = x(k,:);.这比 for 循环更快更短。您也不需要对 k.

进行排序

现在说更重要的事情:

3. 您创建了 zy2,它们都具有 x 的完整大小,但您只创建了 return y2。删除 z,可以节省一些内存。再次借助逻辑索引,我们得到:

k1 = randperm(S1,R);
k2 = randperm(S2,T);

y2(k1,k2) = x(k1,k2);    

4. 让我们看看 Phi2 是什么:使用 X=find(y2) 你会得到每个非零元素的 linear index y2Phi2 的一个简单示例如下所示:

0    0    1    0    0    0    ...
0    0    0    0    1    0    ...
0    0    0    0    0    1    ...
...

这告诉我们第一个非零元素(Phi2 的第一行)位于 y2 的第 3 个线性索引处。第二个非零元素(第二行)位于 y2 的第 5 个线性索引处。第三个非零元素(第三行)位于 y2 的第 6 个线性索引处,依此类推。这增加了 no 额外的知识,但需要一个巨大的矩阵。我不认为你真的需要这个,可能有一些方法可以在不创建这个矩阵的情况下解决你的问题。

如果你真的需要这个巨大的Phi2,你会想把它变成一个sparse矩阵:

Phi2 = sparse(1:J,X,ones(1,J));

对于具有 R=128T=64256*256 图像,全尺寸矩阵将为 4294967296 bytes4 GB !稀疏矩阵只有651272 bytes636 kB

所有的东西放在一起就是

function [ y2,Phi2 ] = Phi2_operator( x,R,T )
    J = R * T;
    [S1,S2] = size(x);

    y2 = zeros(size(x));

    k1 = randperm(S1,R);
    k2 = randperm(S2,T);

    y2(k1,k2) = x(k1,k2);  

    X=find(y2);
    Phi2 = sparse(1:J,X,ones(1,J));
end