我有L-BFGS的实现,并希望从LineSearches.jl调用行搜索进行比较。但是,文档非常稀疏,仅关注在Optim.jl的上下文中使用Linesearches.jl。我找不到任何如何独立使用Linesearches.jl的例子。
答案 0 :(得分:0)
我创建了一个示例,说明如何在custom-made optimizer中使用LineSearches
算法和latest
documentation。
请注意,该示例目前需要LineSearches master
,但很快就会在v6.0.0
中提供。
以下是完整示例,以防链接中断:( 编辑:使用简化流程的新示例代码进行了更新。)
假设我们已经编写了梯度下降优化算法,但我想这样做 尝试不同的线搜索算法。 算法实现如下。
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!
包含在算法中,
即使Gradient Descent算法没有明确地使用它,许多LineSearches算法也会这样做。
Gradient Descent gdoptimize
方法选择下降方向并调用
行搜索算法linesearch
返回步长α
和
客观价值fx = f(x + α*s)
。
函数φ和dφ表示单变量目标
及其衍生物,由线搜索算法使用。
要在优化器中使用fg!
函数调用,请进行一些行搜索
需要一个函数φdφ,它返回单变量目标和
同时衍生出来。
以下是一个示例,说明我们如何合并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)