【问题标题】:Histogram intersection kernel optimization in MATLABMATLAB中的直方图交叉核优化
【发布时间】:2015-06-23 08:10:24
【问题描述】:

我想尝试使用直方图交叉核的 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 优化!

【问题讨论】:

    标签: performance matlab classification svm


    【解决方案1】:

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

    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 对计算并不重要,因为它确实打印了一些消息。

    【讨论】:

    • 我无法删除循环,但使用bsxfun 计算分钟得到了很大的改进。最后:D(i,j) = sum(bsxfun(@min,a(i,:),b(j,:)))。谢谢
    • @user3799302 你什么意思,你不能删除循环?此答案中发布的用于计算 D 的代码是将内核中的两个嵌套循环替换为:for i=1:mfor j=1:n 是两个循环。
    • @user3799302 我之前的评论有意义吗?
    • 它确实有效,但我仍然不明白为什么。那是我的工作。再次感谢
    • @user3799302 查看编辑后的解释是否对您有意义?
    猜你喜欢
    • 2015-01-08
    • 2017-05-11
    • 2019-04-23
    • 1970-01-01
    • 2018-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-02
    相关资源
    最近更新 更多