MATLAB中的直方图交集核优化

时间:2015-04-16 18:14:47

标签: performance matlab classification svm

我想尝试使用直方图交集核心的svm分类器,对于153个图像的数据集,但需要很长时间。这是我的代码:

a = load('...'); %vectors
b = load('...'); %labels
g = dataset(a,b);

error = crossval(g,libsvc([],proxm([],'ih'),100),10,10);
error1 = crossval(g,libsvc([],proxm([],'ih'),10),10,10);
error2 = crossval(g,libsvc([],proxm([],'ih'),1),10,10);

我在proxm函数中的内核实现是:

...
case {'dist_histint','ih'}
    [m,d]=size(A);
    [n,d1]=size(B);
    if (d ~= d1)
        error('column length of A (%d) != column length of B (%d)\n',d,d1);
    end

    % With the MATLAB JIT compiler the trivial implementation turns out
    % to be the fastest, especially for large matrices.
    D = zeros(m,n);
    for i=1:m % m is number of samples of A 
        if (0==mod(i,1000)) fprintf('.'); end
        for j=1:n % n is number of samples of B
            D(i,j) = sum(min([A(i,:);B(j,:)]));%./max(A(:,i),B(:,j)));
        end            
    end

我需要对此代码进行一些matlab优化!

1 个答案:

答案 0 :(得分:3)

您可以使用基于bsxfunvectorized方法摆脱内核循环以计算D -

D = squeeze(sum(bsxfun(@min,A,permute(B,[3 2 1])),2))

或者通过此修改避免squeeze -

D = sum(bsxfun(@min,permute(A,[1 3 2]),permute(B,[3 1 2])),3)

如果D的计算涉及max而不是min,则只需将@min替换为@max


说明bsxfun的工作方式是在单例维上执行扩展,并执行其调用中@列出的操作。现在,这种扩展基本上是如何实现替代for循环的矢量化解决方案。在数组中singleton dimensions,我们指的是1中的维度。

在许多情况下,单例维度尚未出现,对于bsxfun的向量化,我们需要创建singleton dimensions。其中一个工具是使用permute。这基本上都与前面提到的矢量化方法有关。

因此,您的内核代码 -

...
case {'dist_histint','ih'}
    [m,d]=size(A);
    [n,d1]=size(B);
    if (d ~= d1)
        error('column length of A (%d) != column length of B (%d)\n',d,d1);
    end

    % With the MATLAB JIT compiler the trivial implementation turns out
    % to be the fastest, especially for large matrices.
    D = zeros(m,n);
    for i=1:m % m is number of samples of A 
        if (0==mod(i,1000)) fprintf('.'); end
        for j=1:n % n is number of samples of B
            D(i,j) = sum(min([A(i,:);B(j,:)]));%./max(A(:,i),B(:,j)));
        end            
    end

缩减为 -

...
case {'dist_histint','ih'}
    [m,d]=size(A);
    [n,d1]=size(B);
    if (d ~= d1)
        error('column length of A (%d) != column length of B (%d)\n',d,d1);
    end
    D = squeeze(sum(bsxfun(@min,A,permute(B,[3 2 1])),2))
    %// OR D = sum(bsxfun(@min,permute(A,[1 3 2]),permute(B,[3 1 2])),3)

我假设这一行:if (0==mod(i,1000)) fprintf('.'); end对于计算并不重要,因为它会打印某些消息。