0

我正在尝试使用 ForwardDiff.jl 和/或 ReverseDiff.jl 库来计算优化问题中的梯度。

这两个包都给我一个与 ::getfield() 相关的错误消息。

ReverseDiff 给了我一个 LoadError:

 MethodError: no method matching (::getfield(CalibrationModule, Symbol("#f#4"))
 {AlgorithmParameters,ModelParameters,Guess,Array{Float64,1}})
 (::ReverseDiff.TrackedArray{Float64,Float64,1,Array{Float64,1},Array{Float64,1}})

ForwardDiff 给了我一个 LoadError:

 MethodError: no method matching (::getfield(CalibrationModule, Symbol("#f#10"))
 {AlgorithmParameters,ModelParameters,Guess,Array{Float64,1}})
 (::Array{ForwardDiff.Dual{ForwardDiff.Tag{getfield(CalibrationModule,
 Symbol("#f#10"))     
 {AlgorithmParameters,ModelParameters,Guess,Array{Float64,1}},Float64},Float64,6},1})

我不知道如何理解这个错误信息。我的代码太复杂,无法在这里发布,但据我所知,我没有使用任何不是用 Julia 编写的库。我确实在整个过程中广泛使用自定义数据类型(可变结构),但我不明白为什么这会导致问题......

4

2 回答 2

1

从 Julia文档中,MethodError: no method matching当没有与您正在调用的方法具有匹配类型签名的方法时,会抛出 。Julia 有一个动态类型系统,但允许类型注释在值不是预期类型时抛出异常。由于您广泛使用自定义数据类型,因此您可能会将自定义数据类型的值传递给 ForwardDiff/ReverseDiff 中需要不同类型的方法 - 很难在没有看到代码的情况下确认,但这就是我的地方d 开始寻找。

于 2019-01-30T21:12:58.443 回答
1

没有代码真的很难说,但是:

(::getfield(CalibrationModule, Symbol(...)){...}(...)像Julia 显示匿名函数和闭包这样的打印输出。您收到一个方法错误,表明此匿名函数或闭包不支持采用Arraywith Dualor 或Trackednumbers 的签名。您可能具有以下功能:

function main()
    ...
    f(A::Array{Float64}) = # ... some closure
    ...
    f(...)
end

但是 ForwardDiff 和 ReverseDiff 都需要使用双号或跟踪号运行您的程序 - 而不是Float64. 所以你得到一个方法错误,你的闭包命名f不接受这些对偶或跟踪数字的数组。

将闭包的特殊性降低f到它可以支持的最广泛的范围——可能类似于f(A::AbstractArray{<:Number}) = .... 请注意,这两个库的做法略有不同——ForwardDiff 创建一个 Duals 数组,而 ReverseDiff 创建一个跟踪的浮点数数组。因此,您希望两者都::AbstractArray支持的不仅仅是Arrays(除非您调用 C,否则您几乎应该总是这样做)并且您希望将元素类型放松为Number. 我建议走得更远,不要关心元素类型——你通常不需要关心它。

于 2019-01-30T22:26:48.027 回答