cs231n-(3)最优化:随机梯度下降

介绍

上节介绍了图像分类中两个重要的组成部分:
1、评价函数score function
2、损失函数loss function

线性函数$f(x_i, W) = Wx$,那么SVM的loss为:
$$ L = \frac{1}{N} \sum_i \sum_{j\neq y_i} \left[ \max(0, f(x_i; W)_j - f(x_i; W)_{y_i} + 1) \right] + \alpha R(W) $$
现在介绍第三个重要组成部分:优化optimization。优化的过程是寻找参数$W$,是的loss函数的值最小。

铺垫:一旦我们理解了这三个核心组成部分如果相互作用,我们将会重新再回顾评价函数,把它扩展比线性映射更复杂的形式。首先扩展到神经网络,之后神经网络。损失函数和优化不变。

可视化loss函数

loss函数一般都是高维的,难以可视化。但是,我们可以在高维空间切一条线或一个平面来获取一些直观的理解。例如,生成一个矩阵$W$,它代表高维空间的一个点。我们可以随机生成一个方向$W_!$,沿着这个方向,用不同的$\alpha$来计算$L(W+\alpha W_1)$的值,这时$\alpha$可以当做x轴,而loss function可以当做y轴。也可以生成两个方向,根据$a,b$变化计算$L(W+a W_1 + b W_2)$的值,这时$a,b$可以分别代表x轴和y轴,loss函数的值可以用颜色来区分
cs_231n_01.jpeg
上图中是SVM的loss,最左边是一维空间。右边两个是2为空间,蓝色代表低值,红色代表高值。

可以看出svm的loss函数是分段的,SVM的loss函数为:
$$ L_i = \sum_{j\neq y_i} \left[ \max(0, w_j^Tx_i - w_{y_i}^Tx_i + 1) \right] $$
SVM的loss只对小于$\Delta$部分的差值起作用,对于大于$\Delta$的部分,它为零。因此是分段的。

SVM的loss虽然是分段的,但是它是凸函数。优化这类问题,可以参考斯坦福的凸优化
如果把评分函数拓展到神经网络,loss函数就不是凸函数了

不可导函数。因为max算子,函数存在不可导的点。但是次梯度subgradient,本节接下来将交叉使用次梯度和梯度。

优化

loss函数可以衡量权重$W$的好坏。优化的目的就是找到一个$W$是的loss函数最小化。本节优化是以svm的loss函数为例,它是凸函数;但是我们最终的目的是优化神经网络,不能简单使用由凸优化得到的方法。

随机搜索

因为可以很简单的检验参数$W$的好坏。最简单的想法是随机找一些参数,记录它们的loss,找到最好的。
使用随机搜索,得到的准确率为15.5%,比10%高一点。

随机本地搜索

你可能想到的是随机找一个方向,如果这个方向可以减小loss,那么久向这个方向前进一步,更新权重。
使用这个策略,在测试集上的准确率为21.4%,比第一个策略好一点,但是还是浪费计算资源。

沿着梯度

在随机本地搜索中,目的是在梯度空间找到一个方向,使得loss函数值减少。事实上,不用随机找这个方向;可以计算出loss函数下降最快的方向。这个方向就是梯度的负方向。

在一维空间,梯度就是函数在某一点瞬时变化率。在多维空间,输入变量是向量,梯度就是在各个变量方向的瞬时变化率组成的向量(梯度也叫作导数)。一维空间计算导数公式如下:
$$ \frac{df(x)}{dx} = \lim_{h \to 0} \frac{f(x+h) - f(x)}{h} $$
当函数输入不是一个数值,而是一个向量是,我们把导数叫做偏导(partial derivatives),梯度就是各个维度上的偏导组成的向量。

计算梯度

有两种方法计算梯度:一种缓慢逼近的方法是数值梯度(numerical gradient),另一种更快速准确但是容易出错,需要使用微积分,是分析梯度(analytic gradient)

数值梯度

使用数值,逼近计算梯度,有两个公式:
$$ \frac{df(x)}{dx} = \lim_{h \to 0} \frac{f(x+h) - f(x)}{h} $$
还有一种形式是中心差公式(centered difference formula),它效果更好
$$ \frac{df(x)}{dx} = \lim_{h \to 0} \frac{f(x+h) - f(x - h)}{2h} $$
详细内容,可以参考wiki

