一、梯度下降+随机梯度下降+小批量梯度下降
- 假设m个样本作为输入:
- 需要拟合的函数为:
- 目标是为了找到最合适的参数
,使得拟合的效果最好,因此可以定义如下损失函数:
如何求解呢,这里我们就需要用到梯度下降法,目前主要包括三种类型的梯度下降法。
(一)批量梯度下降(Batch Gradient descent,BGD)
每次参数更新时,根据所有样本来计算梯度,即所有样本都参与了loss值的计算。对于凸优化问题这种方法可以找到全局最优解。因此,理论上而言这种情况下,每一步都是朝着全局最优点靠近。对于样本量不大的情况,这种方式的收敛速度会更快。但是对于大样本的情况,由于每一次样本更新所有样本都参与计算,单次更新的时间更长、需要的存储空间也更大,所以这种方法适用度下降。对于非凸优化问题,BGD也无法保证能够在全局最优点收敛,且在大样本的情况下,收敛到局部最优的时间非常的长。更新公式(1)如下:
其中
为学习率,需要利用上述式子对每一个变量
进行更新。
(二)随机梯度下降法(Stochastic Gradient descent)
每一次更新只采用一个样本来计算梯度,并根据梯度对进行更新。因此可知,对于凸优化问题,每一次更新不能保证是朝着全局最优点前进,但是总体的方法仍然是朝着全局最优的方向前进。相对于批量梯度下降,这种方法单次更新时间更快、存储要求小,且非常适合于增量式更新(假设新的样本源源不断的加入)。对于非凸最优化问题,这种方法通常能够更快的收敛到一个局部最优解。更新公式(2)如下
(三)小批量梯度下降法(Mini-batch Gradient descent)
由于SGD单次只采用一个样本来参数进行更新,因此可能需要通过大量的更新到达局部最优点。因此作为BGD和GD的中间方案,提出了mini-batch GD 方法,该方法将所有样本分为多个min-batch(每个mini batch的样本数量大小为b),每一次采用b个样本进行参数更新。更新公式(3)如下
注意,上式中有两个问题:
- 当m不能被b整除时,最后一个mini-batch的数量小于b
- 每一次梯度计算之后,通常使用b个样本梯度的平均值来对参数进行更新,这种情况一般对应的sum() 计算b个样本的loss之和。如果是采用mean()计算b个样本的平均loss,则上式不需要再除以b。
对于非凸优化问题,我们通常设定一个较小的值(如
),通过多次迭代来对参数更新,注意这里的迭代指的是我们经常在代码中看到(epoch)。对于批量更新,多次迭代很好理解(即用所有样本进行更新需要运行epoch次),同理我们也就可以理解为什么在随机梯度下降和小批量梯度下降中需要使用多个epoch来进行参数更新。下面以小批量梯度下降为例,其完整的参数更新流程如下:
Step 1:对样本进行随机排序
Step 2:设定迭代次数epoch、学习率、小批量大小b的初值
Step 3:设定参数θ的初值
Step 5:对参数进行epoch次迭代,每一个迭代采用公式(3)进行参数更新
二、训练集、验证集、测试集合的使用
(一) 为什么需要验证集和测试集
在建模过程中,通常我们的目的是为了预测而非拟合。特别是对于深度学习模型,其特点就是可解释性弱,但是对数据的拟合和预测效果更强。因此,在建模中我们通常预留一部分数据来对模型的泛化能力进行测试。通常这是通过将数据集(样本集)划分为训练集和测试集两份数据来实现的,其中训练集用于模型的训练,测试集用于模型的评估。
有时候我们会看到还有看到另一种划分即:训练集、验证集和测试集。验证集的主要目的是为了对超参数的调整(即step 2中迭代次数epoch、学习率、小批量大小b三个参数)。这三个参数之所以被称之为超参数是因为他们并不像模型参数(如θ)可以通过学习更新得到,而是在训练的一开始就人为的设定。既然是人为设定的参数那么肯定就存在好坏之分,设定不同的超参数得到结果就有可能不同,如何根据结果的好坏来对超参数进行调整呢,这里就需要用到验证集。例如,我们可以通过设定不同的
值来比较对应的训练集和验证集的损失函数大小(当然,也可以考虑其他评价,如准确率、召回率),相同条件下,两个损失函数最小的那个
值即为最优的。
为什么我们需要通过一个单独的验证集而不是训练集本身来确定超参数的值呢,因为我们对模型评估需要同时考察模型的拟合和泛化能力,既不希望出现欠拟合(拟合差)的情况也不希望出现过拟合(拟合好,泛化差)的情况(这两者通常是正相关的)。
当然,验证集并非必须的,如果不需要调整超参数,就可以不使用验证集,直接用测试集来评估效果。实际应用中你也可以看到有时候把测试集就认为是验证集。这是因为很多时候样本集不够大,数据获取难度较高,测试集只使用一次就浪费了,所以存在这种将测试集和验证集模糊使用的情况,严格意义上来说这是不严谨的。
(二)一种常见的样本集划分和使用的方法:K交叉验证方法 (K-cross validation)
假设我们将数据分为训练集、验证集、测试集合三个部分,比如说60%给训练、20%验证,20%测试,即80%用于模型选择,20%用于最终模型评估。对于这80%数据,我们可以将其划分为K 份,然后我们可以进行K次模型训练和验证,每次K-1份数据用于训练,第K份数据用于验证模型。最后我们将K次的训练误差和验证误差取平均值。这样做好处有两点:1)可以降低数据划分带来的影响,如果我们只进行一次验证,那么K份数据中,不论哪一份用于验证可能对受数据选择的影响而产生偏差;2)充分利用数据,在K次不同的训练中,每一份数据都会出现在训练和验证数据集中,从而可以更加充分的利用数据。
参考链接: