梯度:是一个向量
例如:
![](https://i-blog.csdnimg.cn/direct/88c590748a7b420c8cc2755551337019.jpeg)
给定一个初始值 x=5,这是一个一元函数,自变量有两个运动方向,向左和向右。向右边运动,越走越高,函数值在增加,这个方向被称为梯度方向;向左边运动,越走越低,函数值在减小这个方向为梯度的反方向。
显然,要走到最低处,应该选择梯度的反方向。假设走了一段走到某处,再次对方向进行判断,继续朝着梯度的反方向移动,重复这个逻辑,不断朝着梯度的反方向运动,到达最低点附近。
要想达到最低点,要考虑每一次移动多少:
![](https://i-blog.csdnimg.cn/direct/53796da9a27142fcbbc4b5e0c5ae051b.png)
假设 ,梯度为 2x,起始点位置 x0=10,第一个移动的位置为 x1 等于 x0 减去其在 x0 处的梯度值,得到 x1=-10;第二次移动 x2 等于 x1 减去其在 x1 处的梯度值,得到 x2=10;同样 x3=-10, x4=10 ······。但是一直在10和-10之间振荡,并没有降低到最低点。
为此需要一个参数来控制移动的距离,这个参数成为学习率(步长) 。
上述过程的学习率 (图2)。
如果将学习率调到1.05,多次迭代后不仅不会降低到最低点,甚至越走越高(图3)。而如果将学习率降低到较小的值,比如0.02,每次迭代后位置确实在降低,但降低的幅度比较小(图4)。如果将学习率调到0.2,迭代多次后基本就能降到最低处(图5)。因此完成梯度下降,需要选择合适的学习率,不能太大,也不能太小。
![](https://i-blog.csdnimg.cn/direct/2a1e1b40e99c49869673dc7e57c60753.png)
![](https://i-blog.csdnimg.cn/direct/d80dd1b19b2e4adeb28f78e83e722d1d.png)
![](https://i-blog.csdnimg.cn/direct/8c2ccad97b7145e2949c4a34188ef4a9.png)
时,每次迭代后,梯度值都在不断的下降。到第10次的时候降到了0.12,来到最最低点的附近(图6)。梯度为0时的位置,就是最低点的位置。因此选择较小的梯度值作为终止条件是比较自然的,比如希望最后的梯度值小于等于0.01,那么只需要迭代15次;小于等于0.001,就需要迭代19次。只要学习率选择的合适,梯度就可以下降到任意小。
![](https://i-blog.csdnimg.cn/direct/97daf92b23f74d639287d0d143c9f62a.png)
代码:
lr = 0.2 # 学习率
n = 15 # 迭代的次数
x = 10 # 初始值
y = x ** 2 # 目标函数
x_list = [] # 记录每次迭代的x值
y_list = [] # 记录每次迭代的y值
x_list.append(x)
y_list.append(y)
print(f'初始值: x0={x:.4f} y0={x ** 2:.4f}')
# 梯度下降法求最小值
for i in range(n):
i = i + 1
x = x - lr * 2 * x
y = x ** 2
x_list.append(x)
y_list.append(y)
print(f'第{i}次迭代:x{i} = {x:.4f} y{i}={x ** 2:.4f}')
运行结果: