训练神经网络时如何确定batch size?
前言
當(dāng)我們要訓(xùn)練一個(gè)已經(jīng)寫好的神經(jīng)網(wǎng)絡(luò)時(shí),我們就要直面諸多的超參數(shù)了。這些超參數(shù)一旦選不好,那么很有可能讓神經(jīng)網(wǎng)絡(luò)跑的還不如感知機(jī)。因此在面對(duì)神經(jīng)網(wǎng)絡(luò)這種容量很大的model前,是很有必要深刻的理解一下各個(gè)超參數(shù)的意義及其對(duì)model的影響的。
回顧
簡(jiǎn)單回顧一下神經(jīng)網(wǎng)絡(luò)的一次迭代過程:
即,首先選擇n個(gè)樣本組成一個(gè)batch,然后將batch丟進(jìn)神經(jīng)網(wǎng)絡(luò),得到輸出結(jié)果。再將輸出結(jié)果與樣本label丟給loss函數(shù)算出本輪的loss,而后就可以愉快的跑BP算法了(從后往前逐層計(jì)算參數(shù)之于loss的導(dǎo)數(shù))。最后將每個(gè)參數(shù)的導(dǎo)數(shù)配合步長(zhǎng)參數(shù)來進(jìn)行參數(shù)更新。這就是訓(xùn)練過程的一次迭代。
Batch Size
由此,最直觀的超參數(shù)就是batch的大小——我們可以一次性將整個(gè)數(shù)據(jù)集喂給神經(jīng)網(wǎng)絡(luò),讓神經(jīng)網(wǎng)絡(luò)利用全部樣本來計(jì)算迭代時(shí)的梯度(即傳統(tǒng)的梯度下降法),也可以一次只喂一個(gè)樣本(即隨機(jī)梯度下降法,也稱在線梯度下降法),也可以取個(gè)折中的方案,即每次喂一部分樣本讓其完成本輪迭代(即batch梯度下降法)。
數(shù)學(xué)基礎(chǔ)不太好的初學(xué)者可能在這里犯迷糊——一次性喂500個(gè)樣本并迭代一次,跟一次喂1個(gè)樣本迭代500次相比,有區(qū)別嗎?
其實(shí)這兩個(gè)做法就相當(dāng)于:
第一種:
total = 舊參下計(jì)算更新值1+舊參下計(jì)算更新值2+...+舊參下計(jì)算更新值500 ;
新參數(shù) = 舊參數(shù) + total
第二種:
新參數(shù)1 = 舊參數(shù) + 舊參數(shù)下計(jì)算更新值1;
新參數(shù)2 = 新參數(shù)1 + 新參數(shù)1下計(jì)算更新值1;
新參數(shù)3 = 新參數(shù)2 + 新參數(shù)2下計(jì)算更新值1;
...
新參數(shù)500 = 新參數(shù)500 + 新參數(shù)500下計(jì)算更新值1;
也就是說,第一種是將參數(shù)一次性更新500個(gè)樣本的量,第二種是迭代的更新500次參數(shù)。當(dāng)然是不一樣的啦。
那么問題來了,哪個(gè)更好呢?
Which one?
我們首先分析最簡(jiǎn)單的影響,哪種做法收斂更快呢?
我們假設(shè)每個(gè)樣本相對(duì)于大自然真實(shí)分布的標(biāo)準(zhǔn)差為σ,那么根據(jù)概率統(tǒng)計(jì)的知識(shí),很容易推出n個(gè)樣本的標(biāo)準(zhǔn)差為 (有疑問的同學(xué)快翻開概率統(tǒng)計(jì)的課本看一下推導(dǎo)過程)。從這里可以看出,我們使用樣本來估計(jì)梯度的時(shí)候,1個(gè)樣本帶來σ的標(biāo)準(zhǔn)差,但是使用n個(gè)樣本區(qū)估計(jì)梯度并不能讓標(biāo)準(zhǔn)差線性降低(也就是并不能讓誤差降低為原來的1/n,即無法達(dá)到σ/n),而n個(gè)樣本的計(jì)算量卻是線性的(每個(gè)樣本都要平等的跑一遍前向算法)。
由此看出,顯然在同等的計(jì)算量之下(一定的時(shí)間內(nèi)),使用整個(gè)樣本集的收斂速度要遠(yuǎn)慢于使用少量樣本的情況。換句話說,要想收斂到同一個(gè)最優(yōu)點(diǎn),使用整個(gè)樣本集時(shí),雖然迭代次數(shù)少,但是每次迭代的時(shí)間長(zhǎng),耗費(fèi)的總時(shí)間是大于使用少量樣本多次迭代的情況的。
那么是不是樣本越少,收斂越快呢?
理論上確實(shí)是這樣的,使用單個(gè)單核cpu的情況下也確實(shí)是這樣的。但是我們要與工程實(shí)際相結(jié)合呀~實(shí)際上,工程上在使用GPU訓(xùn)練時(shí),跑一個(gè)樣本花的時(shí)間與跑幾十個(gè)樣本甚至幾百個(gè)樣本的時(shí)間是一樣的!當(dāng)然得益于GPU里面超多的核,超強(qiáng)的并行計(jì)算能力啦。因此,在工程實(shí)際中,從收斂速度的角度來說,小批量的樣本集是最優(yōu)的,也就是我們所說的mini-batch。這時(shí)的batch size往往從幾十到幾百不等,但一般不會(huì)超過幾千(你有土豪顯卡的話,當(dāng)我沒說)。
那么,如果我真有一個(gè)怪獸級(jí)顯卡,使得一次計(jì)算10000個(gè)樣本跟計(jì)算1個(gè)樣本的時(shí)間相同的話,是不是設(shè)置10000就一定是最好的呢?雖然從收斂速度上來說是的,但!是!
我們知道,神經(jīng)網(wǎng)絡(luò)是個(gè)復(fù)雜的model,它的損失函數(shù)也不是省油的燈,在實(shí)際問題中,神經(jīng)網(wǎng)絡(luò)的loss曲面(以model參數(shù)為自變量,以loss值為因變量畫出來的曲面)往往是非凸的,這意味著很可能有多個(gè)局部最優(yōu)點(diǎn),而且很可能有鞍點(diǎn)!
插播一下,鞍點(diǎn)就是loss曲面中像馬鞍一樣形狀的地方的中心點(diǎn),如下圖:
(圖片來自《Deep Learning》)想象一下,在鞍點(diǎn)處,橫著看的話,鞍點(diǎn)就是個(gè)極小值點(diǎn),但是豎著看的話,鞍點(diǎn)就是極大值點(diǎn)(線性代數(shù)和最優(yōu)化算法過關(guān)的同學(xué)應(yīng)該能反應(yīng)過來,鞍點(diǎn)處的Hessian矩陣的特征值有正有負(fù)。不理解也沒關(guān)系,小夕過幾天就開始寫最優(yōu)化的文章啦~),因此鞍點(diǎn)容易給優(yōu)化算法一個(gè)“我已經(jīng)收斂了”的假象,殊不知其旁邊有一個(gè)可以跳下去的萬丈深淵。。。(可怕)
回到主線上來,小夕在《機(jī)器學(xué)習(xí)入門指導(dǎo)(4)》中提到過,傳統(tǒng)的最優(yōu)化算法是無法自動(dòng)的避開局部最優(yōu)點(diǎn)的,對(duì)于鞍點(diǎn)也是理論上很頭疼的東西。但是實(shí)際上,工程中卻不怎么容易陷入很差勁的局部最優(yōu)點(diǎn)或者鞍點(diǎn),這是為什么呢?
暫且不說一些很高深的理論如“神經(jīng)網(wǎng)絡(luò)的loss曲面中的局部最優(yōu)點(diǎn)與全局最優(yōu)點(diǎn)差不太多”,我們就從最簡(jiǎn)單的角度想~
想一想,樣本量少的時(shí)候會(huì)帶來很大的方差,而這個(gè)大方差恰好會(huì)導(dǎo)致我們?cè)谔荻认陆档胶懿畹木植孔顑?yōu)點(diǎn)(只是微微凸下去的最優(yōu)點(diǎn))和鞍點(diǎn)的時(shí)候不穩(wěn)定,一不小心就因?yàn)橐粋€(gè)大噪聲的到來導(dǎo)致炸出了局部最優(yōu)點(diǎn),或者炸下了馬(此處請(qǐng)保持純潔的心態(tài)!),從而有機(jī)會(huì)去尋找更優(yōu)的最優(yōu)點(diǎn)。
因此,與之相反的,當(dāng)樣本量很多時(shí),方差很小(咦?最開始的時(shí)候好像在說標(biāo)準(zhǔn)差來著,反正方差與標(biāo)準(zhǔn)差就差個(gè)根號(hào),沒影響的哈~),對(duì)梯度的估計(jì)要準(zhǔn)確和穩(wěn)定的多,因此反而在差勁的局部最優(yōu)點(diǎn)和鞍點(diǎn)時(shí)反而容易自信的呆著不走了,從而導(dǎo)致神經(jīng)網(wǎng)絡(luò)收斂到很差的點(diǎn)上,跟出了bug一樣的差勁。
小總結(jié)一下,batch的size設(shè)置的不能太大也不能太小,因此實(shí)際工程中最常用的就是mini-batch,一般size設(shè)置為幾十或者幾百。但是!
好像這篇文章的轉(zhuǎn)折有點(diǎn)多了誒。。。
細(xì)心的讀者可能注意到了,這之前我們的討論是基于梯度下降的,而且默認(rèn)是一階的(即沒有利用二階導(dǎo)數(shù)信息,僅僅使用一階導(dǎo)數(shù)去優(yōu)化)。因此對(duì)于SGD(隨機(jī)梯度下降)及其改良的一階優(yōu)化算法如Adagrad、Adam等是沒問題的,但是對(duì)于強(qiáng)大的二階優(yōu)化算法如共軛梯度法、L-BFGS來說,如果估計(jì)不好一階導(dǎo)數(shù),那么對(duì)二階導(dǎo)數(shù)的估計(jì)會(huì)有更大的誤差,這對(duì)于這些算法來說是致命的。
因此,對(duì)于二階優(yōu)化算法,減小batch換來的收斂速度提升遠(yuǎn)不如引入大量噪聲導(dǎo)致的性能下降,因此在使用二階優(yōu)化算法時(shí),往往要采用大batch哦。此時(shí)往往batch設(shè)置成幾千甚至一兩萬才能發(fā)揮出最佳性能。
另外,聽說GPU對(duì)2的冪次的batch可以發(fā)揮更佳的性能,因此設(shè)置成16、32、64、128...時(shí)往往要比設(shè)置為整10、整100的倍數(shù)時(shí)表現(xiàn)更優(yōu)(不過我沒有驗(yàn)證過,有興趣的同學(xué)可以試驗(yàn)一下~
參考文獻(xiàn)《Deep Learning》
本文轉(zhuǎn)載自微信訂閱號(hào)【夕小瑤的賣萌屋】,聽說每個(gè)想學(xué)機(jī)器學(xué)習(xí)的人到這里都停不下來了~
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的训练神经网络时如何确定batch size?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 为了养成NLP卷王,我画了一张路线图
- 下一篇: 惊了,掌握了这个炼丹技巧的我开始突飞猛进