Bilstm+crf 常用於序列標注任務,例如命名實體識別,詞性標注
以 “人家是小萌新”作詞性標注為例,分詞后為“人家 是 小萌新”,對應的詞性為名詞,動詞,名詞
為簡化問題,假設詞性只有名詞和動詞兩類,
Bilstm 輸出為每個詞stoftmax輸出最大概率值對應的label,只用BiLSTM的話,輸出label之間是獨立的但傳統BiLSTM的不足未考慮到標簽之間的相互約束性,比如假設Bilstm輸出的最可能標簽序列為"NVV",但根據標簽轉移矩陣,"V→V“概率很小,那么根據得分定義,這種序列不太能得到較高分數

-
為什么要有CRF層呢
CRF是判別模型,在詞性標注栗子里,X對應的是單詞序列,Y則是對應的單詞詞性
分詞后為“人家 是 小萌新”,對應的詞性為名詞,動詞,名詞,為簡化問題,假設詞性只有名詞和動詞兩類,對於三個詞來說,共有2 3=8種路徑,其中真正的路徑是【N→ V→ N]
要做的就是 使得真實路徑的得分在所有路徑得分中最大,加上log 變成對數損失函數,再前面加上負號 就變成最小化損失函數,下圖所示

如圖總結到, 最終的損失函數等於 所有路徑得分總和 - 真實路徑得分
現在問題轉化為 1、怎么定義一條路徑的得分
2、怎么計算所有路徑總分(肯定不會是暴力舉出所有可能的路徑啦,前向)
3、怎么預測隱變量-標簽(維特比算法來解碼)
下面一點一點展開來說;
1、一條路徑得分定義為 轉移特征函數 和狀態特征函數的加和。
Pi,yi 表示的是 第i 個token 輸出為yi詞性)的概率,Ayi,yi+1 表示的是 前一個標簽轉 yi移到下一個標簽 yi+1的概率。假設共有N個標簽,則轉移概率矩陣為(N+2) *(N+2)
以START→N→V→N→END 這條真實路徑為例,EMISSION_SCORE=X0,START + X1,N + X2,V + X3,N + X4,END
TRANSITION_SCORE= TSTART→N + TN→V + TV→N + TN→V + TV→END , 這些分數來自於CRF層
整個過程中需要訓練的參數為:
- BiLSTM中的參數
- 轉移概率/得分矩陣A
2、計算所有路徑總分
整個過程是一個分數的前向滾雪球的過程。它的實現思想有點像動態規划。首先,w0所有路徑的總分先被計算出來,然后,我們計算w0 -> w1的所有路徑的得分,最后計算w0 -> w1 -> w2的所有路徑的得分,也就是我們需要的結果。狀態分數定義如下
| N | V | |
| W0 | X0,N | X0,V |
| W1 |
X1,N | X1,V |
| W2 |
X2,N | X2,V |
轉移矩陣如下
| N | V | |
| N | TN→N | TN→V |
| V | TV→N | TV→V |
設置兩個變量,previous_score 表示 到上一個位置的路徑總分,current_info 表示考慮當前位置的token 帶來的新信息
對於第一個詞W1,有兩條路徑START→ N ,START→V,得分分別為X1,N ,X1,V
對於第二個詞來說,現在previous_score=(X1,N ,X1,V),cur_info=(X2,N ,X2,V),transition_score=
現在因為維度不同,三個矩陣不能相加,因而將previous_score,cur_info 擴展為
,
,三個矩陣相加得
這個矩陣中的四個值分別對應的是從W1 到W2 的四條路徑的得分。
第一次寫博真的發現不是個輕松活,OK,繼續迭代一次!
從W2→ W3,現在我們的previous_score 為上一步的
,cur_info=(X3,N ,X3,V),transition_score=
3、預測標簽(詞性)
在效率方面相對於粗暴地遍歷所有路徑,viterbi 維特比算法到達每一列的時候都會刪除不符合最短路徑要求的路徑,大大降低時間復雜度。
w1→w2 ,假設W1最佳預測結果是N, 三矩陣相加后
=
,對矩陣一列選列最大值(標紅顯示),W2被預測為N標簽的最大得分為0.5(路徑為N →N,W2被預測為V標簽的概率為0.6(N→V)
我們有兩個變量來儲存歷史信息,best_score 和 best_score_id,在每輪迭代中,我們將最佳分數存儲到best_score,同時,最佳分數所對應的類別索引(N標簽:0,V標簽:1)存儲到best_score_id
best_score=[[0.5,0.6]],best_score_id=[[]]
