跳至主要內容

深度学习训练过程中BatchSize的设置

Haopeng Yu大约 5 分钟

昨天配置好GPU加速敲开心,开始跑我的小模型。结果惊奇的发现CPU效率比GPU高5倍多,这是什么鬼?和群里各个大佬讨论了一下,最终发现是BatchSize的问题,在此顺便讨论一下在模型训练过程中BatchSize的设置。

  • Show一下硬件和我简陋的小模型
  • 不同Size下GPU和CPU的运算时间
  • 到底需要设置多大的Size?

先简单说一下我理解的Batch Size吧。

比如你有1w个数据(或者图片)需要训练,也就是需要找1w个数据的规律(感觉深度学习就是让模型找规律)。这时候有几种策略:

  1. 全部数据都拿来用,一次性找所有的规律。

这个首先就是很难(很费时间)总结他们的规律,类似“众口难调”,全局学习速率也不好定。其次就是,往往内存很难容纳全局那么大的数据量。全部数据都拿来用也叫Batch Gradient Descent,批梯度下降,就是每次都用全部数据找规律。

  1. 每次就拿一个数据来找规律。

这个就会造成模型很难收敛,类似“公说公有理,婆说婆有理”。这样是不可取的=-=

  1. 因此就诞生了mini-batches

就是把数据总量分为n份,每次找一份的规律,一轮把每一份的规律找一遍。而Batch Size参数就是每一份有多少数据的意思,比如Batch Size=1000,那么1w的数据就被分成10份,这个意思。

很多大佬的博客写的超级好,我也是看完之后才能总结出上面这些,详细请看:

机器学习中常见问题_几种梯度下降法open in new window谈谈深度学习中的 Batch_Sizeopen in new window

Show一下硬件和我简陋的小模型

首先说一下我的模型,我的测试模型很简单,就是6层全连接层,每层64个unit,激活函数用relu,最后加个BN层。训练集总量135844。

计算的硬件如下,CPU是i7-3770:

CPU

	Intel(R) Core(TM) i7-3770 CPU @ 3.40GHz

	基准速度:	3.40 GHz
	插槽:	1
	内核:	4
	逻辑处理器:	8
	虚拟化:	已启用
	L1 缓存:	256 KB
	L2 缓存:	1.0 MB
	L3 缓存:	8.0 MB

	利用率	5%
	速度	3.15 GHz
	正常运行时间	0:23:56:01
	进程	188
	线程	2579
	句柄	83109

GPU是GTX 1060 6G版本:

GPU 0
	NVIDIA GeForce GTX 1060 6GB

	驱动程序版本:	22.21.13.8554
	驱动程序日期:	09/01/2017
	DirectX 版本:	12 (FL 12.1)
	物理位置:	PCI 总线 1、设备 0、功能 0

	利用率	2%
	专用 GPU 内存	0.2/6.0 GB
	共享 GPU 内存	0.0/12.0 GB
	GPU 内存	0.2/18.0 GB

不同Size下GPU和CPU的运算时间

Epoch定50次,改变不同的Batch Size。

这个是CPU运行情况:

CPURun
CPURun

这个是GPU运行情况:

GPURun
GPURun

其实,感叹一下,GPU加速还是对CNN效果更明显,我这个模型和数据量对GTX1060来说还是有点弱。

下面数字是程序开始和程序结束的时间,代码是:

from time import time
timeBeg=time()
#中间是程序
timeEnd=time()
print (timeEnd-timeBeg)

结果为:

Epoch10050010002000300040005000600070008000900010000135844
CPU128.175.160.554.350.851.054.053.354.553.153.152.669.0
GPU522.1134.585.060.951.547.044.844.442.540.140.239.735.2
CPU/GPU0.20.60.70.91.01.11.21.21.31.31.31.32.0
GPU/CPU4.11.81.41.11.00.90.80.80.80.80.80.80.5

做个折线图:

GPUCPUSpeed
GPUCPUSpeed

可以看到,Size为100时,CPU的效率时GPU的4倍,而Size为总数据量时,GPU效率是CPU的2倍。

对于GTX 1060有1280个CUDA核心,i7-3770 是4核8线程

所以非常非常粗略的证明了,Batch-Size大于显卡核心数可以发挥显卡的最大功能。

额,确实粗略,主要结论足够了,方案欠缺点见下:

  1. 对于每个Epoch应做几个重复,取均值和方差减少随机误差;
  2. GTX1060显卡和早它1年多的i7 3770相比,这两个不同的东西是否有可比性?
  3. 每个核心的计算量应该也做个梯度(比如增大模型层数等)

这样才比较完善,不过懒得做了=-=

上面的证明过程也可以用我之前举得大力士和小学生的栗子来说明:

8个大力士类似CPU,跑的快力气大;1280个小学生类似GPU,跑的慢力气小;

如果都让他们去送信,一次只给他们100封送,大力士跑得快效率占优,小学生也就100个忙活,其他都闲的没事做;而让他们一次去送1280封信,小学生虽然跑的慢,但是一轮全部送完,大力士跑的快但是得送N多次。就是这个到理。

对了,实际中设置Batch Size大小最好设置为2的次方数,比如256,512等,据说能快很多。

到底需要设置多大的Size?

问题来了,到底需要设置多大的Size?

这个,首先作为“工程学”的深度学习,肯定是哪个准确率高,Precision和Recall都好,ROC和PR都优秀,就用哪个呗。

不过通过经验和网上大佬评测:

以下引用:谈谈深度学习中的 Batch_Sizeopen in new window

  • 随着 Batch_Size 增大,处理相同数据量的速度越快。
  • 随着 Batch_Size 增大,达到相同精度所需要的 epoch 数量越来越多。
  • 由于上述两种因素的矛盾, Batch_Size 增大到某个时候,达到时间上的最优。
  • 由于最终收敛精度会陷入不同的局部极值,因此 Batch_Size 增大到某些时候,达到最终收敛精度上的最优。

突然发现像我这种数据,量不大的,做深度学习,完全可以全部加载去找最优值啊~

博主简介
博主简介