【动手学运动规划】 5.3.c 线搜索方法代码解析

欲说还休,欲说还休。却道天凉好个秋. — 辛弃疾

🏰代码及环境配置:请参考 环境配置和代码运行!


本节提供了 线搜索方法的代码测试:

python tests/optimization/line_search_test.py

5.3.c.1 优化问题

在中定义了一个3维空间的二次函数:

min ⁡   f ( x ) = x 2 + 6 y 2 \min \ f(x)= x^2+6y^2 min f(x)=x2+6y2

显然, 这是一个凸函数并且最小点在 ( 0 , 0 ) (0, 0) (0,0).

函数和函数导数如下:

def function(x) -> float:
    return x[0] ** 2 + 6 * x[1] ** 2

def function_gradient(x):
    return np.array([x[0] * 2, x[1] * 12])

5.3.c.2 Armijo准则代码解析

armijo(x, d) 函数中, 我们定义了基于Armijo准则的线搜索方法.

输入决策变量x和下降方向d, 在while 循环中, 不停的缩小

def armijo(x, d) -> float:
    c1 = 1e-3
    gamma = 0.9
    alpha = 1.0

    while function(x + alpha * d) > function(x) + c1 * alpha * np.dot(
        function_gradient(x).T, d
    ):
        alpha = gamma * alpha
    return alpha

5.3.c.3 Goldstein准则代码解析

goldstein(x, d)中, 我们使用了二分的方式, 快速找到满足两个不等式要求的点.

def goldstein(x, d):

    a = 0
    b = np.inf
    alpha = 1
    c1 = 0.1  # 可接受系数
    c2 = 1 - c1
    beta = 2  # 试探点系数

    while np.fabs(a - b) > 1e-5:
        if function(x + alpha * d) <= function(x) + c1 * alpha * np.dot(
            function_gradient(x).T, d
        ):
            if function(x + alpha * d) >= function(x) + c2 * alpha * np.dot(
                function_gradient(x).T, d
            ):
                break
            else:
                a = alpha
                # alpha = (a + b) / 2
                if b < np.inf:
                    alpha = (a + b) / 2
                else:
                    alpha = beta * alpha
        else:
            b = alpha
            alpha = (a + b) / 2

    return alpha

5.3.c.3 Wolfe准则代码解析

类似的, 在wolfe(x, d)中, 也使用了二分的方式, 快速找到满足两个不等式要求的点.

def wolfe(x, d):

    c1 = 0.3
    c2 = 0.9
    alpha = 1
    a = 0
    b = np.inf
    while a < b:
        if function(x + alpha * d) <= function(x) + c1 * alpha * np.dot(
            function_gradient(x).T, d
        ):
            if np.dot(function_gradient(x + alpha * d).T, d) >= c2 * alpha * np.dot(
                function_gradient(x).T, d
            ):
                break
            else:
                a = alpha
                alpha = (a + b) / 2
        else:
            b = alpha
            alpha = (a + b) / 2

    return alpha

5.3.c.4 不同线搜索方法测试

line_search_test() 中, 定义了初始点 ( − 5 , 8 ) (-5, 8) (5,8), 基于梯度下降法, 使用不同的线搜索方法求最优解.

def line_search_test():
    x0 = np.array([-5, 8])

    solution, armijo_x_i = gradient_descent_optimize(copy.deepcopy(x0), armijo)
    solution, goldstein_x_i = gradient_descent_optimize(copy.deepcopy(x0), goldstein)
    solution, wolfe_x_i = gradient_descent_optimize(copy.deepcopy(x0), wolfe)

测试结果如下:

  • Armijo: Step 67:[-1.77436662e-10 -5.51975406e-06]
  • Goldstein: Step 35:[-1.24015340e-05 -3.81469727e-06]
  • Wolfe: Step 35:[-1.89816443e-05 -2.27373675e-06]

可以看到Armijo方法迭代次数最多, Wolfe在前几次迭代时, 路径比Goldstein更优.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值