DNN: How to overfit? 牙牙學語

「學會自排車就以為會開車了」這是我這幾天的感想

以前沒實做過 Neural Network 的我,想先拿簡單資料玩一玩有個 fu,順便看看到底多威,怎麼實現 overfit。

「為什麼要 overfit ? overfitting 不是不好嗎?」如果連 overfit 都沒辦法的話在一些狀況下是沒有餘裕把 generalization 做好的 — 我是這麼想的(嚴格來講我只是想 training accuracy 100%, not necessarily overfitting)

於是簡單拿個 2D toy data 試試看:這是個 binary-class,形狀看起來像是六層「同心正方形」(有這種稱呼嗎 XD)交錯的資料

RBF SVM 要去 overfit 資料相對來說是比較直覺的。從 C 的定義以及 dual 的公式來看,只要把 C 調高 gamma 也調高就好:

紅點藍點表示 training data。圖的底色表示 SVM 根據 training data 訓練出來的模型,在這平面上每個位置的預測。用 C=2¹³, gamma=2⁴ 做參數訓練出來的模型可以發現點和底色都是同一個顏色,也就是 training accuracy = 100%。可以看到其他三張圖並不是這樣,有些 training data 本身倒進模型,預測和 data 是不同的

天真如我認為 neural network 要 overfit,不就是 layer 多一點寬一點,把模型變複雜,能表示的式子變複雜就好了嗎?結果我在 Keras 上連要 overfit 這個資料都沒辦法,無論弄多深多寬?!

折騰了一會才發現兩個結論:
1. batch_size 是不可忽視的參數
2. 要有「耐心」

原來是一開始在玩更小的資料時,把 mini batch size 設成 1,epoch 只設 200。套用到這個資料看 accuracy 和 loss 並無增進,就以為沒辦法 overfit 了,會不會是 model structure 或 activation function,甚至是 initial value 的問題 (!)。最後才發現改一下 batch size 和 epoch 就好了…

這就是手排車和自排車的不同:在這裡是連 batch size 和 max epoch 都要細心照顧的。但這同時也讓我有點好奇 batch size 的影響

Disclaimer: 下面的實驗是用非現實生活的資料,樣本數也不夠,沒有什麼科學的分析,只是玩玩有個感覺而已

Toy Data 實驗

我弄了四組類似分佈的資料:

  • 用三層 100-dimensional fully connected hidden layers (with default Adam optimizer + categorical_crossentropy loss)
  • 實驗不同的 batch size: 1, 2, 4, 8, …。跑 5000 epoch
  • 每組資料每個不同的 batch size 跑 9 次
  • 看到達 100% training accuracy 的 #epoch, training time, acc&loss 歷程
  • 程式碼:https://github.com/untitledc/keras_for_fun/tree/overfit/2d_classify_graph

#epoch:容不容易 train 壞

不同 batch size 要花多少個 epoch 到 100% training accuracy

上面表格列出要達到 100% training accuracy 在不同設定下跑的 epoch 數。並沒有特別明顯的結論,不過在小資料(或者說沒有很多根據來 overfit 的資料?)batch size = 1 時快一半都 train 壞掉。最大的資料可能 training data 排的太整齊,看起來並不難 train。

以下對於每一個實驗設定,只拿九次裡面的中位數那一次來代表那個設定。在這個情況下每一個設定最終都有達到 100% accuracy

Training time

雖然 epoch 數和 batch size 好像沒絕對關係(batch size 大 #epoch大, batch 小但 train 壞掉 #epoch也大),但 training time 有顯著差別

accuracy 和 loss 隨著 epoch 的震盪

這邊以 144-point data set 為例子

在這個資料 batch size 8 和 16 「看起來」振動沒麼大,然後 batch size 1 在同一次 training 隨著 epoch 仍然不是很穩定,但這不是重點

要多有「耐心」才能 overfit

Keras 有一個 “EarlyStopping” 的 callback,可以簡單幫助 training 提早結束(原意是避免 overfitting 不 generalize,但也可以把同樣概念套用在 training data 本身)。你可以設定如果多少個 epoch 後 loss 如果還是沒降低就提前停止。如果當初用了這個 callback 觀察 training loss 的話,在這個例子設多少不會有遺憾呢?可不是個位數可以解決的…

如果有裝 EarlyStopping,為了要達到這個 epoch,patience不能低於多少?

Keras 內建的 EarlyStopping 是檢查 epoch 絕對數量。觀察 batch size 1 和 batch size 32,雖然在 loss 上 size 1 振動很大 size 32 波動小,但是自己跟前面 epoch 比大小上,兩者達到最終目標所需要的耐心是差不多的。為了避免遺憾,負的很小的 min_delta 可能會是需要的??

如果是看 accuracy 的 patience 就是另一種情況。可能是因為 training data 太少,所以 accuracy 很容易就卡在某個瓶頸,即使 loss 可能有進步

Model prediction 的演化?

好奇 model 在中間 fit 的情況,我每 50 個 epoch 就把 model 存下來畫一次預測值的分佈。因為是 binary class,我畫 softmax 出來的機率值而非離散的類別:顏色越深表示越確定是那一個類別,白色 0.5 表示還不確定。(當然真正預測的時候 0.51 和 0.99 結果是一樣的)

另一個好玩的是看起來有先從左下角 fit 好的感覺?為什麼呢?這樣實務上 scaling 到 [0, 1] 和 [-1, 1] 是否會有差呢?

我忘記把最後達到 100% accuracy 的 model 存起來了,所以這 GIF 最後一張有可能還沒完全 fit

這個則是 train 爛的例子,可以看到有些預測值在中間忽然就變成深紅(是不是真的零要待查)

結論?

沒特別結論:這篇文章其實是記錄足跡,自爽用。在理論或是實作上並沒有太大的貢獻。倒是在玩的過程中 trace API code 和抄了很多 matplotlib 的程式有小小成就感,但並沒有解決真實的問題就是。大概就如同嬰兒般,還在牙牙學語吧