【问题标题】:Parallelize MATLAB for loop to calculate MLE并行化 MATLAB for 循环以计算 MLE
【发布时间】:2015-11-03 10:13:57
【问题描述】:

我试图通过使用parfor 来加速我的 MATLAB 代码,但是我做错了。我的代码相当简单,我使用 MATLAB 的内置 mle 函数通过对均值 (mm) 和方差 (vv) 使用不同的初始猜测来拟合一些数据。 onestagepdf2 是我的概率密度函数。

这里是代码片段:

mm=linspace(.1, 1, 2); % mean
vv=linspace(.1, 2, 2); % variance
N=length(mm);
n=length(vv);

pd=zeros(n*N,2);
ld = NaN*ones(n*N,1);

options = statset('MaxIter',10000, 'MaxFunEvals',10000);

parfor i=1:N  % pick a mean
    m=mm(i);
    parfor j=1:n  %  pick a variance
        v=vv(j);
        x0=[m,v];
        [p,conf1]=mle(data,'pdf',@onestagepdf2,'start',x0, 'upperbound', [Inf Inf],'lowerbound',[0 0],'options',options)
        pd(n*(i-1)+j,:)=p;  % store parameter values from mle
        l=onestagepdf2(data,p(1),p(2)); % evaluate pdf with parameter values
        ld(n*(i-1)+j)=sum(log(l));  % store likelihood value

    end
end

我收到的错误是:

'parfor中的变量pd不能分类'

【问题讨论】:

    标签: matlab parallel-processing parfor mle


    【解决方案1】:
    pd = zeros(n, N, 2); %initialise culprits
    ld= zeros(n,N);
    parfor ii=1:N  % pick a mean
        m=mm(ii);
        for jj=1:n  %  Parallellise the second parfor
            v=vv(jj);
            x0=[m,v];
            [p,conf1]=mle(data,'pdf',@onestagepdf2,'start',x0, 'upperbound', [Inf Inf],'lowerbound',[0 0],'options',options)
            pd(ii, jj, :) = p;=p;  % store parameter values from mle
            l=onestagepdf2(data,p(1),p(2)); % evaluate pdf with parameter values
            ld(ii,jj)=sum(log(l));  % store likelihood value
    
        end
    end
    

    正如@Trilarion 所说,您的pd 确实是您遇到错误的罪魁祸首。可能ld 也不是太好,语法相同,所以也要初始化它。这是因为parfor 想知道循环内所有变量的大小在执行之前。 MATLAB 不知道这是一个固定的最大大小,因为您正在使用循环变量来“更改”大小。

    当您将其作为for 循环运行时,您可能在这两行下方有“橙色摆动”(如拼写检查错误),说“pd 每次迭代的大小似乎都在增长。请考虑预先分配速度” .这是parfor要求的,因为迭代的顺序不是连续的,不可能以这种方式增长数组。

    其次,您不能嵌套 parfor 循环。您可以使用 parfor 之类的函数并在 parfor 中运行它,但这不会让您加快速度,因为您已经使用了所有工作人员。

    有关parfor 的更多一般信息,尤其是速度方面的信息,请参阅Saving time and memory using parfor in Matlab?

    【讨论】:

    • 我需要在parfor 循环内部而不是外部初始化pdld
    • 哼,不。确实你需要在外面初始化它们,我的错,我会更新帖子。
    • n*(i-1)+j 这里不大于n*N,所以变量的大小没有增长。只是Matlab不确定。
    • @Trilarion 这正是我要说的。
    【解决方案2】:

    您想要一个切片的输出变量,但 Matlab 不够聪明,无法检测到 n*(i-1)+j 实际上是合理的并且不会干扰异步评估。

    只需将其作为单独的维度进行

    pd = zeros(n, N, 2);
    ...
      % in the loop
      pd(i, j, :) = p;
    

    这会起作用的。

    请注意,Matlab 不允许嵌套 parfors。但是,如果N 大于工作人员的数量,您也不需要它们。另请参阅documentation

    【讨论】:

    • ld也是如此。
    • @Adriaan 假设有 4-8 名工人和 N 可能比这更大,所以询问者不需要第二个 parfor。但是他仍然需要扩展 pd 和 ld 的维数才能使外 parfor 起作用。
    • 这似乎解决了这个问题。我确实有一个后续问题:当我打印max(ld) 时,它会打印两次最大值,即-746.8349 -746.8349。你能解释一下原因吗?
    • @user3603290 如果您有一个与此问题完全不同的新问题,请询问a new question。如果这篇文章中的答案之一解决了您的问题,那么请考虑accepting it
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-10-29
    • 1970-01-01
    • 1970-01-01
    • 2020-09-10
    • 1970-01-01
    • 1970-01-01
    • 2018-05-28
    相关资源
    最近更新 更多