我只想使用该ForwardDiff.jl
功能来定义一个函数并绘制它的梯度(使用 评估ForwardDiff.gradient
)。它似乎不起作用,因为它的输出ForwardDiff.gradient
是这种奇怪Dual
的类型,并且不容易转换为所需的类型(在我的情况下,是 Float32s 的一维数组)。
using Plots
using ForwardDiff
my_func(x::Array{Float32,1}) = 1f0. / (1f0 .+ exp(3f0 .* x)) # doesn't matter what this is, just a sigmoid function here
grad_f(x::Array{Float32,1}) = ForwardDiff.gradient(my_func, x)
x_values = collect(Float32,0:0.01:10)
plot(x_values,my_func(x_values)); # this works fine
plot!(x_values,grad_f(x_values)); # this throws an error
这是我得到的错误:
ERROR: MethodError: no method matching Float64(::ForwardDiff.Dual{ForwardDiff.Tag{typeof(g),Float32},Float64,12})
当我检查 的类型时grad_f(x_values)
,我得到了这个:
Array{Array{ForwardDiff.Dual{ForwardDiff.Tag{typeof(g),Float32},Float32,12},1},1}
例如,为什么在 ForwardDiff 文档的示例中没有发生这种情况?见这里:https ://github.com/JuliaDiff/ForwardDiff.jl
提前致谢。
编辑:在 Kristoffer Carlsson 的评论之后:我试过这个,但它仍然不起作用。我不明白我在这里尝试的内容与他的建议有何不同:
function g(x::Float32)
return x / (1f0 + exp(10f0 * (x - 5f0)))
end
function ∂g∂x(x::Float32)
return ForwardDiff.derivative(g, x)
end
x_vals = collect(Float32,0:0.01:10)
plot(x_vals,g.(x_vals))
plot!(x_vals,∂g∂x.(x_vals))
现在的错误是:
no method matching g(::ForwardDiff.Dual{ForwardDiff.Tag{typeof(g),Float32},Float32,1})
这个错误发生在我打电话的时候∂g∂x(x)
,无论我是否使用广播版本∂g∂x.(x)
。我想这与函数定义有关,但我看不出我定义它的方式与 Kristoffer 的版本有何不同,除了它没有在一行中定义......这太令人困惑了。
这应该可行,因为根据ForwardDiff
的文档,您只需要输入的类型是Real
- 的子类型并且Float32
是 Real 的子类型。
编辑:我现在意识到,在阅读了其他人的评论后,您需要将您的函数限制为足够通用以接受抽象类型的任何输入Real
,我并没有从文档中完全收集到。为混乱道歉。