1. 程式人生 > 其它 >關於CRF層的學習率【轉載以學習、回憶】

關於CRF層的學習率【轉載以學習、回憶】

面試的時候 會有人問你針對BERT+CRF這種模型做出了什麼調參?

這裡其實可以答換用不同的BERT  比說哈工大版本的wwm這種整詞遮蔽的BERT天然適合識別詞級別的任務。

還可以答優化了CRF層的學習率引數,這裡呢是以前看到蘇神的帖子瞭解到的,不過又記不太清了,因此轉載蘇神的文章以學習、回憶。

來源:蘇劍林. (Feb. 07, 2020). 《你的CRF層的學習率可能不夠大 》[Blog post]. Retrieved from https://kexue.fm/archives/7196

轉載開始,有刪改。

CRF是做序列標註的經典方法,它理論優雅,實際也很有效,如果還不瞭解CRF的讀者歡迎閱讀舊作

《簡明條件隨機場CRF介紹(附帶純Keras實現)》。在BERT模型出來之後,也有不少工作探索了BERT+CRF用於序列標註任務的做法。然而,很多實驗結果顯示(比如論文《BERT Meets Chinese Word Segmentation》)不管是中文分詞還是實體識別任務,相比於簡單的BERT+Softmax,BERT+CRF似乎並沒有帶來什麼提升,這跟傳統的BiLSTM+CRF或CNN+CRF的模型表現並不一樣。

 這兩天給bert4keras增加了用CRF做中文分詞的例子(task_sequence_labeling_cws_crf.py),在除錯過程中發現了CRF層可能存在學習不充分的問題,進一步做了幾個對比實驗,結果顯示這可能是CRF在BERT中沒什麼提升的主要原因,遂在此記錄一下分析過程,與大家分享。

糟糕的轉移矩陣 #

由於筆者用的是自己實現的CRF層,所以為了證明自己的實現沒有錯誤,筆者跑完BERT+CRF的實驗(BERT用的是base版本)後,首先觀察了轉移矩陣,大體數值如下:

其中第ii行jj列的數值表示從i轉移到j的得分(記為Sij),其中分值的絕對值並沒有意義,只有相對比較的意義。順便說明下,本文的中文分詞用的是(s,b,m,e)(s,b,m,e)的字標註法,如果不瞭解可以參考《【中文分詞系列】 3. 字標註法與HMM模型》

然而,直觀來看,這並沒有學到一個好的轉移矩陣,甚至可能會帶來負面影響。比如我們看第一行,Ssb=0.459Ss→b=−0.459,Sse=0.707

,即Ssb明顯小於Ss→e。但是,根據(s,b,m,e)的標註設計,s後面是有可能接bb的,但不可能接e,所以Ssb<Sse

是明顯不合理的,它可能引匯出不合理的標註序列,理想情況下Sse應該為才對。

 這樣不合理的轉移矩陣一度讓筆者覺得是自己的CRF實現得有問題,但經過反覆排查以及對比Keras官方的實現,最終還是確認自己的實現並沒有錯誤。那麼問題出現在哪呢?

學習率的不對等 #

如果我們先不管這個轉移矩陣的合理性,直接按照模型的訓練結果套上Viterbi演算法去解碼預測,然後用官方的指令碼去評測,發現F1有96.1%左右(PKU任務上),已經是當前最優水平了。

轉移矩陣很糟糕,最終的結果卻依然很好,這隻能說明轉移矩陣對最終的結果幾乎沒有影響。什麼情況下轉移矩陣幾乎沒影響呢?可能的原因是模型輸出的每個字的標籤分數遠遠大於轉移矩陣的數值,並且區分度已經很明顯了,所以轉移矩陣就影響不到整體的結果了,換言之這時候直接Softmax然後取argmax就很好了。為了確認,我隨機挑了一些句子,觀察模型輸出的每個字的標籤分佈,確實發現每個字的分數最高的標籤分數基本都在6~8之間,而其餘的標籤分數基本比最高的要低上3分以上,這相比轉移矩陣中的數值大了一個數量級以上,顯然就很難被轉移矩陣影響到了。這就肯定了這個猜測。

