动手学深度学习 | 多GPU训练实现 | 33
就是一个小批量的数据,如果你有4张卡,那么这个批量的数据就可以分成4份。比如有100个样本,那么每张卡拿到25个样本,然后去计算梯度,最后再把梯度加起来做更新,这个就是多GPU的训练。
从零实现
理论而言,并行计算得到的结果应该是一样的。
两次结果不一样是因为存在随机性,如果固定住随机种子,理论两次得到的记过应该是一样的。
但是现在最主要的问题就是为什么使用了2个GPU,但是跑一个epoch的时间没有变短?很有可能是读写那部分出了问题;还有就是虽然GPU增加了,但是batch_size没有增加。
但是如果batch_size增大了,但是lr不变的话,很有可能收敛变慢。
简洁实现
之前从零开始实现有两个问题,一个是LeNet网络太小了,还有一个就是手写的多GPU训练性能不行,所以导致单卡和多卡的训练并没有拉开差别。
这里使用ResNet18,先看结果,使用双卡确实训练一个epoch的效率高了很多,但是却没有达到时间减半的效果。至于抖动剧烈,这个就和lr的大小有关了,这里lr可能是调大了。
还有就是batch_size的大小,如果保持epoch次数不变,增大batch_size不能达到原来的精度,那么就可以认真考虑是不是batch_size对于这个数据集大了,为什么呢?因为如果数据集的多样性不够,其实重复计算相似的图片的梯度对收敛是没有什么帮助的。
QA
- 既然xx norm是一种正则,那么原则上它应该能像dropout那样加强模型的泛化能力,那就应该能提高模型的测试精度,那为什么说batch norm只能加快训练而对精度没影响呢?
沐神:我要回去看看paper怎么说的。
吴恩达:不要将BN当作一种正则化方法,只是有一点正则的效果。
BN本身没有引入噪音,只是控制梯度的范围。
- GPU显存如何优化呢?最近跑实验显存经常OOM
显存呢,靠的是框架。其实Pytorch的显存优化还行,这里建议就是把batch_size调整小一点。
- 验证集准确率震荡较大时哪个参数影响最大呢?
是lr。
- 为什么batch_size调的比较小,比如8,精度会一直在0.1左右,一直不怎么变化?
是因为lr太大了,如果batch-size调小了,lr也要相应的调小;batch-size调大了,lr也要相应的调大。
- 训练集和验证集不同分布,该怎么训练?
这个是很正常的,本来现实生活就应该是这个样子,只不过是我们假设了它们是独立同分布的,这个假设一开始就不对,这不过有的错的多,有的错的少。