0x00 前言

在进行机器学习训练的时候,我们会在TF/TORCH中输入各种训练参数,其中关于迭代次数的参数有Epoch,Batch_size和Iterations,这几个参数的作用是什么?有什么样的作用?关系又是什么?笔者将简单给大家解释一下


0x01 基本概念

想要搞清楚Epoch & Batch_size & Iterations之间有什么关系,先给大家普及一些基本概念和知识,大段的讲述各种能够google到的基础知识就不讲了,如果有兴趣可以自行查询。


梯度下降(Gradient Descent)

梯度下降是一个利用不断迭代来优化并找到最优解的算法(求一个曲线的最值)。

我们来分析一下这句话:

梯度:坡度倾角或偏差变化的速率(the rate of inclination or declination of a slope)。

下降:是一个正在发生下降变化的事实(the instance of descending)。

迭代:需要通过多次获取中间结果来获得最好的结果。梯度下降中迭代的质量(例如,次数)将直接影响函数拟合的结果,能够将一个欠拟合的函数更好的拟合数据。

这幅图片就可以很好的理解这个概念:
图1:左图为二次函数寻找最值,右图是离散数据函数拟合

梯度下降有个非常重要的参数:学习率(learning rate),如图1左所示,在算法初始的时候y值变化的幅度非常的大,这就意味着学习率非常的大;随着一次次的迭代,我们的y值变化幅度逐渐变小,学习率也越来越小。当然,我们的cost function也在逐渐下降,也就是说我们的成本(cost)也是越来越小的。(loss/loss function/cost/cost function,他们指的是同一个东西。我们可以理解为模型与现实的差距,通常情况下,越小越好)


0x02 解释和比较

知道了梯度下降是怎么一回事,就可以开始解释EpochBatch_sizeIterations这些概念的意思和关联了。

首先明确一点,我们都是在处理总量大,实时性高并且无法一次性载入到内存当中的数据时才涉及到所说的这些术语名词。如果我们拥有的数据可以一次性载入到内存当中,就不需要这些概念来进行训练了。当数据量较大时,我们需要切分数据到合适的规模能够被训练的环境所载入,然后并逐一不断的提供到神经网络里面,每一步结束后都会更新神经网络的权重来符合(fit)刚输入的一小部分数据。在这个过程当中:


Epoch

指的是全部的数据在神经网络中向前传递并向后传递一次的数量单位。

当我们在制定Epoch = 5的时候,相当于把我们原始的所有数据往神经网络当中输入了5次。当然,其中的每一次,我们是无法把所有的数据一次性载入到内存当中的。

那么,既然我们的数据没有变化,为什么要多次输入到神经网络中进行训练呢?为什么会有多次Epoch呢?

因为我们使用的数据是已知的、有限的,我们要做的是预测未知的,无限的数据和模型拟合度。我们使用的梯度下降是一个通过迭代来优化结果的过程,我们需要把整个数据集多次输入到同一个神经网络当中,所以通过一次Epoch来更新权重是不够的。

图2:函数拟合情况

如图2所示,如果我们只进行一次Epoch,那么可能会出现最右面那种函数欠拟合的状态(underfitting)。随着我们Epoch次数的增加,神经网络的权值被更新的越来越频繁,会出现从欠拟合 --> 最佳拟合(optimum) --> 过拟合(overfitting)的过程。所以,Epoch不宜过多也不宜过少,至于如何选出一个合适的、能够让结果最优的Epoch次数,这会受到我们选用的训练方法,数据集特征,数据量以及数据多样性等因素的影响,笔者之后会根据自己的训练经验专门写一篇文档给出一个方法来确定。(玄学)


Batch_size

当前载入的一个Batch中训练样本的总数。这个和Batch的数量不是一个概念。

首先解释一下,Batch是个啥。文中之前提到过,我们无法把整个数据集全部载入到神经网络当中,可能因为内存限制,或者是因为神经网络数量的限制,你需要把整个数据集切分成一小块一小块,每块就叫做一个Batch,一个Batch中样本的数量是Batch_size。

可以理解为,把一篇文章拆分成各个模块一样,方便理解和阅读。


Iterations

就是一次Epoch中Batch的数量。

这个就不多做解释了。
举个例子,假如我们全部数据集的数量是10000。那么一次Epoch中,如果我们设置Batch_size是100,那么Iteration就是10000/100 = 100。


后记

当然了,实际的训练情况会和上述的这种理想情况不太一样。

举个例子:拿TensorFlow训练LSTM来说,我们会指定几个参数,每层LSTM中神经元的数量,LSTM的层数,Epoch,Batch_size,Num_per_epoch等。

其他参数很好理解,这个Num_per_epoch是什么意思呢?一般来说,我们会选择整体数据集中的一部分数据来当作某次Epoch的全量数据,这样使用数据的随机性更强,每个样本参与训练的次数不一定就是Epoch的数量。这样不使用整体数据集训练的好处有很多,也可以通过推导来证明随机子集的叠加效果好于整体,还可以灵活的调整每次Epoch的量级和数量,这对于找到一个好的Epoch也有帮助。如何证明推导上述结论?如何切分整体数据集为几个Epoch全量数据集?笔者会另开文来和大家一起探讨。