我有一个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

这是一个示例,说明如何结合gdoptimizeLineSearches
最小化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


现在,我们可以将gdoptimizeBackTracking一起使用来优化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)

09-25 21:18