本文作者Key,博客園主頁:https://home.cnblogs.com/u/key1994/
本內容為個人原創作品,轉載請注明出處或聯系:zhengzha16@163.com
在進行神經網絡訓練時,batch_size是一個必須進行設置的參數。以前在用BP神經網絡進行預測時,由於模型結構很簡單,所以對的batch_size值的設置沒太在意。最近在做YOLO這樣的深度網絡,模型結構本身比較復雜,且訓練樣本量較大,在訓練時損失函數降得較慢。看網上有些文章說可以改變batch_size的值來提升訓練效果,我嘗試改變bz值之后發現確實有用,但對其中的原理依然不太懂,所以特地查了一些資料來搞明白這個問題,並在這里簡單進行整理。
Batch一般被翻譯為批量,設置batch_size的目的讓模型在訓練過程中每次選擇批量的數據來進行處理。一般機器學習或者深度學習訓練過程中的目標函數可以簡單理解為在每個訓練集樣本上得到的目標函數值的求和,然后根據目標函數的值進行權重值的調整,大部分時候是根據梯度下降法來進行參數更新的。
為什么要引入batch_size:
如果沒有引入batch_size這一參數,那么在訓練過程中所有的訓練數據直接輸入到網絡,經過計算之后得到網絡輸出值及目標函數值,並以此來調整網絡參數使目標函數取極小值。批量梯度下降算法(Batch Gradient Descent)正是這樣的原理,注意這里的batch和batch_size中的batch並無直接聯系,當然此時也可以理解為batch_size的值恰好等於訓練集樣本數量。
那么這樣做的缺點是什么呢?
首先,當訓練集樣本非常多時,直接將這些數據輸入到神經網絡的話會導致計算量非常大,同時對極端集的內存要求也比較高。
其次,當所有樣本同時輸入到網絡中時,往往很難確定一個全局最優學習率使得訓練效果最佳。
另外一種極端情況是:每次只讀取一個樣本作為輸入,這種方法稱為隨機梯度下降算法(Stochastic Gradient Descent, SGD)。這種情況下,可以充分考慮每一個樣本的特殊性。但是其缺點同樣非常明顯:
在每個訓練樣本上得到的目標函數值差別可能較大,因此最后通過求和或者求平均值的方法而得到的目標函數值不足以代表每個樣本。也就是說,這種方法得到的模型對樣本的泛化能力差。
為了對兩種極端情況進行折衷處理,就有了mini batches這一概念。也就是說每次只輸入一定數量的訓練樣本對模型進行訓練,這個數量就是batch_size的大小。
這樣做的優點主要有:
- 可以充分利用計算機的並行運算結構,提高數據處理速度;
- 考慮了一定數量的樣本數據,可以比較准確得代表梯度下降方向
- 跑完一次 epoch(全數據集)所需的迭代次數減少,對於相同數據量的處理速度進一步加快。
但是,batch_size的大小不能無限增大,如果取過大的batch_size,會導致每個epoch迭代的次數減小,要想取得更好的訓練效果,需要更多的epoch,會增大總體運算量和運算時間;此外,每次處理多張圖片時,雖然可以發揮計算機並行計算的優勢,但是也要充分考慮計算機內存大小的限制。
另外,在對樣本數據進行批量處理時還會產生另外一個問題:當我們采用樣本增強技術或者訓練樣本中重復樣本過多時,如果按順序對輸入樣本進行批量,可能導致同一批數據相關性較高,即使采取了設置了batch_size值也只能代表某一小部分的數據,因此獲取batch_size的數據時需要隨機抽取。在實際中,可以通過對訓練集樣本進行shuffle來實現這一操作。
當然這里還有一個問題我還沒搞明白,就是一般我們在選取batch_size的值時往往采取2的冪數,常見的如16,32,64,128等。取這些值是為了充分發揮計算機的數據處理能力,哪位大神能給講一下其中的原因?或者給推薦一些相關資料來搞明白這個問題?
參考文獻:
1. 深度學習訓練過程中BatchSize的設置
3. 伊恩·古德費洛等,《深度學習》