计算梯度,应该让$h$尽可能小,一般使它在$1e^{-5}$级别。

更新权重时,要注意,是使用梯度的负方向,因为梯度是函数增长最快的方向,其负方向才是下降最快的方向。

梯度只是告诉了我们方向,但是没告诉我们一步走远,这个参数是步长(也叫作学习率),它也是一个超参数。

效率问题:计算梯度时,需要计算每一个参数的梯度。在神经网络中,参数量巨大,计算每一个参数的梯度,也给我们带来了效率问题。可以找到更好的方法。

分析梯度

数值梯度求到的是近似梯度,因为$h$不能等于零。分析梯度需要使用微积分,它是计算得到真正的梯度,而且它非常快。但是分析梯度容易出错;这也是为什么在实践中,经常使用分析梯度和数值梯度对比来验证分析梯度。这叫做梯度检验gradien check

以SVM的loss为例,求某个点上的梯度:
$$ L_i = \sum_{j\neq y_i} \left[ \max(0, w_j^Tx_i - w_{y_i}^Tx_i + \Delta) \right] $$
对权重$w{yi}$求导
$$ \nabla_{w_{y_i}} L_i = - \left( \sum_{j\neq y_i} \mathbb{1}(w_j^Tx_i - w_{y_i}^Tx_i + \Delta > 0) \right) x_i $$
上式中,$\mathbb{1()}$是指示函数,如果后面括号条件为true,那么值为1,否则值为零。需要注意一点,计算梯度,只需要计算分类错误对应权重$W$那些行的梯度,正确分类的不用计算。例如正确标签为$s
{yj}$,那么梯度是:
$$ \nabla_{w_j} L_i = \mathbb{1}(w_j^Tx_i - w_{y_i}^Tx_i + \Delta > 0) x_i $$

梯度下降

计算好梯度后,就可以用梯度更新权重参数,这叫做梯度下降。

最简单的使用梯度下降的方法就是用一个循环,在循环中不计算梯度,更新权重。这是最基本的思想。但还有其他使用梯度下降的方法。

Mini-batch梯度下降

当训练集比较大时,以计算机所有样本来计算梯度,之后更新一次参数。这样做有点浪费。一个常用的方法是使用训练集一批样本来计算梯度。这个方法之所以也管用,是因为训练集样本是相关的。一小批样本可以看做训练集的近似。

随机梯度下面Stochastic Gradient Descent (SGD)

Mini-bach梯度下降中,当每批样本只包含一个样本是,就是随机梯度下降了。随机梯度下降在线梯度下降算法;在实际应用中比较少见随机梯度下降,因为一次计算多个样本梯度更加高效。

技术上SGD是指用一个样本来计算梯度,实际中经常听到SGD实际指mini-bach(MGD指Minibatch Gradient Descent, 或者BGD指Batch Gradient descent,它们并不常见)。Mini-batch的大小也是一个超参数,但是它不需要使用交叉验证来获取;实际经常根据内存大小来制定,常常使用2的幂:32、64、128,这样更容易实现向量化操作,且运算更快。

总结

cs231n3_02.jpeg
数据集$(x,y)$已知且固定。权重以一个随机数开始。前向传播由评价函数计算得分。loss函数包含两部分:data loss是计算评分和真实值的loss;正则化loss只和权重有关。在梯度下降过程中,计算梯度,更新参数。

在这一节中:
1、loss函数类似高纬度的地形优化,我们要到达最底部。SVM的loss是分段的。
2、使用迭代增强方法优化loss函数。
3、梯度给出了loss函数下降最快的方向。
4、梯度下降过程中,要使用一个超参数:步长(学习率)。学习率的设置需要技巧。
5、数值梯度和分析梯度。两者优缺点,前者可以检验后者。
6、介绍了梯度下降算法。

文章目录
  1. 1. 介绍
  2. 2. 可视化loss函数
  3. 3. 优化
    1. 3.1. 随机搜索
    2. 3.2. 随机本地搜索
    3. 3.3. 沿着梯度
  4. 4. 计算梯度
    1. 4.1. 数值梯度
    2. 4.2. 分析梯度
  5. 5. 梯度下降
    1. 5.1. Mini-batch梯度下降
    2. 5.2. 随机梯度下面Stochastic Gradient Descent (SGD)
  6. 6. 总结
,
#add by kangyabing