julia - 在 Julia 的函数中使用 Optim 时如何解决此方法错误?
问题描述
我使用 Optim 编写了一个找鞍函数。它工作得很好,但是当我尝试使用框优化时,它给了我一个方法错误。问题是什么?
这有效:
using Optim
function saddle2(f::Function, initx, inity)
# function is assumed to be f(xmin, ymax)
ymax = similar(inity)
function fx(x)
optymax = optimize(y -> -f(vcat(x, y)), inity, NelderMead())
ymax = Optim.minimizer(optymax)
return -Optim.minimum(optymax)
end
optxmin = optimize(fx, repeat([0.0], 6), initx, NelderMead())
xmin = Optim.minimizer(optxmin)
return (f(vcat(xmin, ymax)), xmin, ymax)
end
saddle2(Lsaddle, repeat([0.5], 6), repeat([0.5], 12)) # works!
这不起作用:
using Optim
function saddle(f::Function, initx, inity)
# function is assumed to be f(xmin, ymax)
ymax = similar(inity)
function fx(x)
optymax = optimize(y -> -f(vcat(x, y)), repeat([0.0], 12), repeat([Y], 12), inity, Fminbox(NelderMead()))
ymax = Optim.minimizer(optymax)
return -Optim.minimum(optymax)
end
optxmin = optimize(fx, repeat([0.0], 6), repeat([1.0], 6), initx, Fminbox(NelderMead()))
xmin = Optim.minimizer(optxmin)
return (f(vcat(xmin, ymax)), xmin, ymax)
end
saddle(Lsaddle, repeat([0.5], 6), repeat([0.5], 12)) # doesn't work:
MethodError: no method matching optimize(::getfield(Main, Symbol("##3#5")){Array{Float64,1},typeof(Lsaddle)}, ::Array{Float64,1}, ::Array{Int64,1}, ::Array{Float64,1}, ::Fminbox{NelderMead{Optim.AffineSimplexer,Optim.AdaptiveParameters},Float64,getfield(Optim, Symbol("##46#48"))})
Closest candidates are:
optimize(::Any, ::AbstractArray{T<:AbstractFloat,N} where N, !Matched::AbstractArray{T<:AbstractFloat,N} where N, ::AbstractArray{T<:AbstractFloat,N} where N, ::Fminbox) where T<:AbstractFloat at /Users/amrods/.julia/packages/Optim/ULNLZ/src/multivariate/solvers/constrained/fminbox.jl:163
optimize(::Any, ::AbstractArray{T<:AbstractFloat,N} where N, !Matched::AbstractArray{T<:AbstractFloat,N} where N, ::AbstractArray{T<:AbstractFloat,N} where N, ::Fminbox, !Matched::Any; inplace, autodiff) where T<:AbstractFloat at /Users/amrods/.julia/packages/Optim/ULNLZ/src/multivariate/solvers/constrained/fminbox.jl:163
optimize(::Any, ::AbstractArray, ::AbstractArray, ::AbstractArray, !Matched::SAMIN) at /Users/amrods/.julia/packages/Optim/ULNLZ/src/multivariate/solvers/constrained/samin.jl:60
...
Stacktrace:
[1] (::getfield(Main, Symbol("#fx#4")){typeof(Lsaddle),Array{Float64,1}})(::Array{Float64,1}) at ./In[9]:5
[2] finite_difference_gradient! at /Users/amrods/.julia/packages/DiffEqDiffTools/visbP/src/gradients.jl:282 [inlined]
[3] (::getfield(NLSolversBase, Symbol("#g!#15")){getfield(Main, Symbol("#fx#4")){typeof(Lsaddle),Array{Float64,1}},DiffEqDiffTools.GradientCache{Nothing,Nothing,Nothing,Val{:central},Float64,Val{true}}})(::Array{Float64,1}, ::Array{Float64,1}) at /Users/amrods/.julia/packages/NLSolversBase/KG9Ie/src/objective_types/oncedifferentiable.jl:56
[4] gradient!!(::OnceDifferentiable{Float64,Array{Float64,1},Array{Float64,1}}, ::Array{Float64,1}) at /Users/amrods/.julia/packages/NLSolversBase/KG9Ie/src/interface.jl:63
[5] optimize(::OnceDifferentiable{Float64,Array{Float64,1},Array{Float64,1}}, ::Array{Float64,1}, ::Array{Float64,1}, ::Array{Float64,1}, ::Fminbox{NelderMead{Optim.AffineSimplexer,Optim.AdaptiveParameters},Float64,getfield(Optim, Symbol("##46#48"))}, ::Optim.Options{Float64,Nothing}) at /Users/amrods/.julia/packages/NLSolversBase/KG9Ie/src/interface.jl:51
[6] #optimize#53 at /Users/amrods/.julia/packages/Optim/ULNLZ/src/multivariate/solvers/constrained/fminbox.jl:164 [inlined]
[7] optimize at /Users/amrods/.julia/packages/Optim/ULNLZ/src/multivariate/solvers/constrained/fminbox.jl:163 [inlined] (repeats 2 times)
[8] saddle(::typeof(Lsaddle), ::Array{Float64,1}, ::Array{Float64,1}) at ./In[9]:9
[9] top-level scope at In[13]:1
解决方案
问题是在您的代码Y
中是Int
not Float64
。很可能你写过类似的东西Y = 1
,你应该写过Y = 1.0
。
如果您对定义方式没有影响,请Y
编写:
optimize(y -> -f(vcat(x, y)), repeat([0.0], 12), repeat(Float64[Y], 12), inity, Fminbox(NelderMead()))
或者
optimize(y -> -f(vcat(x, y)), repeat([0.0], 12), fill(Float64(Y), 12), inity, Fminbox(NelderMead()))
如果您发布了完全可重现的代码,我会更容易诊断问题。
编辑
您可以通过以下方式跟踪此问题。阅读错误信息:
MethodError: no method matching optimize(::getfield(Main, Symbol("##3#5")){Array{Float64,1},typeof(Lsaddle)}, ::Array{Float64,1}, ::Array{Int64,1}, ::Array{Float64,1}, ::Fminbox{NelderMead{Optim.AffineSimplexer,Optim.AdaptiveParameters},Float64,getfield(Optim, Symbol("##46#48"))})
Closest candidates are:
optimize(::Any, ::AbstractArray{T<:AbstractFloat,N} where N, !Matched::AbstractArray{T<:AbstractFloat,N} where N, ::AbstractArray{T<:AbstractFloat,N} where N, ::Fminbox) where T<:AbstractFloat at /Users/amrods/.julia/packages/Optim/ULNLZ/src/multivariate/solvers/constrained/fminbox.jl:163
optimize(::Any, ::AbstractArray{T<:AbstractFloat,N} where N, !Matched::AbstractArray{T<:AbstractFloat,N} where N, ::AbstractArray{T<:AbstractFloat,N} where N, ::Fminbox, !Matched::Any; inplace, autodiff) where T<:AbstractFloat at /Users/amrods/.julia/packages/Optim/ULNLZ/src/multivariate/solvers/constrained/fminbox.jl:163
optimize(::Any, ::AbstractArray, ::AbstractArray, ::AbstractArray, !Matched::SAMIN) at /Users/amrods/.julia/packages/Optim/ULNLZ/src/multivariate/solvers/constrained/samin.jl:60
...
你会发现你可以怀疑optimize
forFminbox
只接受AbstractFloat
. 确保运行:
julia> methodswith(Fminbox, supertypes=true)
[1] summary(F::Fminbox) in Optim at C:\Users\bogum\.julia\packages\Optim\ULNLZ\src\multivariate\solvers\constrained\fminbox.jl:117
[2] optimize(df::OnceDifferentiable, l::AbstractArray{T,N} where N, u::AbstractArray{T,N} where N, initial_x::AbstractArray{T,N} where N, F::Fminbox) where T<:AbstractFloat in Optim at C:\Users\bogum\.julia\packages\Optim\ULNLZ\src\multivariate\solvers\constrained\fminbox.jl:175
[3] optimize(df::OnceDifferentiable, l::AbstractArray{T,N} where N, u::AbstractArray{T,N} where N, initial_x::AbstractArray{T,N} where N, F::Fminbox, options) where T<:AbstractFloat in Optim at C:\Users\bogum\.julia\packages\Optim\ULNLZ\src\multivariate\solvers\constrained\fminbox.jl:175
[4] optimize(df::OnceDifferentiable, l::Array{T,N} where N, u::Array{T,N} where N, F::Fminbox{O,T,P} where P where T) where {T<:AbstractFloat, O<:AbstractOptimizer} in Optim at C:\Users\bogum\.julia\packages\Optim\ULNLZ\src\deprecate.jl:67
[5] optimize(f, l::AbstractArray{T,N} where N, u::AbstractArray{T,N} where N, initial_x::AbstractArray{T,N} where N, F::Fminbox) where T<:AbstractFloat in Optim at C:\Users\bogum\.julia\packages\Optim\ULNLZ\src\multivariate\solvers\constrained\fminbox.jl:163
[6] optimize(f, l::AbstractArray{T,N} where N, u::AbstractArray{T,N} where N, initial_x::AbstractArray{T,N} where N, F::Fminbox, options) where T<:AbstractFloat in Optim at C:\Users\bogum\.julia\packages\Optim\ULNLZ\src\multivariate\solvers\constrained\fminbox.jl:163
[7] optimize(f, g, l::AbstractArray{T,N} where N, u::AbstractArray{T,N} where N, initial_x::AbstractArray{T,N} where N, F::Fminbox) where T<:AbstractFloat in Optim at C:\Users\bogum\.julia\packages\Optim\ULNLZ\src\multivariate\solvers\constrained\fminbox.jl:150
[8] optimize(f, g, l::AbstractArray{T,N} where N, u::AbstractArray{T,N} where N, initial_x::AbstractArray{T,N} where N, F::Fminbox, options) where T<:AbstractFloat in Optim at C:\Users\bogum\.julia\packages\Optim\ULNLZ\src\multivariate\solvers\constrained\fminbox.jl:150
并且您确定所有optimize
接受的方法都Fminbox
需要AbstractFloat
. 从理论上讲,您要求的这种自动提升是可能的,但正如您所看到的,它没有实现,所以您只需要记住将AbstractFloat
参数传递给optimize
.
默认情况下,Julia 不会像这样执行自动升级。这是一个最小的例子:
julia> f(x::Vector{Float64}) = x
f (generic function with 1 method)
julia> f([1,2,3])
ERROR: MethodError: no method matching f(::Array{Int64,1})
Closest candidates are:
f(::Array{Float64,1}) at REPL[9]:1
Stacktrace:
[1] top-level scope at none:0
推荐阅读
- javascript - 如何让 JavaScript 检测变量 c 何时更改并执行某些操作?
- spring-boot - 如何将 spring-boot web 应用程序转换为非 web 应用程序
- javascript - 我的 AJAX 调用没有同时运行
- python - 您将如何压缩此代码? - Python
- javascript - 从 .load jquery 返回到 div 框的默认内容
- xamarin - Xamarin:android 10中的多个请求网络弹出,当尝试连接到IOT模块中的wifi时
- android-studio - 错误:没有内容提供者:“整个 uri 出现在这里”
- excel - SSIS在有数据时将列读取为NULL
- python - Flask 错误请求错误(错误请求浏览器(或代理)发送了此服务器无法理解的请求。)
- qml - QT5:未找到 QTQuick.Controls 2.12 版