前幾天在知乎刷到邱震宇同學的一個文章,如何讓 Bert 在 finetune 小資料集時更“穩”一點,主要是分析了一篇論文,感覺很有意思。

小資料集的時候,很容易就訓練震盪。作者主要是分析了兩個點進行最佳化。一個是adam偏移修正的問題,一個是權重初始化的問題。

作者透過實驗給出的結論是:1。使用誤差修正,訓練效率提高(收斂變快),開發集效果變好。2。使用權重初始化(後6層),訓練效率提高(收斂變快),開發集效果變化不大。

我做了簡單的測試,有一個小點和作者結論不太一樣,adam的修正並沒有加速模型收斂,具體的看正文分析吧。

我基於 huggingface 的 Bert,做了個兩個簡單的實驗,詳細情況如下。

文章也更新在這裡,文中如果有連結不方便調轉,可以去 github 上觀看全文:

或者去微信看。

實驗做的比較粗糙,有疏忽的地方歡迎探討。​

1。 adam偏移修正

對於adam偏移修正的實驗,我這邊得到的結果是:使用誤差修正,收斂並未變快(反而變慢),訓練更加穩定,開發集效果變好。

對於收斂速度這塊和作者結論不太一樣,多跑了幾個種子,都是收斂速度並未變快,希望有關大佬解惑。

1。1 程式碼情況講解

首先說一下,在翻看原始碼的時候,發現對於抱抱臉的 Bert 的實現,預設偏移修正是開啟的,具體程式碼的位置在這裡:

https://

github。com/huggingface/

transformers/blob/84be482f6698fac822a5113735f2242c6d3abc76/src/transformers/optimization。py#L107

抱抱臉使用的是 AdamW: Adam algorithm with weight decay fix

程式碼如下

class

AdamW

Optimizer

):

def

__init__

self

。。。

correct_bias

=

True

):

。。。

。。。

所以在測試偏移修正的對比的實驗的時候,一個是保持預設不變得出一個結果;一個是修改這個引數,你可以在呼叫函式的時候修改引數傳入值,也可以修改原始碼,如果是修改的原始碼,記得做完實驗把程式碼改回來,別對之後工作造成影響。

大家可以使用我這個 ‘手撕 Bert 原始碼’ 的倉庫中的程式碼更改相應的位置,地址在這裡:

https://

github。com/DA-southampt

on/Read_Bert_Code

1。2 任務基本情況

任務基本情況是這樣的:

任務類別:文字分類/15個類別

資料來源: 今日頭條新聞資料

資料量級:訓練集1K/開發集50k

訓練引數:

Bert : chinese_l-12_h-768_a-12,使用原始版本未做修改

batchsize:16

max_seq_length :128

learning_rate:2e-5

Epoches: 10

因為資料量較小,並且想要觀察變化,沒使用 earlly stopping,完整的跑完了10個epoch,一共是 600 steps 左右,文中所示圖以每隔 10 steps 打點顯示,所以最大顯示為 60/30。

1。3 結果展示

結果展示分為兩個,一個是 Loss 變化圖,一個是在開發集 Acc 展示圖。

Loss 變化如下圖:

Pytorch程式碼分析-如何讓Bert在finetune小資料集時更“穩”(附lossacc圖)

可以看到,沒有使用偏移糾正的 loss 收斂的更加的迅速一點,反而使用了修正的模型收斂的慢一點。但是同時可以觀測到,修正之後,模型的收斂更加的穩定,相比較而言,並沒有特別大的震盪。

Acc變化如下圖(後期沒怎麼變化,所以截取了前300steps):

Pytorch程式碼分析-如何讓Bert在finetune小資料集時更“穩”(附lossacc圖)

對於在開發集來說,經過修正的收斂速度慢,但是比較穩定,沒有大幅度的震盪,準確度相比,有可觀收益(圖中看不不太明顯,無修正最好效果:0。80,加入修正最好效果: 0。82)

2。 權重初始化

權重初始化比較簡單,平常任務也試過,因為是文字分類任務,所以在這裡只是簡單的測試了一下重新初始化 Pooler 層。

Loss結果如下圖:

Pytorch程式碼分析-如何讓Bert在finetune小資料集時更“穩”(附lossacc圖)

從圖中可以看出,重新初始化,收斂速度變快了,但是不明顯。

Acc沒什麼變化,就不上圖了,沒什麼變化(主要是被我無意刪了,懶得再重跑一次了,不影響大局)

3。 簡單總結

簡單總結一下:

與沒有修正的adam之後,修正之後,模型收斂速度變慢,收斂過程變得穩定,效果提升比較明顯。

與沒有重新初始化的模型相比,初始化最後一層pooler之後,模型收斂速度有所變快,但是不明顯,效果也沒有明顯變化。

當然初始化這個並沒有仔細去除錯層數和引數,之後可能再做個詳細實驗,主要是不覺得會有效果。

上面這兩個實驗只是基於邱震宇同學的文章做的,在這裡感謝作者。關於收斂速度這裡,結果有一點不一樣,希望有大佬可以解惑,我也會抽空去看看原論文,仔細研讀一下,看論文還有沒有值得挖的東西,有任何進展,我再和大家說。

打完收工,看完我這麼辛苦畫圖(真是累死了)的份上,點個贊再撤吧,鞠躬感謝。