ForwardDiff.jl和ReverseDiff.jl错误消息与:getfield()有关



我正在尝试使用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编写的库。我确实在整个过程中广泛使用了自定义数据类型(可变结构),但我不明白为什么这会引起问题。。。

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

(::getfield(CalibrationModule, Symbol(...)){...}(...)这样的打印输出就是Julia显示匿名函数和闭包的方式。您得到一个方法错误,即此匿名函数或闭包不支持采用DualTracked数字的Array的签名。你可能有一个类似于的函数

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的任何子类型。我建议你更进一步,不要关心元素类型——你通常不需要关心它

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

相关内容

  • 没有找到相关文章

最新更新