梯度下降
梯度下降是非常常用的优化方法,能够为大范围的问题找到最优解,可以类比迷失在浓雾的山上想下山。
具体而言,通过测量参数相关的误差函数的局部梯度,并不断沿着降低梯度的方向调整,直到梯度降为0,达到最小值。梯度下降每一个重要参数的每一步的步长,这取决于超参数学习率。并不是所有的成本函数都像碗,有的可能像洞,像其他各种不规则的地形,导致模型难以收敛。
梯度下降算法的两个主要挑战,一个是局部最小值,另一个是高原地区需要很长时间才能越过。不过线性回归模型的MSE成本函数是凸函数,这意味着两点的线段永远不会和曲线相交,也就是不存在局部最小,只有全局最小值。它同时也是一个连续数据,所以斜率不会发生陡峭的变化。
这两件事保证的结论是:即便是乱走,梯度下降算法可以趋近于全局最小值(只要等待足够长的时间,学习率也不要太高)不过成本函数虽然是碗状的,不同特征的尺寸差别巨大,可能是细长的碗,这样收敛更慢。因此,应用梯度下降算法时,需要保证所有的特征值的大小比例都差不多,比如使用标准化,否则收敛的时间会长很多。
训练模型,就是搜寻使成本函数(在训练集上)最小化的参数组合,这是模型参数空间层面上的搜索:模型的参数越多,这个空间的维度就越多,搜索也越难。
批量梯度下降
简而言之,就是询问,当我们下山时,脚下的斜率是多少:
需要注意的是,批量梯度下降,每一次都使用全部数据,故而数据量越多,速度越慢。但是算法,在随特征数据扩展的表现比较好。如果训练数据有几十万特征,那么梯度下降要比标准方程要快得多。
eta=0.1#定义学习率
n_iterations=1000
m=100#100次梯度下降
theta=np.random.randn(2,1)
for iteration in range(n_iterations):
gradients = 2/m * X_b.T.dot(X_b.dot(theta)-y)
theta=theta-eta*gradients
theta
array([[4.21509616],
[2.77011339]])
X_new_b.dot(theta)#预测
array([[4.21509616],
[9.75532293]])
演示不同学习率造成的结果:
theta_path_bgd=[]
def plot_gradient_descent(theta,eta,theta_path=None):
m=len(X_b)
plt.plot(X,y,'b.')
n_iterations=1000
for iteration in range(n_iterations):
if iteration<10:
y_predict=X_new_b.dot(theta)
style="b-" if iteration > 0 else 'r--'
plt.plot(X_new,y_predict,style)
gradients = 2/m * X_b.T.dot(X_b.dot(theta)-y)
theta=theta-eta*gradients
if theta_path is not None:
theta