5.梯度下降法
5.1什么是梯度下降法
5.1.1梯度下降法的实现思想
最优化方法是寻找函数(目标函数)极值点的数值方法,包括梯度下降法、牛顿法、坐标下降法、拉格朗日乘数法、凸优化等。
梯度下降法是一种基于搜索的最优化方法,它不是机器学习算法;其作用是最小化一个损失函数。
梯度是导数对多元函数的推广,它是多元函数对各个自变量偏导数形成的向量,常表示为▽f。
一元函数y = f(x)的梯度是df/dx,其在x0处的梯度为df/dx|x=x0。
多元函数y = f(x),x = (x1,x2,x3,...xn)的梯度是:
需要注意的是,在机器学习中梯度都是列向量。
梯度下降法就是沿着梯度向量反方向进行迭代以达到函数极值点的方法。在这里直接给出公式,不再推导。从初始点x0开始,使用如下的迭代公式:
其中,η是一个接近于0的正数(一般设置为0.01),称为学习率。其取值会影响获得最优解的速度;若η取值不合适,甚至得不到最优解。η是梯度下降法中的一个超参数。
当f(xk+1)-f(xk)无限接近于0时,可以认为xk+1为极小值点;否则函数值xk+1会继续沿着序列xk+2的方向进行搜索,最终找到梯度为0的点。
当一个函数有多个极值点时,获得的极值点可能是局部极值点;为了获得全局极值点(最小值点),可以多次随机化初始点来重新运行程序。因此,初始点也是梯度下降法的一个超参数。
5.1.2简单实现梯度下降法
#程序5-1:求其y = (x-1)**2 + 2的极小值点
import numpy as np
def dy(x):
return 2*(x-1)
def y(x):
return (x-1)**2 + 2
#设置初始点x_0
x = 0.0
#设置eta
eta = 0.01
#设置近0值
near_zero = 1e-10
while True:
grad_x = dy(x)
last_x = x
x = x - eta*grad_x
if abs(y(last_x)-y(x)) < near_zero:
break
print(x)
print(y(x))
运行结果:
0.9999507956878463
2.0000000024210642
在梯度下降法中,η的取值非常关键,若η取值过大,可能执行x = x - eta*grad_x时导致x值不断增大/减小,使y(last_x)和y(x)趋向于无穷大/小。因此,修改代码如下。
#程序5-2:修改eta
import numpy as np
def dy(x):
return 2*(x-1)
def y(x):
try:
return (x-1)**2 + 2
except:
return float('inf') #返回最大的浮点数
#设置初始点x_0
x = 0.0
#设置eta
eta = 1.11
#设置近0值
near_zero = 1e-10
cur_iters = 0
max_iters = 1e4
while cur_iters < max_iters:
grad_x = dy(x)