3

ForwardDiff.jlこの機能を使用して関数を定義し、その勾配をプロットしたいだけです(を使用して評価ForwardDiff.gradient)。の出力ForwardDiff.gradientはこの奇妙なDual型のものであり、目的の型 (私の場合は Float32 の 1-D 配列) に簡単に変換されないため、機能していないようです。

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)。関数定義と関係があると思いますが、1行で定義されていないことを除けば、私が定義した方法がクリストファーのバージョンとどのように違うのかわかりません...これはとても混乱しています。

ForwardDiffのドキュメントによると、入力のタイプがReal-Float32のサブタイプであり、Real のサブタイプである必要があるため、これは機能するはずです。

編集:他の人からのコメントを読んだ今、関数を制限して抽象型の入力を受け入れるのに十分な汎用性を持たせる必要があることに気付きましたReal。混乱をお詫び申し上げます。

4

1 に答える 1