《FASTER NEURAL NETWORK TRAINING WITH DATA ECHOING》文章阅读总结与思考。
论文写的还挺多,不过都比较容易理解。当然论文非常学术语(就是废话空话太多),于是我用最简洁的话吧本文做一个总结,方便读者学习交流。学术搬运工是我没跑了:)
一、文章概述
大家已经对摩尔定律十分熟悉了,GPU和其他硬件加速器极大地加速了神经网络的训练(GPU、TPU、编程有点复杂的FPGA还有AI专用加速器)但是数据传输以及预处理仍然是非常慢。随着加速器的不断改进,这些前期阶段所花费的时间将逐渐成为训练速度的瓶颈(就是我们常说的“存储墙”
)。作为研究者,我们的目标只有一个了,那就是让系统变的更快,让训练变得更快!!PS:这个时候心疼我可怜的AI室友,训练代价非常大,所以中途不敢有任何闪失。
好了言归正传,那么为了让训练更快要怎么做呢?文章给了两个可以考虑的方向:
- (1)使非加速器工作地更快
- (2)减少非加速器所需的工作量。
选项(1)可能需要大量的工程工作或技术探索,给系统增加太多的复杂性。我的理解是加速CPU的计算能力,或者写代码的时候用考虑更快速的更简洁的函数等等。反正是非常麻烦的一件事情。
因此,作者将重点放在选项(2)上,探索减少训练前期阶段的工作量的方法。既然数据传输于预处理这么慢,那就让他少做一点吧。
下面我们可以看一个简单的深度学习训练过程:
- 1 读数据并解码数据
- 2 对数据进行混洗(打乱数据的顺序)
- 3 数据增强(剪裁,翻转)
- 4 把图片组建成一个batch批次方便训练
- 5 SGD梯度下降训练过程
由于任何流程阶段的输出都可以缓冲,因此不同阶段的计算互相重叠,最慢的阶段将占用主要的训练时间。即短板效应。
本文中的假设是基于预处理阶段非常慢,训练非常快这种前提,如下图:
左图就是先有的某种训练情况:文章中用上下游(Upstream与Downstream来形容,害我理解了半天。能看出来写论文造概念多么重要。。。)来分别代表读取数据预处理、SGD训练。
左图Idle的原因是因为训练太快,要等待下一个阶段的数据(虽然有Pipeline,但是还是慢)。于是,在这篇论文中,作者研究如何通过减少训练前期部分的时间来加速神经网络训练(图 2a)。作者将训练过程中第一部分的输出重复用于多个 SGD 更新,以利用空闲计算能力。这类算法称为 “数据回送”(data echoing)
,每个中间输出被使用的次数称为 回送因子(echoing factor)
。 数据回送算法在训练流程中的某个位置(SGD 更新之前)插入重复阶段。如果上游任务(重复阶段之前)花费的时间超过下游任务(重复阶段之后)花费的时间,算法将回收下游闲置的计算能力,并提高模型的 SGD 更新率(图 2b)。通过改变插入点、回送因子和 shuffle 程度,可以得到不同的数据回送算法。
二、数据回送
数据回送指在训练流程中插入一个重复阶段,回送前一阶段的输出。这里我们假设SGD操作(upstream)进行e次,则数据回送完成一个上游步骤和 e 个下游步骤的时间为:
其中 Tupstream 是数据处理所有阶段所用的时间,Tdownstream 是SGD阶所用的时间,e 是回送因子。
R=Tupstream/Tdownstream表示所需预处理阶段时间与训练时间的比例。那么完成一个上游步骤和 e 个下游步骤的时间对于从 e 到 R 的所有回送因子都是相同的。换句话说,额外的下游步骤是“无消耗的”,因为它们使用的是空闲的下游计算能力。
如果 e=R,并且重复数据和新数据价值相同,则可以实现最大加速。
考虑到训练过程中的每个操作都需要一些时间来执行,如果在 SGD 更新之前应用数据回送,R 能取最大值,但这将导致每个 epoch 多次使用同一批数据。然而,如果想在上游步骤和下游步骤之间找到更有利的权衡,更好的方式是较早的插入回送数据。
所以就需要考虑在不同的阶段执行数据回送操作。
不同插入点的数据回送:
批处理前或批处理后的回送(Batch前后):批处理前的回送是指数据在样本级别而不是批级别进行重复
。这样增加了相邻批次不同的可能性,但代价是不能复制一批内的样本。
批处理前回送的算法称为样本回送(example echoing)
,批处理后回送的算法称为批回送(batch echoing)
。
数据增强前或数据增强后的回送:数据增强前的回送允许重复数据进行不同的转换,能使重复数据更接近新数据。(这里我理解是这样:如果在shuffle与数据增强之间插入数据回送,那么虽然用的是同一批数据,但是两次增强对数据的处理不同从而生成的数据有所区别)
数据回送的表现也受回送阶段后 shuffle 程度的影响。在适用的情况下,作者将 shuffle 作为缓冲区。缓冲区越大,shuffle 程度越高,训练算法能够近似于将整个训练集加载到内存中。
PS;这里的数据回送可以放在任何阶段,比如下图的1234 。后面的实验首先拿掉了shuffle这个阶段,所以对2 3 4先进行了效果测试。
三、实验
作者在两个语言建模任务、两个图像分类任务和一个目标检测任务上验证了数据回送的效果。对于语言建模任务,作者在 LM1B 和 Common Crawl 数据集上训练了 Transformer 模型。对于图像分类任务,作者在 CIFAR-10 数据集上训练了 ResNet-32 模型,在 ImageNet 数据集上训练了 ResNet-50 模型。对于目标检测任务,作者在 COCO 数据集上训练了 SSD 模型。
我们关心的问题就是这个方案到底能不能加速模型训练?能不能提高准确率?会不会带来不良影响?
实验用了一堆篇幅来说我们怎么把各个模型参数调到“最优”。相当于给读者说:我每个模型的原始Baseline是已经达到上限,如果回送方案测试的效果更优那就是回送方案带来的好处,从而排除了未知情况干扰。
3.1 数据回送可减少训练所需的全新数据的数量
这个实验就是用来说明,我用回放机制可以使得我模型达到预定最优效果时,需要更少的数据。(听起来很玄学,不过他这五组的测试效果还不错)
五组实验,横坐标的不同颜色从左到右分别代表:①橘色:不用回放的原始方案;②蓝色:在batch操作后阶段(下图阶段a)进行回放;③浅绿色:在下图b阶段进行数据回传,我理解的是这个时候回传数据会再进行一下Batch操作;④深绿色:在下图c阶段回传,数据会再经过增强、Batch两个操作。
图中虚线代表最优理论读入数据量。就是说假如我重复读入的数据带来的信息量与全新的数据信息量相等,那么我就应该达到虚线那个点。当然,我重复读入的数据信息量肯定少,所以这个线是我们理想的线。
根据测试结果我们能看出,整体来看进行回放操作会减少新数据的读入量,并且随着回放操作位置向前移动,效果越好(由于越向前移动与上一次训练数据的差别越大)
3.2 数据回送可以缩短训练时间
实验对ResNet-50进行测试(因为这个模型比较小,而所需数据部分占比比较大,所以对当前场景有利),这里能达到R=6,也就是上游时间是下游时间的6倍。
于是我们将e设置为2~5(回放次数)
实验把回放放到数据增强操作之前,测试发现,随着e的增加,效果越好,数据读取量约少,即训练所需时间越短。
3.3在回送因子的合理上限内,数据回送是有效的
此外,实验对不同e进行了测试,是不是回放次数越多效果就一定越好呢??
测试表明,在batch为1024大小下(并不知道单位,这arvix上的文章就是不如A严谨),e>8之后效果就反弹了,不过还是比Baseline要好;
而当我们将batch设置更大,这个能承受的e也更大。所以能说明batch越大的话更适合多次回放。这里我觉得可以想极端情况:当我batch大到能装下所有dataset的时候,那一次回放就是一次epoch,那肯定效果好啊!hhhh
3.4 批尺寸的增加对数据回送的影响
上一个实验稍微点了一下batch的大小,那这次实验就针对batch大小详细做一下实验。
对于这个图,论文对其解释也是有点模糊,不过我们直观来看,随着batch增大batch echoing应该是要变好的,而example echoing变差了。对于batch echoing,文章解释为:因为随着批尺寸接近训练集的大小,重复的批数据会接近新的批数据
。而对于example echoing,“由于随着批尺寸的增加,每批中重复样本的比例也随之增加,因此实际中,批尺寸较大的样本回送的表现可能更像较小的批尺寸的表现。”
。这个我就不是很懂了。难受
3.5 Shuffle 程度越高,数据回送表现更好
之前的测试都没有考虑shuffle,不过如果我们把数据混洗操作加入,那么随着混洗buffer大小的增加,对应的效果也是更好。也就是说随机程度越好,连续两次回放相似度越低。
3.6 数据回送不损害准确率
人们可能担心重复使用数据可能会损害最终的表现性能,但实验中没有观察到任何类似情况。为了进一步证明数据回送不会降低解决方案的质量,作者在 LM1B 上使用 Transformer 进行了实验,在 ImageNet 上使用 Resnet-50 进行了实验。
实验表明用这个数据回放方案可以使得模型读入更少的数据就能达到最优的准确率。从而节约了训练时间。
不过对于精确度,实验没有测试。
四、结论
文章又回答了这个问题:尽管先前研究人员担心重复数据的 SGD 更新是无用的,甚至是有害的。但是对于实验中的每一项任务,至少有一种数据回送方法能够减少需要从磁盘读取的样本数量。
目前这个方案也就是初步提出,感觉里面还要验证很多东西才能说他真正有效。放这里供大家学习吧。
其中还有一些问题我也没有理解很清楚:
- 比如batch操作前后为什么会有区别?我之前理解的batch操作就是把数据组成一个batch队列,所以感觉这个并不会对数据顺序以及样子带来任何变化。文章在测试的时候却给了一些不一样的反馈。这个有待深入学习一下。
也欢迎大家给我留言,方便我们进行交流(公众号直接发消息就行了hhhh)
感谢我室友的微信聊天图,祝早日AAA。