訓練神經網絡的時候,基本就是三個步驟:
- 正向計算網絡輸出;
- 計算Loss;
- 反向傳播,計算Loss的梯度來更新參數(即梯度下降)。
在小的訓練集上聯系的時候,通常每次對所有樣本計算Loss之后通過梯度下降的方式更新參數(批量梯度下降),但是在大的訓練集時,這樣每次計算所有樣本的Loss再計算一次梯度更新參數的方式效率是很低的。因此就有了隨機梯度下降和mini-batch梯度下降的方式。下面來具體講講。
批量梯度下降(Batch Gradient Descent)
上面說了,批量梯度下降就是每個epoch計算所有樣本的Loss,進而計算梯度進行反向傳播、參數更新:
其中,\(m\) 為訓練集樣本數,\(l\) 為損失函數,\(\epsilon\) 表示學習率。批量梯度下降的優缺點如下:
- 優點
每個epoch通過所有樣本來計算Loss,這樣計算出的Loss更能表示當前分類器在於整個訓練集的表現,得到的梯度的方向也更能代表全局極小值點的方向。如果損失函數為凸函數,那么這種方式一定可以找到全局最優解。 - 缺點
每次都需要用所有樣本來計算Loss,在樣本數量非常大的時候即使也只能有限的並行計算,並且在每個epoch計算所有樣本Loss后只更新一次參數,即只進行一次梯度下降操作,效率非常低。
隨機梯度下降(Stochastic Gradient Descent)
先貼上隨機梯度下降的偽代碼
隨機梯度下降每次迭代(iteration)計算單個樣本的損失並進行梯度下降更新參數,這樣在每輪epoch就能進行 \(m\) 次參數更新。看優缺點吧:
- 優點
參數更新速度大大加快,因為計算完每個樣本的Loss都會進行一次參數更新 - 缺點
1.計算量大且無法並行。批量梯度下降能夠利用矩陣運算和並行計算來計算Loss,但是SGD每遍歷到一個樣本就進行梯度計算和參數下降,無法進行有效的並行計算。
2.容易陷入局部最優導致模型准確率下降。因為單個樣本的Loss無法代替全局Loss,這樣計算出來的梯度方向也會和全局最優的方向存在偏離。但是由於樣本數量多,總體的Loss會保持降低,只不過Loss的變化曲線會存在較大的波動。像下圖這樣:
小批量梯度下降
似乎隨機梯度下降和批量梯度下降走向了兩個計算,那么將這兩種方法中和一下呢?這就得到了min-Batch Gradient Descent。
小批量梯度下降將所有的訓練樣本划分到 \(batches\) 個min-batch中,每個mini-batch包含 \(batch_size\) 個訓練樣本。每個iteration計算一個mini-batch中的樣本的Loss,進而進梯度下降和參數更新,這樣兼顧了批量梯度下降的准確度和隨機梯度下降的更新效率。
可以看到,當 \(batch\_size=m\) 時,小批量梯度下降就變成了批量梯度下降;當 \(batch\_size=1\) ,就退化為了SGD。一般來說 \(batch\_size\) 取2的整數次方的值。
注意,這里有個坑!
事實上,我們平時用梯度下降的時候說的最多的SGD指的是小批量梯度下降,各種論文里所說的SGD也大都指的mini-batch梯度下降這種方式。tensorflow中也是通過定義batch_size的方式在優化過程中使用小批量梯度下降的方式(當然,也取決於batch_size的設置)。