首页 > 解决方案 > 为什么我在 Julia 中编写的这个 softmax 函数不会改变输入数据?

问题描述

我在 Julia 中编写了 softmax 函数。它逐行对矩阵执行softmax并更改矩阵。但是,当我在 REPL 中调用该函数时,它对矩阵没有影响。我不明白为什么会这样,我真的很想解释一下。

"""
the following function performs softmax on a design matrix row by row
inputs: X:mxn matrix
output: none
"""
function softmax!(X::Array{Float64,2})
    X = exp.(X)
    for i = 1:size(X,1)
        rowsum = sum(X[i,:])
        X[i,:] /= rowsum
    end
end

这是 REPL 中的一个示例调用:

julia> a = rand(2,5)
2×5 Array{Float64,2}:
 0.069014  0.265159  0.489641  0.455672  0.0489479
 0.274386  0.935308  0.41976   0.509558  0.234294

julia> softmax!(a)

julia> a
2×5 Array{Float64,2}:
 0.069014  0.265159  0.489641  0.455672  0.0489479
 0.274386  0.935308  0.41976   0.509558  0.234294

如您所见,矩阵没有变化。非常奇怪的是,如果我硬编码 REPL 中函数内部的内容,我会得到预期的效果。

julia> a = exp.(a)
2×5 Array{Float64,2}:
 1.07145  1.30364  1.63173  1.57723  1.05017
 1.31572  2.548    1.5216   1.66456  1.26402

julia>     for i = 1:size(a,1)
               rowsum = sum(a[i,:])
               a[i,:] /= rowsum
           end

julia> a
2×5 Array{Float64,2}:
 0.161504  0.196502  0.245957  0.237742  0.158295
 0.158256  0.306475  0.183019  0.200214  0.152037

我知道有些东西我不理解,但我不知道那可能是什么。任何帮助都感激不尽 :)

标签: neural-networkjulia

解决方案


您需要替换X = exp.(X)X .= exp.(X). Julia 是通过共享传递的,所以当你X = exp.(X)从那一刻开始说,X你的函数中的和X你传入的引用不同的内存。

另请注意,此方法效率相当低,因为 julia 使用列主矩阵。如果你转置你的问题并写下,

function softmax!(X::Array{Float64,2})
    X .= exp.(X)
    for j = 1:size(X,2)
        @views rowsum = sum(X[:,j])
        X[:,j] .*= 1/rowsum
    end
end

它将快约 2 倍


推荐阅读