【深度學(xué)習(xí)】深入探討!Batch 大小對訓(xùn)練的影響
一、概要:
批訓(xùn)練(mini-batch)的訓(xùn)練方法幾乎每一個深度學(xué)習(xí)的任務(wù)都在用,但是關(guān)于批訓(xùn)練的一些問題卻仍然保留,本文通過對MNIST數(shù)據(jù)集的演示,詳細(xì)討論了batch_size對訓(xùn)練的影響,結(jié)果均通過colab(https://colab.research.google.com/drive/1ygbjyKZH2DPhMbAU7r2CUm3f59UHq7Iv?usp=sharing)跑出,開始時對數(shù)據(jù)進(jìn)行了歸一化處理,其他的與經(jīng)典CNN代碼無差,(單GPU:Telsa T4),對結(jié)果懷疑的可以去復(fù)現(xiàn)一下。
二、實驗結(jié)果:
首先我選取了 Batch Size=64,Epochs=20,進(jìn)行了18次實驗,第一張圖橫坐標(biāo)是訓(xùn)練次數(shù),縱坐標(biāo)是每一次單獨所花時間,由圖易得趨勢是很不穩(wěn)定的,這跟批訓(xùn)練的本質(zhì)有關(guān),這在第三節(jié)中有詳細(xì)探討。由此可以得出一個結(jié)論:
''任何時候幾乎每一次的訓(xùn)練得到的結(jié)果都是互異的,當(dāng)且僅當(dāng)超參數(shù)一致和不同批之間的數(shù)據(jù)分布幾乎無差情況下不滿足。''
因而多數(shù)情況下,批訓(xùn)練出的結(jié)果不一定具有很強的代表性,之所以會比較它們的原因主要是為了比對不同配置(如超參數(shù)不一樣)帶來的相對變化,若以一次批訓(xùn)練的結(jié)果就開始信口開河就不免滑稽了。

下面兩張圖是不同的兩次訓(xùn)練所呈現(xiàn)的精確度與Epochs的關(guān)系,不難發(fā)現(xiàn),兩者的平穩(wěn)程度有很大差異,也符合前面的結(jié)論。


因為訓(xùn)練時較不穩(wěn)定,因此在以下的對照實驗中每一組均至少進(jìn)行5次實驗,選取較為接近的數(shù)據(jù)( ±3% )取平均,當(dāng)然,可以發(fā)現(xiàn) Batch Size=64 時的情況與上面又有一定差異。下表中的數(shù)據(jù)基于 Epochs=20 , Time 指的是跑完所有的Epochs所需的時間。

最慢的為 Batch Size=1 的情況,如果一開始數(shù)據(jù)經(jīng)過了shuffle處理,這種情況可以近似為SGD。
不存在無條件batch越大,時間越短的情況,只是在一定范圍內(nèi)( [1, 1024] )該結(jié)論成立,雖然1024時時間慢于512,考慮到不穩(wěn)定的情況,這里擴(kuò)大了范圍,當(dāng)然,結(jié)論在 [1,512] 范圍內(nèi)應(yīng)滿足。
當(dāng) Batch Size>=1024 之后,盡管速度比64和128來得快,但是卻較難收斂,所以較大batch和較小batch之間幾乎沒有可比性。
接下來我將后面不能完全收斂的組在 Epochs=80 的設(shè)置下繼續(xù)進(jìn)行實驗,可以發(fā)現(xiàn)會有輕微提升但還是不能收斂,關(guān)于如何實現(xiàn)大batch加速在會在第四節(jié)討論。

三、批訓(xùn)練的本質(zhì):
如果把訓(xùn)練類比成從山頂?shù)缴侥_的過程,批訓(xùn)練就是每一次你選定一個方向(一個batch的數(shù)據(jù))往下走,batch的大小可以類比成你打算每一次走多少步,當(dāng)然,深度學(xué)習(xí)是實驗型科學(xué),這里的例子只是嘗試解釋一下intuition,例子有不妥之處,樂一樂也無妨。
若 Batch Size=1 ,小碎步往下走,謹(jǐn)小慎微,自然花的時間比較多
當(dāng) Batch Size 慢慢增大時,你思考的時間相對來講會變少,但你每一次的遇到的路況不算多,因而你學(xué)習(xí)能力強,應(yīng)對出現(xiàn)過的路況能較好應(yīng)對,訓(xùn)練會一定程度提高
當(dāng) Batch Size 很大時,你一開始一個大跨步就直接來到了一個很平坦的地方,你誤以為這邊就是山腳,因而卡在了局部最優(yōu)處,當(dāng)然如果你運氣好,每次都是有坡度的情況,你很快就到了山腳。或者可以這樣想,你一下子走太多步,有些路況你給忘了,導(dǎo)致下一次走的時候做了錯誤的選擇,導(dǎo)致走不出來,這也是大batch泛化能力差的原因吧。
訓(xùn)練時需要保證batch里面的數(shù)據(jù)與整個數(shù)據(jù)的差異不太大,如果當(dāng)差異很大的時候,我們一開始遇到的路況跟后面的完全不一樣,導(dǎo)致你直接懵逼,訓(xùn)練效果差。
四、保持準(zhǔn)確率的大batch加速:
詳見:Accurate, Large Minibatch SGD: Training ImageNet in 1 Hour
https://arxiv.org/abs/1706.02677
雖然是2017的論文,但是是篇有意思的論文,通過分布式訓(xùn)練可以在 Batch Size=8k 的時候保持準(zhǔn)確率,時間為1hour,數(shù)據(jù)集為ImageNet,有多個GPU的可以去深挖一下,加速自己的訓(xùn)練,因我連GPU都是白嫖colab的,分布式更不可能了,這里只是簡單敘述而已。