一個好的轉移矩陣顯然會對預測是有幫助的,至少能幫助我們排除不合理的標籤轉移,或者說至少能保證不會帶來負面影響。所以值得思考的是:究竟是什麼阻止了模型去學一個好的轉移矩陣呢?筆者猜測答案可能是學習率

BERT經過預訓練後,針對下游任務進行finetune時,只需要非常小的學習率(通常是105量級),太大反而可能不收斂。儘管學習率很小,但對於多數下游任務來說收斂是很快的,很多工都只需要2~3個epoch就能收斂到最優。另一方面,BERT的擬合能力是很強的,所以它能比較充分地擬合訓練資料。

這說明什麼呢?首先,我們知道,每個字的標籤分佈是直接由BERT模型算出來的,而轉移矩陣是附加的,與BERT沒直接關係。當我們以10510−5量級的學習率進行finetune時,BERT部分迅速收斂,也就是每個字的標籤分佈會迅速被擬合,同時因為BERT的擬合能力比較強,所以迅速擬合到一個比較優的狀態(即目標標籤打分很高,並且拉開了與非目標標籤的差距)。而由於轉移矩陣跟BERT沒什麼聯絡,當逐字標籤分佈迅速地收斂到較優值時,它還是以10510−5的速度“悠哉悠哉”地前進著,最終要比逐字標籤的分數低一個數量級。而且,當逐字標籤分佈都已經能很好擬合目標序列了,也就不再需要轉移矩陣了(轉移矩陣的梯度會非常小,從而幾乎不更新)。

思考到這裡,一個很自然的想法是:能不能增加CRF層的學習率?筆者嘗試增大CRF層的學習率,經過多次實驗,發現CRF層的學習率為主體學習率的100倍以上時,轉移矩陣開始變得合理起來了,下面是BERT主體學習率為105、CRF層的學習率為102(即1000倍)時,訓練出的一個轉移矩陣

 這樣的轉移矩陣是合理的,量級也是對的,它學習到了正確的標籤轉移,比如ss,,b比sm,e分數大、bm,ebs,b分數大,等等。不過,就算調大了CRF層的學習率,結果相比不調整時沒有明顯優勢,歸根結底,BERT的擬合能力太強了,就連Softmax效果都能達到最優了,轉移矩陣自然也不能帶來太大的提升。

(附註:增大學習率的實現技巧可以參考《“讓Keras更酷一些!”:分層的學習率和自由的梯度》。)

更多的實驗分析 #

CRF沒給BERT帶來什麼效果變化,原因是BERT的擬合能力太強了,導致不需要轉移矩陣效果都很好。那如果降低BERT的擬合能力,會不會帶來顯著差異呢?

前面的實驗中是使用BERT base的第12層的輸出來finetune的,現在我們只用第1層的輸出來進行finetune,來測試上述調整是否會帶來顯著性差異。結果如下表:

 由於只用了1層BERT,所以主體學習率設定為103(模型越淺,學習率可以適當地越大),主要對比的是調整CRF層學習率所帶來的提升。從表格可以看到:

這說明,對於擬合能力不是特別強大的模型(比如只用BERT的前幾層,或者對於某些特別難的任務來說,完整的BERT擬合能力也不算充分),CRF及其轉移矩陣還是有一定幫助的,而精調CRF層的學習率能帶來更大的提升。此外,上述所有的實驗都是基於BERT進行的,對於傳統的BiLSTM+CRF或CNN+CRF來說同樣的做法有沒有效果呢?筆者也簡單實驗了一下,發現有些情況下也是有幫助的,所以估計這是CRF層的一個通用技巧。

內容簡單彙總 #

本文從給bert4keras新增的CRF例子出發,發現BERT與CRF結合的時候,CRF層可能存在訓練不充分的問題,進而猜測了可能的原因,並通過實驗進一步肯定了猜測,最後提出通過增大CRF層學習率的方式來提升CRF的效果,初步驗證了(在某些任務下)其有效性。