Matlab計算大規模圖片數據集的L1距離



比較兩幅圖片之間的距離或者相似性,我們常以Matlab pdist函數或者pdist2函數計算。計算大規模圖片數據集的兩兩圖片之間的距離,很自然想到雙重for循環完成了。不過,這很慢:

function KMatrix = getL1( X, Y ) %L1距離

m = size(X,1);  n = size(Y,1);

KMatrix = zeros(m,n);

for i = 1: m %按行

for j = 1: n

KMatrix(i,j) = sum( abs( X(i,:)-Y(j,:)) );

end

fprintf('%d.',i); if mod(i,10)==0, fprintf('\n'); end

end

其中,X、Y分別是圖片集X、Y的特徵文件矩陣。


以L1距離爲例,特徵文件是4096維的RGB彩色描述子,兩萬幅圖片之間的L1距離矩陣20000×20000,在 8CPU + 16GB內存的X64 Windows 7系統上計算,MATLAB 2012b運行時間5小時。比較慢。


向量化是一個考慮。不過,童鞋們,如何向量化呢?這個比起點積要複雜一點點。通過一行一行計算距離,去掉一個內循環:

function KMatrix = getL1( X, Y ) %L1距離 向量化

m = size(X,1);  n = size(Y,1);

nOnes = ones(1,n); KMatrix = zeros(m,n);

for i = 1: m %按行

   xi = X(i,:);  xi = xi( nOnes, : );

   KMatrix(i,:) = sum( abs( xi-Y),2 );%計算一行L1距離

   fprintf('%d.',i); if mod(i,10)==0, fprintf('\n'); end

end


似乎無法繼續向量化了?還好,arrayfun幫助我們繼續向量化。

function KMatrix = getL1( X, Y ) %L1距離 arrayfun向量化

m = size(X,1);  n = size(Y,1);

KMatrix = zeros(m,n);

CC = arrayfun(@(i) getL1Vec(X(i,:), Y, i), 1:m, 'UniformOutput', false);%只能得到Cells

for i = 1: m %Cells->矩陣,極快

   KMatrix(i,:) = CC{i};

end


end


function KVec = getL1Vec(XVec, Y, i)%第i行L1

n = size(Y,1);

nOnes = ones(1,n);

XVec = XVec( nOnes, : );

   KVec = sum( abs( XVec-Y),2 );%計算一行L1距離

   fprintf('%d.', i);if mod(i,10)==0, fprintf('\n'); end

end


至此,arrayfun完成了向量化。計算L1距離沒有循環了。只是Cells轉換爲矩陣,有一個循環,極快。不是瓶頸。



向量化還能否改進下?

似乎內存優化不夠,試試matlab函數:bsxfun(),改善:

n = size(Y,1);

nOnes = ones(1,n);

XVec = XVec( nOnes, : );

   KVec = sum( abs( XVec-Y),2 );%計算一行L1距離


於是,得到:

function KMatrix = getL1( X, Y ) %L1距離

m = size(X,1);  n = size(Y,1);

KMatrix = zeros(m,n);

CC = arrayfun(@(i) getL1Vec(X(i,:), Y, i), 1:m, 'UniformOutput', false);%只能得到Cells

for i = 1: m %Cells->矩陣,極快

   KMatrix(i,:) = CC{i};

end


end


function KVec = getL1Vec(XVec, Y, i)%第i行L1

   KVec = sum( abs(bsxfun(@minus,XVec,Y)),2 );

   fprintf('%d.', i);if mod(i,10)==0, fprintf('\n'); end

end

完成了。在 8CPU + 16GB內存的X64 Windows 7系統上計算,MATLAB 2012b運行時間3小時。節省了2個小時。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章