我有一个L-BFGS的实现,想从LineSearches.jl调用line-search进行比较。但是,该文档非常稀疏,仅关注在Optim.jl上下文中使用Linesearches.jl。我找不到如何独立使用Linesearches.jl的任何示例。
最佳答案
我创建了一个示例,说明如何将LineSearches
算法与custom-made optimizer中的latest
documentation一起使用。
请注意,该示例当前需要LineSearches master
,但不久后应在v6.0.0
中可用。
如果链接断开,这是完整的示例:(编辑:更新了新的示例代码,以简化过程。)
在没有Optim / NLsolve的情况下使用LineSearches
假设我们已经编写了梯度下降优化算法,但想
试验不同的线搜索算法。
该算法实现如下。
function gdoptimize(f, g!, fg!, x0::AbstractArray{T}, linesearch,
maxiter::Int = 10000,
g_rtol::T = sqrt(eps(T)), g_atol::T = eps(T)) where T <: Number
x = copy(x0)
gvec = similar(x)
g!(gvec, x)
fx = f(x)
gnorm = norm(gvec)
gtol = max(g_rtol*gnorm, g_atol)
# Univariate line search functions
ϕ(α) = f(x .+ α.*s)
function dϕ(α)
g!(gvec, x .+ α.*s)
return vecdot(gvec, s)
end
function ϕdϕ(α)
phi = fg!(gvec, x .+ α.*s)
dphi = vecdot(gvec, s)
return (phi, dphi)
end
s = similar(gvec) # Step direction
iter = 0
while iter < maxiter && gnorm > gtol
iter += 1
s .= -gvec
dϕ_0 = dot(s, gvec)
α, fx = linesearch(ϕ, dϕ, ϕdϕ, 1.0, fx, dϕ_0)
@. x = x + α*s
g!(gvec, x)
gnorm = norm(gvec)
end
return (fx, x, iter)
end
请注意,有许多优化和行搜索算法可以
用户可以同时评估物镜和梯度
计算效率的原因。
我们已将此功能作为输入函数
fg!
包含在算法中,即使“梯度下降”算法未明确使用它,许多LineSearches算法也可以使用。
渐变下降
gdoptimize
方法选择下降方向并调用线搜索算法
linesearch
,它返回步长α
和目标值
fx = f(x + α*s)
。函数ϕ和dϕ表示单变量目标
及其派生词,供线搜索算法使用。
为了利用优化器中的
fg!
函数调用,一些行搜索要求函数ϕdϕ返回单变量目标,并且
同时衍生。
优化Rosenbrock
这是一个示例,说明如何结合
gdoptimize
和LineSearches
最小化Rosenbrock函数,该函数由
f(x) = (1.0 - x[1])^2 + 100.0 * (x[2] - x[1]^2)^2
function g!(gvec, x)
gvec[1] = -2.0 * (1.0 - x[1]) - 400.0 * (x[2] - x[1]^2) * x[1]
gvec[2] = 200.0 * (x[2] - x[1]^2)
gvec
end
function fg!(gvec, x)
g!(gvec, x)
f(x)
end
现在,我们可以将
gdoptimize
与BackTracking
一起使用来优化Rosenbrock函数从给定的初始条件
x0
。x0 = [-1., 1.0]
using LineSearches
ls = BackTracking(order=3)
fx_bt3, x_bt3, iter_bt3 = gdoptimize(f, g!, fg!, x0, ls)
有趣的是,
StrongWolfe
行搜索在一次迭代中收敛,而所有其他算法都需要进行数千次迭代。
由于初始条件的特殊选择,这只是运气
ls = StrongWolfe()
fx_sw, x_sw, iter_sw = gdoptimize(f, g!, fg!, x0, ls)