quad_function
我喜欢通过使用Optim.jl
自动微分( )来优化(最小化)以下给定函数(autodiff=true
)。
我的目标函数将值四舍五入 Real
为整数,因此是阶梯式的。
当我使用该autodiff
选项时,我的Real
值得到双数(ForwardDiff.Dual
s)。但不幸的是round
,该类型没有实现任何功能ForwardDiff.Dual
。因此,我编写了一个roundtoint64
函数,它提取实部。这种方法在优化过程中会引起问题。
using Plots
plotlyjs()
function roundtoint64(x)
if typeof(x) <: ForwardDiff.Dual
roundtoint64(x.value)
else
Int64(round(x))
end
end
function quad_function(xs::Vector)
roundtoint64(xs[1])^2 + roundtoint64(xs[2])^2
end
x, y = linspace(-5, 5, 100), linspace(-5, 5, 100)
z = Surface((x,y)->quad_function([x,y]), x, y)
surface(x,y,z, linealpha = 0.3)
问题是,optimize
函数会立即收敛并且不会继续进行。
using Optim
res = Optim.optimize(
quad_function,
[5.0,5.0],
Newton(),
OptimizationOptions(
autodiff = true,
# show_trace = true
))
结果:
Results of Optimization Algorithm
* Algorithm: Newton's Method
* Starting Point: [5.0,5.0]
* Minimizer: [5.0,5.0]
* Minimum: 5.000000e+01
* Iterations: 0
* Convergence: true
* |x - x'| < 1.0e-32: false
* |f(x) - f(x')| / |f(x)| < 1.0e-32: false
* |g(x)| < 1.0e-08: true
* Reached Maximum Number of Iterations: false
* Objective Function Calls: 1
* Gradient Calls: 1
optimal_values = Optim.minimizer(res) # [5.0, 5.0]
optimum = Optim.minimum(res) # 50.0
我还尝试optimize
使用整数向量初始化函数[5,5]
以避免四舍五入,但这也会导致在以下位置找到初始步长的问题:
ERROR: InexactError()
in alphainit(::Int64, ::Array{Int64,1}, ::Array{Int64,1}, ::Int64) at /home/sebastian/.julia/v0.5/Optim/src/linesearch/hz_linesearch.jl:63
in optimize(::Optim.TwiceDifferentiableFunction, ::Array{Int64,1}, ::Optim.Newton, ::Optim.OptimizationOptions{Void}) at /home/sebastian/.julia/v0.5/Optim/src/newton.jl:69
in optimize(::Function, ::Array{Int64,1}, ::Optim.Newton, ::Optim.OptimizationOptions{Void}) at /home/sebastian/.julia/v0.5/Optim/src/optimize.jl:169
问题:有没有办法告诉optimize
只探索整数空间?
更新:
我认为转换方法的问题Int64
是我不再有ForwardDiff.Dual
s ,因此无法计算任何导数/梯度。一个更好的round
函数会是什么样子,哪些回合还嵌套了对偶并返回对偶?