0%

0成本的NLP訓練技巧 - 不需額外資料就可提升準確率

訓練我們的NLP模型或者一個神經網路,需要的是大量的標記的資料。資料有限的時候,怎麼樣再給自己的模型帶來一些提升呢?這裡將會給大家介紹一些有趣的技巧:

label information enhance

在一個分類模型上,我們輸入一串文本,輸出它的類別:

X1 X2 X3… 會作為輸入的embedding,作為輸入文本的representation。而輸出的部分,則只有1維,表示每一個類別的機率。也就是說,對於模型而言,是理解輸入的文本,然後從候選類別中選一個。是個類別的話,就是0-3選一個數字。
這就像是看不到選項文本的百萬富翁:

所以,是有必要提供標籤訊息同時讓模型更好學到兩者的聯繫,解決方法很簡單,將標籤丟到輸入的文本就好:

Focal Loss

在做分類的時候,某一類的樣本總是特別多,這就導致模型會偏向將結果判斷成這一類,可以輕鬆得到很高的準確度,但這個準確度對實作來説,並沒有什麽用。

常見的例子是:資料中有大量正樣本,比如 100筆資料中,當中有95筆資料是正樣本,5筆資料是負樣本。那模型只要將結果都預測為正樣本,模型準確度就可以有95%

神經網絡訓練跟樣本不平衡的關係
那麽從神經網絡的角度來看,可以怎麽解決這個問題呢?
簡單總結下神經網絡訓練過程,就是根據我們的 objective function得到離目標結果有多近(loss/梯度),通過反向傳播的方式讓預測結果與目標結果越近越好。

當樣本很不平衡,如剛剛的例子,100筆資料中,當中有95筆資料是正樣本,5筆資料是負樣本舉例好了,若網絡將所有樣本預測成正樣本,所以正樣本的loss會是0,負樣本的loss則會是1,有五個負樣本,loss就有5。
收到loss以後網絡開始調整參數,若干輪訓練后,每一個正樣本或多或少都會有一點loss,比如本來是100%確定是正樣本,現在變成99%確定了。這1%的差距也就是正樣本的loss,假設95個正樣本都掉了1%,正樣本提供的total loss就是0.95了。此時負樣本已經做很好了,單看負樣本loss也降到2。

這時候發現,我們回傳總共的loss會是2.95,正樣本這些一點點,一點點的loss,積少成多以至於最終正樣本提供的loss佔總共的32% !
可是我們在乎99%到100%的差距嗎?顯然不是的,但這一點點的差距在大量樣本的帶動下,影響著loss的計算,使得網絡的更新不如人意。這也是從神經網絡的訓練來看,樣本不平衡會帶來的問題。

對做很好的地方減少關注 - Focal loss
人總會過於關注自己做得好的地方,看來神經網絡也一樣XD
對於預測來説,51%是正樣本,跟81甚至99%其實沒有差別。最後預測出來的結果也是正樣本。
預測結果越接近正確的結果,其實也就越不需要更新了。但完全沒有梯度也不好,其可能受其他資料更新的結果影響,使得結果不進反退

爲了讓結果能保持下去,我們需要讓模型每次都要有梯度更新,而準確度越高,更新的量應該越少,才可以避免被大量容易處理的資料帶歪。

做法也呼之欲出了,給梯度一個權重,這個權重使得準確度越高,梯度越小,作為懲罰
本來cross entropy的計算是

-log(Px)

越高的機率,意味越不需要更新,因此懲罰越多,因此可以改成
-(1-Px)* log(Px)

為了讓這個懲罰更加有力,可以讓其變成指數級
-(1-Px)* log(Px)

這個就是focal loss,如果在二分類,還會有一個調節權重的參數

Label Smoothing

分類任務通常會預測一個類別的機率為1,其他類別為0,最大化類別之間的差距。模型對於結果的預測已經有9成確信,為了提升到1,可能會讓一些weight去強行fit那些樣本,然其輸出更加接近1。因此,讓模型預測目標到0.9就好,可以減緩overfitting的現象。

PhraseMask

這一個方法專門為MaskLM打造。在之前的文章中:
https://voidful.github.io/voidful_blog/implement/2019/12/02/bert-recent-update-2019/

其中有提到,MaskLM應該是目前最好用的預訓練方式,因此提高masklm的效果相比改用或增加其他方法應該會更佳有效。
讓MaskLM效果更好,提高Mask範圍到一個合理大小,例如 詞或phrase或連續區間 是一個有效的方式。以詞的方法需要提供詞表 - 斷詞錯誤,或者詞表收錄不全 會影響到訓練的結果。
因此,我們可以改用統計的方法得到一個動態的詞表,再用這個詞表做masking

這個統計到方法之前也有提到過,透過找boundary做斷詞這件事:

https://github.com/voidful/Phraseg