【问题标题】:Matlab efficiency - vectorizationMatlab 效率 - 向量化
【发布时间】:2014-05-31 20:54:38
【问题描述】:

我有这个运行的 Matlab 代码,但我想通过删除 for 循环来使其更快,并且基本上只使用矩阵进行相同的计算(我的数据集非常大,所以我需要这种优化):

Matrices dimensions: x(N,D), m(K,D), p(K), fL(N,K), maxf(N), maxfL(N), z(N,K).
Also p, maxf, maxfL are row vectors

代码1:

f = zeros(N,K);
maxf = zeros(1,N);

for n=1:N
   for k=1:K
      % here i had a loop for d dimension but made it more efficient like this:
      f2 = x(n,:) * log(m(k,:))' + (1 - x(n,:)) * log(1 - m(k,:))';
      f(n,k) = log(p(k)) + f2;
   end
   maxf(n) = max(f(n,:));
   f(n,:) = f(n,:) - maxf(n);
end

代码2:

for k=1:K
  sum2 = sum(z(:,k)); 
  p(k)= sum2/N;
  for d=1:D
     % here i had a n loop for sum1 and made it like this:
     sum1 = z(:,k)' * x(:,d); 
     m(k,d) = sum1/sum2;
  end
end

代码3:

L_new = 0;
for n=1:N
  suma = sum(fL(n,:));
  L_new = L_new + maxfL(n) + log(suma);
end

我现在将总结在我的工作负载中使用以下提供的答案的一些平均执行时间(结果以秒为单位)(N = 1000,K = 2,D = 784):

CodeNumber                      Execution Time
    1           3.98(for_loops), 1.01(Divakar), 0.5(Nishant)
    2           0.2(for_loops), 0.40-0.42(Divakar-2 approaches), 0.13(Nishant)
    3           0.03(for_loops), 0.0026(Divakar), 0.0024(Nishant)

感谢您的回答!

【问题讨论】:

  • 由于这是三个不相关的代码,我认为最好将其拆分为三个单独的问题。
  • 它们是相同代码的一部分,它们只是其中的一小部分。有人可以为其中一个、两个或所有三个提供答案。我不相信拆分它们会有好处!
  • Stackoverflow 我们不做部分答案。还是继续吧,zmaxfL 的尺寸是多少?
  • 我在上面的问题中添加了尺寸!
  • code2 中,会不会是for d=1:K

标签: matlab vectorization performance


【解决方案1】:

对于代码 1:

f2 = x*log(m)' + (1-x)*(log(1-m))' ;
f = f2 + ones(N,1)*log(p);
maxf = max(f');
f = f - maxf'*ones(1,K);

对于代码 2:

sum2 = sum(z);
sum1 = z'*x;
temp = sum2'*ones(1,D);
m = sum1./temp;
p  = sum2/N;  

对于代码 3:

L_new = sum(log(sum(fL'))) + sum(maxfL');

【讨论】:

  • 我不认为code3是正确的!我重新运行了我的代码,虽然时间从 ~0.001 减少到 ~0.00001 秒,但 L_new 的输出值与以前不同!
  • 我认为你提到的code1实际上是code2,对吗?
  • 是的,你是对的,检查一下,如果有错误告诉我,我现在正在查看代码 3
  • 对于代码 2 在:m = sum1./sum2;我明白了:???错误使用 ==> rdivide 矩阵维度必须一致。
  • maxFL 是行向量,我也会在上面加上!
【解决方案2】:

试试这些 -

代码 1:

tp1 = squeeze(sum(bsxfun(@times,x,permute(log(m),[3 2 1])),2))
tp2 = squeeze(sum(bsxfun(@times,1-x,permute(log(1-m),[3 2 1])),2))
tp3 = tp1 + tp2
f = bsxfun(@plus,tp3,log(p))
f = bsxfun(@minus,f,max(f,[],2))

代码 2:

p = sum(z)./N;
m = bsxfun(@rdivide,squeeze(sum(bsxfun(@times,x,permute(z,[1 3 2]))))',sum(z)');

代码 2: [方法 2] -

p = sum(z)./N;
sum2_1 = sum(z);
m = zeros(K,D);
for k=1:K  
  m(k,:) = sum(bsxfun(@times,x,z(:,k)))./sum2_1(k);
end

代码 3:(假设您从某处获得 maxfL

L_new = sum(maxfL' + log(sum(fL,2)))

【讨论】:

  • @JohnZobolas 太棒了!确保其他代码运行并检查它们对您的 for 循环代码的执行情况!
  • 代码 2 得到错误的结果,但你也没有计算 p(K) 向量
  • @JohnZobolas 在代码 2 中添加了 p 的计算。好吧,我确实检查了代码 2 的 m 值,所以你能仔细检查一下吗?
  • 你的 code3 比 nishantsny 的快一点!我的算法中的一些平均总执行时间给出:Code3(Divakar)=~0.0024 和 Code3(nishantsny)=~0.0026。太棒了!
  • @JohnZobolas 代码 1 和 2 怎么样?
猜你喜欢
  • 1970-01-01
  • 2020-02-16
  • 2017-02-11
  • 2017-04-16
  • 2015-07-06
  • 2013-02-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多