梯度下降是一种常见的优化算法,非常通用,能够为大范围的问题找到最优解
设置一个随机的θ值(这个过程称为初始化),然后逐步改进,每次踏出一步,每一步都尝试降低一点成本函数(例如MSE),知道算法收敛出一个最小值
假设一人去爬山,山上起雾,只能感受到地面坡度,那么下山最快的办法就是一直走坡度最陡的方向(当然这是正常人不会干的事)
梯度下降每一步的步长取决于超参数-学习率,如果学习率太低,则算法需要大量迭代才能找到最小值,这将会消耗大量的时间,反之,如果学习率太高,那就很可能直接跨过最小值,甚至可能比起点更高,这回导致算法呈发散状态,值越来越大,最后崩掉
不是所有成本函数都是抛物线状,有的可能像山脉,起起伏伏,不规则形状,导致很难收敛到全局最小值,很有可能只收敛到局部最小值
不同特征尺寸差别巨大,它可能是一个细长的碗状,或者是一个类似平盘的形状,这就会导致梯度下降的效率大不相同
图中: 左图梯度下降法可以直接向下一直走,快速的找到全局最小值,而右图中,梯度下降需要先垂直向下,然后在一个接近平原的斜面上持续迭代,虽然最终依旧会找到最小值,但消耗的时间成本比左图高很多
实现梯度下降,需要计算每个模型关于θ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)
每一步既不基于整个训练集,也不是基于一个单独的实例,而是基于一小部分随机的实例集