2017-07-11 26 views
2
m,n =size(l.x) 
for batch=1:m 
    l.ly = l.y[batch,:] 
    l.jacobian .= -l.ly .* l.ly' 
    l.jacobian[diagind(l.jacobian)] .= l.ly.*(1.0.-l.ly) 
    # # n x 1 = n x n * n x 1 
    l.dldx[batch,:] = l.jacobian * DLDY[batch,:] 
end 
return l.dldx 

l.xは、mであり、nマトリクスである。 l.yは、l.xと同じサイズの別の行列です。私の目標は、別のmn行列、l.dldxで作成することです。各行はforループ内での演算の結果です。このコードブロックをさらに最適化することができますか?上記のコードはhttps://github.com/stevenygd/NN.jlの一部です。ループ/ mallocを避けるために以下のjuliaコードをリファクタリングする方法はありますか?

答えて

1

以下は同じ計算を実装し、より効率的であるべきである。

l.dldx = l.y .* (DLDY .- sum(l.y .* DLDY , 2)) 

ループにsumをリファクタリングすることにより利用可能なわずかな改善があるかもしれません。

質問には実行可能コードやテストケースがありませんので、明確なベンチマークを与えるのは難しいので、フィードバックを歓迎します。ここで

UPDATE

は、明示的なループを有する上記のコードです:

function calc_dldx(y,DLDY) 
    tmp = zeros(eltype(y),size(y,1)) 
    dldx = similar(y) 
    @inbounds for j=1:size(y,2) 
     for i=1:size(y,1) 
      tmp[i] += y[i,j]*DLDY[i,j] 
     end 
    end 
    @inbounds for j=1:size(y,2) 
     for i=1:size(y,1) 
      dldx[i,j] = y[i,j]*(DLDY[i,j]-tmp[i]) 
     end 
    end 
    return dldx 
end 

ロングバージョンはさらに速く実行する必要があります。コードのパフォーマンスを測定するには、BenchmarkToolsパッケージを使用するのが良い方法です。

+0

2つの 'for'ループに計算をパックすると2つの割り振りになり、さらに5倍の速度向上*が得られます。それは簡単ですが、要求された場合はコードを追加します。 –

+0

コードも追加してください!あなたはジュリアのパフォーマンスの神です。 –

+0

コードブロック全体を1行にリファクタリングする方法についても説明できますか?あなたのコードで、どこにジャコビ行列の対角要素を計算したのか分かりません。 –

関連する問題