梯度下降算法
一、梯度下降算法本文介绍梯度下降算法,其本质是仅仅使用函数的一阶导数信息选取下降方向dkd_kdk。梯度下降法的方向选取非常直观,实际应用范围非常广,因此它在优化算法中的地位可相当于高斯消元法在线性方程组中的地位。此外我们也会介绍BB方法,该方法作为一种梯度法的变形,虽然理论性质目前仍不完整,但由于优秀的数值表现,也是在实际应用中使用较多的一种算法。对于光滑函数f(x)f(x)f(x),在迭代点
一、梯度下降算法
本文介绍梯度下降算法,其本质是仅仅使用函数的一阶导数信息选取下降方向
d
k
d_k
dk。梯度下降法的方向选取非常直观,实际应用范围非常广,因此它在优化算法中的地位可相当于高斯消元法在线性方程组中的地位。此外我们也会介绍BB方法,该方法作为一种梯度法的变形,虽然理论性质目前仍不完整,但由于优秀的数值表现,也是在实际应用中使用较多的一种算法。
对于光滑函数
f
(
x
)
f(x)
f(x),在迭代点
x
k
x_k
xk处,我们需要选择一个较为合理的
d
k
d_k
dk作为下降方向。注意到
ϕ
(
α
)
=
f
(
x
k
+
α
d
k
)
\phi(\alpha)=f(x_k+\alpha d_k)
ϕ(α)=f(xk+αdk)有泰勒展开
ϕ
(
α
)
=
f
(
x
k
)
+
α
∇
f
(
x
k
)
T
d
k
+
O
(
α
2
∣
∣
d
k
∣
∣
2
)
\phi(\alpha)=f(x_k)+\alpha\nabla f(x_k)^Td_k+O(\alpha^2||d_k||^2)
ϕ(α)=f(xk)+α∇f(xk)Tdk+O(α2∣∣dk∣∣2)
根据柯西不等式,当
α
\alpha
α足够小时,取
d
k
=
−
∇
f
(
d
k
)
d_k=-\nabla f(d_k)
dk=−∇f(dk)会使得函数下降最快。因此梯度法就是选取
d
k
=
−
∇
f
(
x
k
)
d_k=-\nabla f(x_k)
dk=−∇f(xk)的算法,它的迭代格式为:
x
k
+
1
=
x
k
−
α
k
∇
f
(
x
k
)
.
x_{k+1}=x_k-\alpha_k\nabla f(x_k).
xk+1=xk−αk∇f(xk).
其中步长
α
k
\alpha_k
αk的选取可依赖于一维线搜索,也可直接选取固定的步长。
二、梯度下降法的收敛性
本节不加证明的给出梯度下降发的收敛性定理:
定理1(梯度法在凸函数上的收敛性):设函数
f
(
x
)
f(x)
f(x)为凸的梯度L-利普希茨连续函数,
f
∗
=
f
(
x
∗
)
=
inf
x
f
(
x
)
f^*=f(x^*)=\inf\limits_x f(x)
f∗=f(x∗)=xinff(x)存在且可达。如果步长
α
k
\alpha_k
αk取为常数
α
\alpha
α且满足
0
<
α
≤
1
L
0\lt \alpha\le\frac{1}{L}
0<α≤L1,那么梯度下降的电联
{
x
k
}
\{x_k\}
{xk}的函数值收敛到最优值,且在函数值的意义下收敛速度为
O
(
1
k
)
O(\frac{1}{k})
O(k1)
三、Barzilar-Borwein方法
Barzilar-Borwein方法又简称BB法,从形式上来看BB法的下降方向仍然是点
x
k
x_k
xk处的负梯度方向
−
∇
f
(
x
k
)
-\nabla f(x_k)
−∇f(xk),但步长
α
k
\alpha_k
αk并不是直接由线搜索算法给出的。考虑梯度下降法的格式
x
k
+
1
=
x
k
−
α
k
∇
f
(
x
k
)
x_{k+1}=x_k-\alpha_k\nabla f(x_k)
xk+1=xk−αk∇f(xk)
这种格式也可以写成
x
k
+
1
=
x
k
−
D
k
∇
f
(
x
k
)
x_{k+1}=x_k-D_k\nabla f(x_k)
xk+1=xk−Dk∇f(xk)
其中
D
k
=
α
k
I
D_k=\alpha_k I
Dk=αkI,BB法选取的
α
k
\alpha_k
αk是如下两个最优问题之一的解:
min
α
∣
∣
α
y
k
−
1
−
s
k
−
1
∣
∣
2
,
min
α
∣
∣
y
k
−
1
−
α
−
1
s
k
−
1
∣
∣
2
\begin{aligned} & \min\limits_{\alpha}||\alpha y_{k-1}-s_{k-1}||^2,\\ & \min\limits_{\alpha}|| y_{k-1}-\alpha^{-1}s_{k-1}||^2 \end{aligned}
αmin∣∣αyk−1−sk−1∣∣2,αmin∣∣yk−1−α−1sk−1∣∣2
其中我们引入记号
s
k
−
1
=
x
k
−
x
k
−
1
s_{k-1}=x_k-x_{k-1}
sk−1=xk−xk−1以及
y
k
−
1
=
∇
f
(
x
k
)
−
∇
f
(
x
k
−
1
)
y_{k-1}=\nabla f(x_k)-\nabla f(x_{k-1})
yk−1=∇f(xk)−∇f(xk−1),容易求得上述问题的解分别为
α
B
B
1
k
=
(
s
k
−
1
)
T
y
k
−
1
(
y
k
−
1
)
T
y
k
−
1
\alpha_{BB1}^k=\frac{(s_{k-1})^Ty_{k-1}}{(y_{k-1})^Ty_{k-1}}
αBB1k=(yk−1)Tyk−1(sk−1)Tyk−1和
α
B
B
2
k
=
(
s
k
−
1
)
T
s
k
−
1
(
s
k
−
1
)
T
y
k
−
1
\alpha_{BB2}^k=\frac{(s_{k-1})^Ts_{k-1}}{(s_{k-1})^Ty_{k-1}}
αBB2k=(sk−1)Tyk−1(sk−1)Tsk−1,因此可以得到BB方法的两种迭代格式:
x
k
+
1
=
x
k
−
α
B
B
1
k
∇
f
(
x
k
)
,
x
k
+
1
=
x
k
−
α
B
B
2
k
∇
f
(
x
k
)
.
\begin{aligned} x_{k+1}&=x_k-\alpha_{BB1}^k\nabla f(x_k), \\ x_{k+1}&=x_k-\alpha_{BB2}^k\nabla f(x_k). \end{aligned}
xk+1xk+1=xk−αBB1k∇f(xk),=xk−αBB2k∇f(xk).
从两种BB步长的计算公式可知,任何一种仅仅需要函数和相邻亮部的梯度信息和迭代点信息,不需要任何线搜索算法即可选取算法步长。正因为这个特点,BB算法的使用范围特别广泛。对于一般的问题,通过BB步长计算公式得到的步长可能过大或者过小,因此我们还需要将步长做上界和下界的截断,即选取
0
<
α
m
<
α
M
0\lt\alpha_m\lt\alpha_M
0<αm<αM使得
α
m
≤
α
k
≤
α
M
\alpha_m\le\alpha_k\le\alpha_M
αm≤αk≤αM,还需要注意的是,BB方法本身是非单调方法,有时也配合非单调收敛准则使用以获得更好的实际效果。
三、梯度下降法应用举例
应用举例1
对于函数
f
(
x
,
y
)
=
x
2
+
10
y
2
f(x,y)=x^2+10y^2
f(x,y)=x2+10y2,比较固定步长梯度下降算法和BB步长梯度下降算法的计算效率:
固定步长梯度下降法matlab实现
function [fmin, xmin, fk, xk] = gradient_descent_fix_stepsize(func, gfunc, x0, alpha, epsilon)
iIter = 1;
iterMax = 500;
xOld = x0;
xk = zeros(size(x0, 1), 66);
xk(:, 1) = x0;
fk = zeros(1, 66);
while iIter < iterMax
dk = feval(gfunc, xOld);
xNew = xOld - alpha * dk;
if norm(xNew - xOld, 2) <= epsilon
break;
end
iIter = iIter + 1;
xk(:, iIter) = xNew;
fk(:, iIter) = feval(func, xNew);
xOld = xNew;
end
if iIter == iterMax
fprintf('reach maximum iteration, and not found minimal x!\n');
end
xmin = xNew;
fmin = feval(func, xmin);
fprintf('iIter = %d, fmin = %f\n', iIter, fmin);
end
BB步长梯度下降法matlab实现
function [fmin, xmin, fk, xk] = gradient_descent(func, gfunc, x0, epsilon)
iIter = 1;
iterMax = 500;
xOld = x0;
alphaMin = 1e-5;
alphaMax = 1e5;
M = 10;
%alpha = 0.5;
[~, ~, alpha] = armijo_rule(func, gfunc, x0, 0.5, -feval(gfunc, x0));
QOld = 1;
COld = feval(func, xOld);
c1 = 0.5;
eta = 0.5;
xk = zeros(size(x0, 1), 11);
fk = zeros(11, 1);
xk(:, 1) = x0;
fk(1, :) = feval(func, x0);
while iIter < iterMax
grad = feval(gfunc, xOld);
dk = -grad;
% Zhang, Hanger nonmonotone line search
for i = 1:M
xNew = xOld + alpha * dk;
fNew = feval(func, xNew);
if fNew <= COld + alpha * c1 * dot(dk, dk)
break;
end
alpha = alpha * eta;
end
%xNew = xOld - alpha * dk;
iIter = iIter + 1;
if norm(grad, 2) < epsilon
break;
end
% BB step-size calculation
sk = xNew - xOld; yk = feval(gfunc, xNew) - feval(gfunc, xOld);
if mod(iIter, 2) == 1
alpha = dot(sk, yk) / dot(yk, yk);
else
alpha = dot(sk, sk) / dot(sk, yk);
end
alpha = max(min(alpha, alphaMax), alphaMin);
QNew = eta * QOld + 1;
CNew = (eta * QOld * COld + fNew) / QNew;
COld = CNew;
xOld = xNew;
xk(:, iIter) = xNew;
fk(iIter, :) = fNew;
end
if iIter == iterMax
fprintf('exceed max iteration, not found minimal point x.\n');
end
xmin = xNew;
fmin = feval(func, xmin);
fprintf('iIter = %d, fmin = %f\n', iIter, fmin);
end
这里用到的armijo准则实现见前面的线搜索部分
测试比较二者计算结果:
close all
% f(x, y) = x^2 + 10y^2;
func = @(x)(x(1)^2 + 10 * x(2)^2);
gfunc = @(x)([2*x(1); 20 * x(2)]);
x0 = [10; 1];
alpha = 0.085;
epsilon = 1e-5;
[fmin, xmin, fk, xk] = gradient_descent_fix_stepsize(func, gfunc, x0, alpha, epsilon);
x1 = -12:1e-2:12;
x2 = -10:1e-2:10;
[X1, X2] = meshgrid(x1, x2);
F = X1.^2 + 10 * X2.^2;
figure, contour(X1, X2, F, 50)
hold on
plot(xk(1,:), xk(2,:), 'LineWidth', 2)
plot(xk(1,:), xk(2,:), 'o', 'LineWidth', 2)
x0 = [-10; -1];
[fmin, xmin, fkBB, xkBB] = gradient_descent(func, gfunc, x0, epsilon);
hold on
plot(xkBB(1, :), xkBB(2, :), 'k', 'LineWidth', 2);
plot(xkBB(1, :), xkBB(2, :), 'bo', 'LineWidth', 2);
经过计算,固定步长梯度下降需要66次迭代,而BB步长梯度下降只需要12步迭代就达到最优点(0,0), fmin = 0,从等高线图来看,BB步长梯度下降是非单调线搜索一类的下降算法,并不是每一步都严格下降的。
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)