Сообщения об ошибках ForwardDiff.jl и ReverseDiff.jl, связанные с :: getfield () - PullRequest
0 голосов
/ 19 января 2019

Я пытаюсь использовать библиотеки 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})

Я понятия не имею, как понять это сообщение об ошибке. Мой код слишком сложен, чтобы публиковать здесь, но, насколько я могу судить, я не использую библиотеки, написанные не на Джулии. Я широко использую пользовательские типы данных (изменяемые структуры), но не понимаю, почему это может вызвать проблемы ...

Ответы [ 2 ]

0 голосов
/ 31 января 2019

Действительно трудно сказать без кода, но:

Распечатка наподобие (::getfield(CalibrationModule, Symbol(...)){...}(...) - это то, как Юлия отображает анонимные функции и замыкания. Вы получаете ошибку метода, что эта анонимная функция или закрытие не поддерживает подпись, которая принимает Array с Dual или Tracked числами. У вас, вероятно, есть функция, аналогичная:

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

Но и ForwardDiff, и ReverseDiff требуют запуска вашей программы с двойными или отслеживаемыми числами - которые не Float64. Таким образом, вы получаете ошибку метода, что ваше закрытие с именем f не принимает массивы этих двойных или отслеживаемых чисел.

Уменьшите специфичность вашего f замыкания до самого широкого, что он может поддерживать - вероятно, что-то вроде f(A::AbstractArray{<:Number}) = .... Обратите внимание, что две библиотеки делают это немного по-разному - ForwardDiff создает массив Duals, тогда как ReverseDiff создает отслеживаемый массив чисел с плавающей запятой. Таким образом, вы хотите, чтобы оба ::AbstractArray поддерживали больше, чем просто Array s (вы должны почти всегда делать это, если вы не вызываете C), и вы хотите ослабить тип элемента до любого подтипа Number. Я бы порекомендовал пойти еще дальше и не заботиться о типе элемента - вам часто не нужно заботиться об этом.

0 голосов
/ 31 января 2019

Из документов Julia , MethodError: no method matching генерируется, когда нет метода с сигнатурой типа, совпадающей с той, которую вы вызываете.У Джулии есть динамическая система типов, но она позволяет создавать аннотации типов, которые выдают исключение, если значение не относится к ожидаемому типу.Поскольку вы широко используете настраиваемые типы данных, возможно, вы передаете значение настраиваемого типа данных методу в ForwardDiff / ReverseDiff, который ожидает другой тип - трудно подтвердить, не видя код, но именно здесь я 'буду искать.

...