7.7梯度下降算法的改进
之前我们讲过了梯度下降算法,你也动手实现了自己的梯度下降算法。当时我们使用的是用全部训练数据计算平均loss,然后计算所有参数的梯度,更新参数,然后进行多次训练。
7.7.1批量梯度下降(Batch Gradient Descent)
严格来讲,我们之前讲的梯度下降算法叫做批量梯度下降。这个梯度是利用所有训练数据求得每个参数的平均梯度,它准确的反应了模型在整个训练数据集上的改进方向。 它的优点很明显,就是训练稳定,收敛方向准确。但是缺点是不利于模型探索不同的参数空间,可能会陷入局部最小值。 但是当数据量很大时,比如你有上百万的训练数据,那计算量就难以承受。可能每次前向传播就需要数个小时,导致训练非常慢。
7.7.2随机梯度下降(Stochastic Gradient Descent)
为了解决使用全量数据进行训练耗时的问题,人们提出了随机梯度下降的办法。它每次只从训练集里取一个样本,然后计算loss,反向传播,计算梯度,更新模型参数。 它的优点是计算快,而且因为单个数据随机性很强,每次都是不同的数据在更新参数,可以帮助模型训练快速逃出局部最小值。但是它的缺点也很明显,就是训练波动大,不稳定。
7.7.3小批量梯度下降(Mini-batch Gradient Descent)
为了结合批量梯度下降和随机梯度下降的优点,每次从训练数据集里取一小部分样本,用来训练。这样一次训练叫做一个step。而通过每次取一小部分样本(叫做一个batch),把训练集所有数据都训练一遍叫做一个epoch(迭代)。
7.7.4BatchSize怎么选择
在实际训练深度学习模型时,该如何设置每个batch样本的大小呢?通常我们把batch size设置为2的幂,比如32,64,128,256...,这是为什么呢?这是和底层硬件结构相关的。这样做有两个好处,一是因为内存/显存是按照2的幂分块的,比如8,16,32,64字节一块。如果batch size也是2的幂,则数据在存储中更容易对齐,减少读取次数,读取效率更好。二是CUDA架构中,一个执行单元是32个线程,执行效率在batch size是32或其倍数时最高。 另外我们一般会让batch size越大越好,这样训练速度会快,训练也会更稳定。当然batch size的上限由GPU的显存决定。你可以从一个batch size开始尝试,比如256,如果显存溢出,你可以尝试降低到128。如果显存占用还不到一半,你可以尝试增加到512。最终得到一个在你的硬件条件下最大的batch size。
小批量梯度下降是深度学习中最常用的训练方法,后边我们的模型都采用小批量梯度下降算法来进行训练。