本文主要是为了讲解 梯度下降法 的原理和实践, 至于什么是梯度下降法, 他能做什么, 相信百度一下你就都知道了, 所以下面进入正题
梯度下降法主要是用来求解某个方程的最小值, 这里我们以 凹一元二次方程 为例。
这里我们用到 matplotlib
和 numpy
,
如果你对这两个库不了解也没关系,
我们主要是借助它来进行讲解,
不会过多涉及相关的东西
import matplotlib.pyplot as plt
import numpy as np
# 生成一个等差数列 plot_x
plot_x = np.linspace(1,5,20)
# plot_x 平方 再加2 生成一个数列 plot_y
plot_y = (plot_x-3)**2+2
# 将 plot_x plot_y 对应位置作为一个点的 x,y 坐标,那么就可以画出如下图的一条一元二次方程的曲线
plt.plot(plot_x,plot_y)
plt.show()
这里我们首先明确两个概念:
本质上其实都是一样的,都是指导我们求最值。
# 梯度函数
def dJ(x):
return (x-3)*2
# 损失函数
def J(x):
return (x-3)**2+2
x = 0.1
# 记录每次梯度下降的点
history_x=[x]
i_iter=1
# 学习率
learn_rate = 0.1
# 进行梯度迭代
while i_iter < 1e4:
i_iter += 1
dj = dJ(x)
last_x = x
x =x -learn_rate *dj
history_x.append(x)
# 如果迭代精确的达到,则结束结算
if abs(J(x)-J(last_x))<0.0000000001 :
break
history_y = J(np.array(history_x))
plt.plot(plot_x,plot_y)
plt.plot(history_x,history_y,color='r',marker='+')
plt.show()
本文讲的并不如何易懂 和 通俗, 不过因为 一元二次的 梯度应该是相对很容易的, 所以这里也就不啰嗦了, 梯度下降其实也不外呼这个原理, 只是可能损失函数会不太一样, 那么梯度函数也就跟着不太一样了, 但是到最后都是通过这两个函数来进行迭代达到最后的标准求出最优解
梯度下降法容易陷入局部最优解的而达不到全局最优解, 所以可能需要随机选取多个起始点进行梯度迭代, 这样 全量的梯度下降法 也叫做 批量梯度下降法
对于多元二次方程, 因为多元会使得 批量梯度下降法 的梯度函数计算的非常缓慢, 所以可以采用随机梯度下降, 并且随机梯度下降 不容易 陷入局部最优解的的陷阱, 所谓的随机梯度就是每次计算梯度的时候随机选取一个样本进行迭代来实现, 但是因为单一样本的偶然性比较大, 并且其最后不一定能达到最小值, 所以一般也是采取折中的 小批量梯度下降法, 即可以随机抽取一部分样本进行迭代。
值得注意的是使用随机梯度下降的时候,
我们的 学习率
就不能取一个固定值,
这一点从上面的轨迹图可见一般,
越是接近底部,其变化应该是越来越小的,
如果 学习率 还是一开始的那样,
会使得最终的结果在真正的最小值附件徘徊,
很难得到一个比较精确的值。
这里可以参考下 模拟退火
的思想,
顺便我们可以看下随机梯度下降的 学习率 公式: a/(b+迭代次数)
其中 a 和 b 是作为参数来调节 学习率,使得其更适合进行迭代的计算