梯度下降几乎可以说是机器学习算法中,训练模型和调参最重要的方法了。梯度就是所有偏导数构成的向量。因为计算代价函数的梯度需要求导,这里应该是机器学习中使用微积分最多的地方了。微博上爱可可老师分享过一个将梯度下降算法演化史的视频,链接在这里。
3.1 梯度下降的一般步骤参数的初始化:通常所有参数都初始化为1;
确定学习率;
求代价函数的梯度(所有参数的偏导数);
所有参数都沿梯度方向移动一步,步长就是学习率的大小;
重复步骤4直到参数不再发生变化(此时取到极值点,梯度为0)或达到预先设定的迭代次数.
3.1.1 学习率学习率一般用希腊字母$\alpha$表示,可能需要多尝试几次,才能找到合适的学习率。过大的学习率会导致梯度下降时越过代价函数的最小值点,随着训练步数的增加,代价函数不减反增;如果学习率太小,训练中的每一步参数的变化会非常小,这时可以看到代价函数的值在不断减小,但是需要非常大的迭代次数才能到达代价函数的最小值点。
按照吴恩达老师的建议,每次可以3倍放大或者3倍缩小来调整学习率。
图3-1,学习率过大会导致参数的取值越过最小值点;学习率过小会导致参数变化缓慢
3.1.2 代价函数的梯度在机器学习中,对代价函数包含的每一个参数求偏导数,这些偏导数组成的向量就是代价函数的梯度。
这个时候就要用到微积分中求导数的知识了。如果自己有兴趣可以在草稿纸上手动算一算;如果不想自己算,常见的代价函数的求导过程在网上很容易找到。
均方误差函数的梯度
为了简单起见,先考虑只有一个特征的直线方程:$h_{(\theta)} = \theta_0 + \theta_1x$
参考MSE的公式,见式子(2-1),可得,
$J(\theta)$对$\theta_0$的偏导数:$\frac{\partial}{\partial \theta_0} J(\theta) = \frac{1}{m} \sum_{i=1}^{m}{(h_{\theta}(x^{(i)}) - y^{(i)})} \cdot 1 \quad \cdots \ (3-1)$;
$J(\theta)$对$\theta_1$的偏导数:$\frac{\partial}{\partial \theta_1} J(\theta) = \frac{1}{m} \sum_{i=1}^{m}{(h_{\theta}(x^{(i)}) - y^{(i)})} \cdot x^{(i)} \quad \cdots \ (3-2)$;
3.2 梯度下降的Python实现 3.2.1 方法1 - 原始实现下面根据前面已经获得的信息,做一个简单的实现,首先利用直线方程生成一些数据(添加了一些随机误差)
1 import numpy as np 2 import matplotlib.pyplot as plt 3 m = 100 # 样本量 4 X = 2 * np.random.rand(m, 1) # 取大小在区间(0, 1)上的随机数,构成一个100*1的矩阵 5 y = 5 + 2 * X + np.random.rand(m, 1) 6 plt.plot(X, y, "b.") 7 plt.show()