欲说还休,欲说还休。却道天凉好个秋. — 辛弃疾
🏰代码及环境配置:请参考 环境配置和代码运行!
本节提供了 线搜索方法的代码测试:
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更优.