Linear Scaling Rule:當(dāng)mini-batch的大小乘以k,則學(xué)習(xí)率也乘以k。
x 是從總的分布 X 中取樣出來,w 代表一個網(wǎng)絡(luò)的權(quán)重參數(shù), l(x,w) 意味著損失,將它們加起來再除以總數(shù)據(jù)分布的大小便是總損失了。

mini-batch的SGD更新一次如下, B 是一個從 X 中取樣出來的mini-batch, n=|B| 是mini-batch的大小。

在時間步 t ,權(quán)重參數(shù)為 wt ,經(jīng)過 k 次迭代更新后如下,這是一次一次疊加起來的



warm-up:一開始的學(xué)習(xí)率不那么高
臉書討論了兩種熱身方式:恒定常數(shù)和循序漸進(jìn)法進(jìn)行熱身。前者說的是在前5個Epochs保持學(xué)習(xí)率為 η ,之后再調(diào)為 kη ,在fine-tune目標(biāo)識別和分割的任務(wù)中的模型大有裨益,可是當(dāng) k 很大后,錯誤急劇上升。循序漸進(jìn)說的是一開始為 η,然后不斷加上常數(shù),要求是前5個訓(xùn)練結(jié)束后能達(dá)到 kη 。后者證明在訓(xùn)練ImageNet更有效。
技巧還有每一個分布式GPU訓(xùn)練的損失除以 kn 和對修改后的學(xué)習(xí)率進(jìn)行momentum修正。還有一些分布式的細(xì)節(jié)這里不再詳述。
五、討論:
看了臉書的那篇論文,我也突發(fā)奇想,能不能設(shè)計一個自定義的學(xué)習(xí)率來試試呢?實驗中 Batch Size=1024,Epochs=20 ,選取的自定義為每當(dāng)經(jīng)過了step size的optimizer.step()就給學(xué)習(xí)率乘上 γ ,當(dāng) Batch Size=1024 時,一共有59個batch,因而step的總次數(shù)為59 * 20 = 1180,同時考慮到模型在第6個Epoch卡在局部最優(yōu)點,將step size設(shè)為100,當(dāng)然也設(shè)置過200,400等,結(jié)果一樣收斂不了。

往期精彩回顧 本站qq群851320808,加入微信群請掃碼:
