Stochastic Gradient Descent 介紹:Mini-Batch 與 Epoch

1 前言
在上一篇Deep Learning 基本功:Gradient Descent 介紹中,我們談到如何透過 Gradient Descent 更新參數 v,讓 Cost Function 的數值不斷下降。計算 Cost Function 的 Gradient 給了我們參數的「更新方向」,設定 Learning Rate 則決定參數的「更新大小」。
不過把 Gradient Descent 直接套到 Neural Network 的參數更新上,會遇到一個很現實的問題:參數更新得太慢。Stochastic Gradient Descent 就是為了解決這件事而出現的改良版。本文會說明什麼是 Stochastic Gradient Descent、它和原本的 Gradient Descent 差在哪,以及 Mini-Batch、Batch Size、Epoch 這幾個常聽到的名詞各自代表什麼。
- Gradient Descent 的瓶頸:必須看完整個訓練資料集才算得出一個 Gradient,也才能更新一次參數。
- Stochastic Gradient Descent 的做法:只看一個 Mini-Batch 就算一次 Gradient、更新一次參數,用更頻繁的更新換取更快的訓練速度。
- Batch Size 是一個 Mini-Batch 中的資料筆數,和 Learning Rate 一樣是必須手動設定的 Hyperparameter。
- 代價:每一步的方向變成抽樣的估計值,所以 Batch Size 不能太小,否則方向失準、模型收斂不了。
2 利用 Gradient Descent 更新 Neural Network 中的參數
在進入 Stochastic Gradient Descent 之前,先複習一下 Gradient Descent 是怎麼更新 Neural Network 裡的參數的。
在Deep Learning 基本功:認識 MNIST 資料集與損失函數一文中我們提過,Cost Function 的用途是評估目前 Neural Network 中參數(包含 Weight 與 Bias)的好壞:Cost 愈小,代表這組參數讓模型的輸出愈接近正確答案。

而在介紹 Gradient Descent 的那篇文章中,我們已經知道怎麼更新參數 v 來讓 Cost Function 的數值下降。到了 Neural Network,做法完全一樣,只要依樣畫葫蘆,把 v 換成 Neural Network 中的 Weight 與 Bias 就好:

每套用一次這個規則,Weight 與 Bias 就往讓 Cost Function 變小的方向挪一步。反覆做下去,Cost Function 的數值就會愈來愈小。
3 Gradient Descent 的缺點
Gradient Descent 已經算是很好用的方法了,但它有個結構性的缺點,問題出在 Cost 是怎麼被平均出來的。
前面提到的 Cost Function,其形式為:
其中 表示模型針對一筆訓練資料所計算出來的 Cost(也就是模型的這一筆輸出與正確答案的誤差),我們會將每一筆訓練資料的 Cost 加總再除以訓練資料的數目,得到平均每一筆訓練資料的 Cost。
Gradient 也是同樣的算法:先用一筆訓練資料的 Cost 算出一個 Gradient(),再把所有訓練資料的 Gradient 加總後除以訓練資料的數量,得到平均每一筆訓練資料的 Gradient:
問題就在這裡:模型必須看過整個訓練資料集,才算得出一個 Gradient,也才能更新一次參數。以 MNIST 這種有 60000 張圖像的資料集來說,跑完一整輪才換來一次參數更新,訓練當然快不起來。
4 Stochastic Gradient Descent 是什麼
Stochastic Gradient Descent 的出現正是為了加速訓練,讓參數的更新頻率高一些。用它更新參數時,模型不需要看完訓練資料集中的所有樣本才計算一次 Gradient,而是看過其中「部分樣本」就算一次 Gradient、更新一次參數。
舉個具體的例子。假設訓練資料集中有 100 筆資料:用 Gradient Descent,模型要看完 100 筆才算得出一個平均的 Gradient;用 Stochastic Gradient Descent,模型可能只看 10 筆就算出一個平均的 Gradient 並更新參數。同樣是看過 100 筆訓練資料,前者只能更新模型一次,後者卻能更新十次。
你可能會問,一定要是 10 筆嗎?20 筆或 5 筆行不行?
當然可以。在 Stochastic Gradient Descent 中,這種「部分資料」稱為 Mini-Batch,而一個 Mini-Batch 裡訓練資料的數量則稱為 Batch Size。Batch Size 和上一篇提到的 Learning Rate 同樣屬於 Hyperparameter,都要由我們(人類)手動設定,沒辦法像模型參數那樣自動被更新。
Batch Size 該設多大,本文先不深入討論,但有個原則值得先記住。我們之所以隨機抽出一部分資料組成 Mini-Batch,是為了讓參數被更新更多次、加快訓練速度;可是如果「更新的方向」不對,更新再多次模型也收斂不了(也就是 Cost Function 的數值還是降不下來)。所以 Batch Size 要夠大,大到只用這一個 Mini-Batch 算出來的平均 Gradient,就能夠近似整個訓練資料集算出來的平均 Gradient:

換句話說,Mini-Batch 是拿「一小份抽樣」去估計「全體的平均 Gradient」。抽樣抽得太少,估出來的方向就會偏掉。
5 利用 Stochastic Gradient Descent 更新 Neural Network 中的參數
回到 Neural Network。用 Stochastic Gradient Descent 更新時,Weight 與 Bias 的更新方式為:

也就是說,每一次都從整個訓練資料集中「隨機」抓出一個 Mini-Batch 的資料,假設 Batch Size 為 m,那就是 m 筆資料。把這 m 筆資料的 Gradient 加總後除以 m,得到平均的 Gradient。有了這個平均的 Gradient,我們就知道參數的更新方向,再透過 Learning Rate(也就是前面提到控制「更新大小」的那個 Hyperparameter)調整這一步要跨多大。
完成這一次 Weight 與 Bias 的更新後,再從訓練資料集中「隨機」抓出另一個 Mini-Batch,用同樣的方式更新參數。等到整個訓練資料集中的所有資料都被模型看過一遍,就表示模型完成了一個 Epoch 的訓練。
實務上訓練一個模型會跑很多個 Epoch,每個 Epoch 內又切成許多個 Mini-Batch。所以「Batch Size 設多少」直接決定了一個 Epoch 裡參數會被更新幾次:資料量 n 除以 Batch Size m,就是這一輪的更新次數。
6 結論
本文介紹了 Stochastic Gradient Descent,以及 Mini-Batch、Batch Size 與 Epoch 的概念。它與 Gradient Descent 的差別只有一句話:不必看完整個訓練資料集才更新一次參數,而是看過一個 Mini-Batch 就更新一次,用更頻繁的更新換取更快的訓練速度。
代價則是每一步的方向不再是「全體資料的平均 Gradient」,而是一份抽樣的估計值,因此 Batch Size 不能太小,否則方向失準,模型反而收斂不了。這個「更新頻率」與「梯度準確度」之間的取捨,正是實際調參時最常碰到的權衡。