私は、自動微分(autodiff=true
)のOptim.jl
を使って次の与えられた関数(quad_function
)を最適化Julia:整数のために `Optim.jl`と` autodiff`を使ってコスト関数を最適化する
私の目的関数は、Real
を整数に丸めて階段状です。
私はautodiff
オプションを使用しているので、私のReal
の値はdual numbers(ForwardDiff.Dual
s)です。しかし残念ながら、ForwardDiff.Dual
タイプのために実装されたround
機能はありません。したがって、私は実際の部分を抽出する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)
これは次のように私のquad_function
がどのように見えるかです:問題は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
私はまた、丸め、物事を避けるために、整数[5,5]
のベクターでoptimize
機能を初期化しようとしたが、それは初期のステップサイズを見つけるのも問題が発生します。
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
に電子メールのみを送信する方法はありますか整数空間をxplore?
更新: 私はInt64
への変換アプローチの問題は、私はもはやForwardDiff.Dual
秒を持っていないので、任意の誘導体/勾配を計算することができないということだと思います。どのようにより良いround
関数は、ネストされたデュアルをラウンドし、二重を返すように見えるかもしれませんか?
グラジエントがゼロであるためアルゴリズムが停止します。あなたの問題は、円滑な関数を期待するソルバーにはあまり適していません。あなたの関数には、MIQP(混合整数二次計画法)ソルバのようなものを試してみてください。 –
ありがとうございます@ErwinKalvelagen私はそれをチェックします。しかし、ソルバーがそれに適していない限り、私がやろうとしているこの種のマッピングを実現する方法が一般的にあると思いますか?なぜなら、私のpersperctiveでは滑らかな関数から離れていないからです。 – swiesend
これは滑らかではなく、ローカルnlpソルバが停止することになるゼログラデーションを持つこれらの領域をすべて持っています。これは本当に本質的に離散的な問題の間違った技術です。 –