梯度下降
简介
梯度下降是一种常见的优化算法,非常通用,能够为大范围的问题找到最优解
中心思想: 迭代的调整参数从而使成本函数最小
课本话解释:
设置一个随机的θ值(这个过程称为初始化),然后逐步改进,每次踏出一步,每一步都尝试降低一点成本函数(例如MSE),知道算法收敛出一个最小值
大白话解释:
假设一人去爬山,山上起雾,只能感受到地面坡度,那么下山最快的办法就是一直走坡度最陡的方向(当然这是正常人不会干的事)
图示:
学习率
梯度下降每一步的步长取决于超参数-学习率,如果学习率太低,则算法需要大量迭代才能找到最小值,这将会消耗大量的时间,反之,如果学习率太高,那就很可能直接跨过最小值,甚至可能比起点更高,这回导致算法呈发散状态,值越来越大,最后崩掉
学习率低:
学习率太高
梯度下降陷阱
不是所有成本函数都是抛物线状,有的可能像山脉,起起伏伏,不规则形状,导致很难收敛到全局最小值,很有可能只收敛到局部最小值
特征尺寸问题
不同特征尺寸差别巨大,它可能是一个细长的碗状,或者是一个类似平盘的形状,这就会导致梯度下降的效率大不相同
图中: 左图梯度下降法可以直接向下一直走,快速的找到全局最小值,而右图中,梯度下降需要先垂直向下,然后在一个接近平原的斜面上持续迭代,虽然最终依旧会找到最小值,但消耗的时间成本比左图高很多
所以使用梯度下降,一般会配合归一化来使用,例如sklearn中的Standardscaler类
注意: 模型的参数越多,空间维度也就越多,搜索的困难也就越大
批量梯度下降
简介
实现梯度下降,需要计算每个模型关于θj的成本函数的梯度,也就是需要计算改变θj,成本函数会改变多少
成本函数的偏导数公式:
α
α
θ
j
M
S
E
(
θ
)
=
2
m
X
T
∗
(
X
∗
θ
−
y
)
\frac \alpha {\alpha\theta_j}MSE(\theta)=\frac 2 mX^T*(X*\theta-y)
αθjαMSE(θ)=m2XT∗(X∗θ−y)
成本函数的梯度向量:
▽
θ
M
S
E
(
θ
)
=
2
m
X
T
∗
(
X
∗
θ
−
y
)
▽_\theta MSE(\theta)=\frac 2 m X^T*(X*\theta -y)
▽θMSE(θ)=m2XT∗(X∗θ−y)
梯度下降步长:
θ
(
n
e
x
t
s
t
e
p
)
=
θ
−
η
▽
θ
M
S
E
(
θ
)
\theta^{(next \ step)}=\theta-\eta ▽_\theta MSE(\theta)
θ(next step)=θ−η▽θMSE(θ)
# 代码实现
eta = 0.1 # 公式中的η
n_iterations = 1000
m = 100
theta = np.random.randn(2,1) # theta就是θ
X = 2 * np.random.rand(100, 1)
y = 4 + 3 * X + np.random.randn(100, 1)
X_b = np.c_[np.ones((100, 1)), X]
for i in range(n_iterations):
gradients = 2/m * X_b.T.dot(X_b.dot(theta) - y)
theta = theta - eta * gradients
print(theta)
随机梯度下降
简介
由于批量梯度下降需要用整个训练集来计算,所以训练集很大的情况下,效率会很低,与之相反的就是随机梯度下降,每一步在训练集中随机选择一个实例,基于这一个实例来进行梯度计算,大大提高了效率
注意: 由于随机的性质,随意不会向批量梯度下降一样缓慢减小,而是不断上下的,但从整体上看是在持续下降
随着时间推移,随机梯度下降会到达最小值,但不会停止,会继续反弹,永远不会停止,当算法停下来时,得到的是足够好的值,但不会是最小值。
当成本函数不规则时,随机梯度下降可以帮助算法跳出局部最小值,所以相比批量梯度,它对于寻找全局最小值更有优势。
由于算法本身永远无法确定最小值,所以需要制定一个学习计划,也就是逐步降低学习率,让算法逐步靠近最小值
X = 2 * np.random.rand(100, 1)
y = 4 + 3 * X + np.random.randn(100, 1)
X_b = np.c_[np.ones((100, 1)), X]
n_epochs = 50
t0, t1 = 5, 50
m = 100
def learning_schedule(t):
return t0 / (t + t1)
theta = np.random.randn(2,1) # theta就是θ
for epoch in range(n_epochs):
for i in range(m):
random_index = np.random.randint(m)
xi = X_b[random_index:random_index + 1]
yi = y[random_index:random_index + 1]
gradients = 2 * xi.T.dot(xi.dot(theta) - yi)
eta = learning_schedule(epoch * m + i)
theta = theta - eta * gradients
print(theta)
小批量梯度下降
简介
每一步既不基于整个训练集,也不是基于一个单独的实例,而是基于一小部分随机的实例集
优点
- 比批量梯度下降时间上节省了
- 比随机梯度下降更容易接近最小值
缺点
- 比批量梯度下降更容易陷入局部最小值
- 比随机梯度下降需要更多的时间