有没有办法重构下面的 julia 代码以避免 loop/malloc?
Is there a way to refactor the julia code below in order to avoid the loop/malloc?
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
大小相同的矩阵。我的目标是创建另一个 m
by n
矩阵,l.dldx
,其中每一行都是 for 循环内操作的结果。任何人都可以发现此代码块的进一步优化吗?上面的代码是 https://github.com/stevenygd/NN.jl.
的一部分
下面应该实现相同的计算并且效率更高:
l.dldx = l.y .* (DLDY .- sum( l.y .* DLDY , 2))
将 sum
重构为一个循环可能会有轻微的改进。
由于问题没有运行可用代码或测试用例,因此很难给出明确的基准,因此欢迎反馈。
更新
这是上面带有显式循环的代码:
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 包。
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
大小相同的矩阵。我的目标是创建另一个 m
by n
矩阵,l.dldx
,其中每一行都是 for 循环内操作的结果。任何人都可以发现此代码块的进一步优化吗?上面的代码是 https://github.com/stevenygd/NN.jl.
下面应该实现相同的计算并且效率更高:
l.dldx = l.y .* (DLDY .- sum( l.y .* DLDY , 2))
将 sum
重构为一个循环可能会有轻微的改进。
由于问题没有运行可用代码或测试用例,因此很难给出明确的基准,因此欢迎反馈。
更新
这是上面带有显式循环的代码:
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 包。