編輯:添加函數頭提示以改善下面的代碼性能計算SOFTMAX衍生物
function backward(l::SoftMax, DLDY::Array{Float64}; kwargs...)
# credits: https://stats.stackexchange.com/questions/79454/softmax-layer-in-a-neural-network?newreg=d1e89b443dd346ae8bccaf038a944221
m,n =size(l.x)
ly = Array{Float64}(n)
for batch=1:m
ly = l.y[batch,:]
for i=1:n
li = ly[i]
l.jacobian[:,i] = -li * ly
l.jacobian[i,i] = li*(1-li)
end
# l.jacobian = ly'.*repmat(ly, 1, n)
# for i=1:n
# li = l.y[batch,i]
# l.jacobian[i,i] = li*(1.0-li)
# end
# # n x 1 = n x n * n x 1
l.dldx[batch,:] = l.jacobian * DLDY[batch,:]
end
return l.dldx
end
以上是我爲我SOFTMAX層的後退功能的代碼。軟件https://stats.stackexchange.com/questions/79454/softmax-layer-in-a-neural-network?newreg=d1e89b443dd346ae8bccaf038a944221中的回答很好地描述了計算softmax導數的方式。在這裏,我正在尋找更有效的方法來計算導數,因爲上面的代碼需要0.05~6
秒才能評估1000乘以100,而之前的softmax +交叉熵組合層僅需要0.002
秒。
我正在尋找一種讓代碼運行更快的方法。我不確定我是否正在使用計算雅可比矩陣的最有效方式,但我嘗試了另一種方法,然後將其與ly
相乘,然後將其乘以ly
。事實證明,情況更糟,因爲顯然朱莉婭的repmat
需要太多的分配。
本質上,我正在尋找一種有效的方法來將數組與數組中的每個元素相乘,並將結果連接成方矩陣。任何朱莉婭大師對此有何看法?謝謝!
如果問題中存在正在運行的代碼(緩慢,我猜),回答有關速度的問題要容易得多。如果您添加可運行代碼,那麼響應通常很快。 –
我不認爲有辦法在這裏顯示我的「可運行」代碼,因爲它相對龐大而複雜。除了這部分真的讓代碼變得緩慢外,它實際上是將函數「落後」,我提出這個問題。我相信我在功能上要達到的目標應該是比較明顯的,同時我也盡力用文字來形容。正如我在原始文章中所說的,第二個循環'i = 1:n'是需要最多時間的東西,並且是通過在此處發佈代碼進行優化的主要部分。如果您對我的代碼有任何疑問,我也很樂意澄清。 –