好吧,我从 4 个不同的 Matlab 函数制作了 4 个独立的可执行文件来构建人脸识别系统。我正在使用不同的批处理代码调用这 4 个可执行文件并对图像执行任务。我拥有的图像总数超过 300k。这 4 个可执行文件中有 3 个运行良好,但是当我尝试调用 Fisherface 函数的独立可执行文件时,我面临“内存不足”问题。它使用 Fisher 的线性判别分析简单地计算每个图像的独特特征。该分析应用于由超过 150,000 张大小为 60*60 的图像的像素值组成的巨大人脸矩阵。因此矩阵的大小是 150,000*3600。
好吧,我所理解的是由于 RAM 中的连续内存不足而发生的。所以作为一个出路,我选择将我的大图像集划分为多个子集,每个子集包含 3000 张图像。现在,当提供输入人脸时,它会在每个子集中搜索该输入的最佳匹配,并最终整理出具有最低距离(欧几里得)的 3 个最佳匹配的最终列表。这解决了内存不足错误,但识别率变得低得多。因为当在原始人脸矩阵中进行判别分析时(我已经在包含 4000-5000 张图像的较小数据集中进行了测试),它给出了很好的识别率。
我正在寻找解决这个问题的方法。我想对大矩阵执行所有操作。有没有办法更高效地实现该功能,例如在Matlab中动态分配内存?我希望我已经相当具体,以便解释我的问题。下面,我提供了该特定可执行文件的代码段。
function FisherfaceCorenew(matname)
load(matname);
Class_number = size(T,2) ;
Class_population = 1;
P = Class_population * Class_number; % Total number of training images
%%%%%%%%%%%%%%%%%%%%%%%% calculating the mean image
m_database = single(mean(T,2));
%%%%%%%%%%%%%%%%%%%%%%%% Calculating the deviation of each image from mean image
A = T - repmat(m_database,1,P);
L = single(A')*single(A);
[V D] = eig(L); % Diagonal elements of D are the eigenvalues for both L=A'*A and C=A*A'.
%%%%%%%%%%%%%%%%%%%%%%%% Sorting and eliminating small eigenvalues
L_eig_vec = [];
for i = 1 : P
L_eig_vec = [L_eig_vec V(:,i)];
end
%%%%%%%%%%%%%%%%%%%%%%%% Calculating the eigenvectors of covariance matrix 'C'
V_PCA = single(A) * single(L_eig_vec);
%%%%%%%%%%%%%%%%%%%%%%%% Projecting centered image vectors onto eigenspace
ProjectedImages_PCA = [];
for i = 1 : P
temp = single(V_PCA')*single(A(:,i));
ProjectedImages_PCA = [ProjectedImages_PCA temp];
end
%%%%%%%%%%%%%%%%%%%%%%%% Calculating the mean of each class in eigenspace
m_PCA = mean(ProjectedImages_PCA,2); % Total mean in eigenspace
m = zeros(P,Class_number);
Sw = zeros(P,P); %new
Sb = zeros(P,P); %new
for i = 1 : Class_number
m(:,i) = mean( ( ProjectedImages_PCA(:,((i-1)*Class_population+1):i*Class_population) ), 2 )';
S = zeros(P,P); %new
for j = ( (i-1)*Class_population+1 ) : ( i*Class_population )
S = S + (ProjectedImages_PCA(:,j)-m(:,i))*(ProjectedImages_PCA(:,j)-m(:,i))';
end
Sw = Sw + S; % Within Scatter Matrix
Sb = Sb + (m(:,i)-m_PCA) * (m(:,i)-m_PCA)'; % Between Scatter Matrix
end
%%%%%%%%%%%%%%%%%%%%%%%% Calculating Fisher discriminant basis's
% We want to maximise the Between Scatter Matrix, while minimising the
% Within Scatter Matrix. Thus, a cost function J is defined, so that this condition is satisfied.
[J_eig_vec, J_eig_val] = eig(Sb,Sw);
J_eig_vec = fliplr(J_eig_vec);
%%%%%%%%%%%%%%%%%%%%%%%% Eliminating zero eigens and sorting in descend order
for i = 1 : Class_number-1
V_Fisher(:,i) = J_eig_vec(:,i);
end
%%%%%%%%%%%%%%%%%%%%%%%% Projecting images onto Fisher linear space
for i = 1 : Class_number*Class_population
ProjectedImages_Fisher(:,i) = V_Fisher' * ProjectedImages_PCA(:,i);
end
save fisherdata.mat m_database V_PCA V_Fisher ProjectedImages_Fisher;
end
Run Code Online (Sandbox Code Playgroud)
帮助你并不容易,因为我们看不到你的矩阵的大小。
至少clear在不再使用变量后您可以使用Matlab命令(例如A)。
也许您可以single()在分配 A 变量时使用该命令,而不是在每个方程中使用该命令。
A = single(T - repmat(m_database,1,P));
Run Code Online (Sandbox Code Playgroud)
进而
L = A'*A;
Run Code Online (Sandbox Code Playgroud)
您还可以使用Matlab 分析器和内存使用情况来查看您的内存需求。
另一种选择可能是使用sparse矩阵或简化为更小的数据类型,例如uint8,如果适用于某些数据。