2017-07-11 60 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.xmn矩陣。 l.y是另一個與l.x大小相同的矩陣。我的目標是通過n matrix,l.dldx創建另一個m,其中每行都是for循環內部操作的結果。任何一個可以進一步優化這段代碼?上面的代碼是https://github.com/stevenygd/NN.jl的一部分。有沒有辦法重構下面的朱莉婭代碼,以避免循環/ malloc?

回答

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

將計算打包成幾個'for'循環將其降至2個分配,並給*另一個5倍速度提升*。這是微不足道的,但我會在需要時添加代碼。 –

+0

請添加代碼!你是朱莉婭演出中的上帝。 –

+0

你也可以解釋一下如何將整個代碼塊重構爲一行?我不明白在你的代碼中你計算了雅可比矩陣的對角線條目。 –