逐幀softmax
CRF主要用於序列標注問題,可以簡單理解為是給序列中的每一幀都進行分類,既然是分類,很自然想到將這個序列用CNN或者RNN進行編碼后,接一個全連接層用softmax激活,如下圖所示
條件隨機場
然而,當我們設計標簽時,比如用s、b、m、e的4個標簽來做字標注法的分詞,目標輸出序列本身會帶有一些上下文關聯,比如s后面就不能接m和e,等等。逐標簽softmax並沒有考慮這種輸出層面的上下文關聯,所以它意味着把這些關聯放到了編碼層面,希望模型能自己學到這些內容,但有時候會“強模型所難”。CRF和編碼層是兩個不同的層。
BiLSTM-CRF model
我們只考慮4個標簽
- B-Person
- I- Person
- B-Organization
- I-Organization
- O
正如下圖所示
1. 在每個句子中的詞x被以詞向量和字向量所表示
2. 模型輸出的是這次詞的命名實體識別的標簽
雖然,這沒必要去了解BiLSTM的細節,但是為了了解CRF層更加清晰,你必須知道BiLSTM層輸出內容的含義。
上面這張圖已經闡述了BiLSTM輸出對於每個label的打分
CRF Layer
CRF層學習的是標簽之間的關聯信息,也可以叫做約束信息,因為B-Peson后面不可能接I-Organization
在CRF層的損失函數有兩個不同的分數,這兩個分數是CRF層關鍵性的思想
1. Emission score(當前標簽分數)
這個分數是來自編碼器的輸出,如下圖所示:
為了方便起見,我們給每個標簽一個下標
Label | index |
B-Person | 0 |
I-Person | 1 |
B-Organization | 2 |
I-Organization | 3 |
O | 4 |
當我們用xij表示emission score, i是字在句子中的下標,yi表示標簽的下標,例如,xi=1,yj=2=Xw1,B-Oranization=0.1,這表示字w1會被標注為B-Organization的分數為0.1
2. Transition score(轉移矩陣分數)
我們用tyiyj表示轉移分數,例如tB-Person,I-Person=0.9代表B-Person->I-Person的分數為0.1,因此,我們有一個代表所有標簽轉移的轉移矩陣。
為了讓我們這個轉移舉證更加的強健,我們需要加入START和END,START代表的是一個句子的開始,不是代表第一個字;END代表的是一個句子的結尾,不是代表最后一個字。
轉移矩陣的例子:下表是添加了START和END標簽后的轉移矩陣
START | B-Person | I-Person | B-Organization | I-Organization | O | END | |
START | 0 | 0.8 | 0.007 | 0.7 | 0.0008 | 0.9 | 0.008 |
B-Person | 0 | 0.6 | 0.9 | 0.2 | 0.0006 | 0.6 | 0.009 |
I-Person | -1 | 0.5 | 0.53 | 0.55 | 0.0003 |
0.85 | 0.008 |
B-Organization | 0.9 | 0.5 | 0.0003 | 0.25 | 0.8 | 0.77 | 0.006 |
I-Organization | -0.9 | 0.45 | 0.007 | 0.7 | 0.65 | 0.76 | 0.2 |
O | 0 | 0.65 | 0.0007 | 0.7 | 0.0008 | 0.9 | 0.008 |
END | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
正如上表所看到的,我們可以看到轉移矩陣可以學習某些約束性的特征:例如:B-Person->I-Organization的分數很小,I-Person->I-Organization的分數很小。
你可能會問,這個轉移矩陣是從哪里學習到這些約束性的特征的?
事實上,這個矩陣是Encoder-CRF的參數,這個是隨機初始化后,通過訓練學習到的。換句話說,CRF層可以通過訓練自己學習到。
3. 所有路徑的總得分和真正路徑得分
CRF與Softmax不同的是,Softmax把序列標注看成是n個k分類問題,后者將序列標注看成是一個1個kn問題,從kn路徑中找出一條分值最大的路徑,並且CRF是一個條件概率。
CRF在定義的時候,提出了兩個假設
假設一 該分布是指數族分布。
這個假設意味着存在函數\[f({y_1},...,{y_n};x){\kern 1pt} \]使得
\[P({y_1},...,{y_n}|x) = \frac{1}{{Z(x)}}\exp (f({y_1},...,{y_n};x))\]
注:在這里x表示CRF層的輸入,表示編碼器的輸出,y表示命名實體的標簽。
其中Z(x)是歸一化因子,因為這個是條件分布,所以歸一化因子與x(輸入)有關。這個f函數可以視為一個打分函數,打分函數取指數並歸一化就得到了概率分布。
假設二 輸出之間的關聯僅發生在相鄰位置,並且關聯是指數加性的。
這個假設意味着存在函數\[f({y_1},...,{y_n};x)\]可以更進一步簡化為
\[f({y_1},...,{y_n};x) = h({y_1};x) + g({y_1},{y_2};x) + h({y_2};x) + g({y_2},{y_3};x) + ... + g({y_{n - 1}},{y_n};x) + h({y_n};x)\]
所有路徑的總得分
假設在某一時刻所有可能的路徑都都一個分為Pi,並且總共有N條可能的路徑,那么所有路徑的總分為
\[P_t^{total} = P_t^1 + P_t^2 + ... + P_t^N = e_t^{{S_1}} + e_t^{{S_2}} + ... + e_t^{{S_N}}\]
注:e是自然對數
明確的點,這是下面遞歸求法的關鍵關鍵:
- 每個分量的分值標志上一個時刻,轉移到這個分量標簽的總分,總分表示這個時刻所有分量的的總分,相當於總分求了2次指數的和,而分量只求了一次。
- t+1時刻的每個分量(每個標簽)的結果 = t時刻所有分量的結果(這個shape為[B, N]) + 加上狀態轉移分值 (轉移到t+1時刻分量的轉移值) + t+1時刻的該標簽的分值(編碼器輸出的值),然后再e指數再求和(這里為什么要e指數再求和,跟CRF的主題思想是一樣的,哪條路徑占是最大的概率),得到的結果才是該標簽(指的是N個標簽中的一個,分量的意思)在t+1時刻的結果,所有e指數求和才是t+1時刻的Ptotal
例如,如果我們數據集中有如下標簽:
Label | Index |
B-Person | 0 |
I-Person | 1 |
B-Organization | 2 |
I-Organization | 3 |
O | 4 |
START | 5 |
END | 6 |
我們現在拿一個句子來舉例,這個句子里面有5個字,它可能的標簽是:
- 1) START B-Person B-Person B-Person B-Person B-Person END
- 2) START B-Person I-Person B-Person B-Person B-Person END
- …
- 10) START B-Person I-Person O B-Organization O END
- …
- N) O O O O O O O
在上面的例子中,如果第10個是真正的路徑,換句話說,這個是訓練集中對應的路徑,那么第10個路徑的得分肯定是在Ptotal中最大的。
下面是CRF真正路徑的概率公式,隨着訓練步數的增加,那么真正路徑的概率肯定是一直增加的。
\[\Pr {\rm{o}}{{\rm{b}}_{{\mathop{\rm Re}\nolimits} alPath}} = \frac{{{P_{{\mathop{\rm Re}\nolimits} alPath}}}}{{{P_1} + {P_2} + ... + {P_N}}}\]
現在我們來用一個例子來進行講解:
我們加入我們訓練的句子只有3個字 x = {w0, w1, w2},而且在我們的數據集中標簽就只有兩個 label = {l1, l2}
1. Emission Score,這個分值是從編碼器中輸出來的:
l1 | l2 | |
w0 | x01 | x02 |
w1 | x11 | x12 |
w2 | x21 | x22 |
2. Transition Score,狀態轉移分數:
l1 | l2 | |
l1 | t11 | t12 |
l2 | t21 | t22 |
3. 在計算的時候,我們要用到遞歸的思想,我們在這里定義兩個名稱:obs和previous,previous是求前面所有步驟的結果,obs是當前詞在編碼器中輸出的信息
在w0的時刻
obs = [x01, x02]
previous = None
相當於這一時刻的previous的result是編碼器輸出的值,所以 TotalScore(w0) = log(ex01+ex02),加上log是防止出現極小極大值
在w1的時刻
obs = [x11, x12]
previous = [x01, x02]
復制previous維度,並擴展
\[previous = \left( \begin{array}{l}
{x_{01}},{x_{01}}\\
{x_{02}},{x_{02}}
\end{array} \right)\]
復制previous維度,並擴展
\[obs = \left( \begin{array}{l}
{x_{11}},{x_{12}}\\
{x_{11}},{x_{12}}
\end{array} \right)\]
注:擴展維度和復制維度的目的是為了讓我們計算更加的方便
對previous, obs和transition的分數進行求和
\[\begin{array}{l}
scores = \left( \begin{array}{l}
{x_{01}},{x_{01}}\\
{x_{02}},{x_{02}}
\end{array} \right) + \left( \begin{array}{l}
{t_{11}},{x_{12}}\\
{x_{21}},{x_{22}}
\end{array} \right) + \left( \begin{array}{l}
{x_{11}},{x_{12}}\\
{x_{11}},{x_{12}}
\end{array} \right)\\
scores = \left( \begin{array}{l}
{x_{01}} + {t_{11}} + {x_{11}},{x_{01}} + {t_{12}} + {x_{12}}\\
{x_{02}} + {t_{21}} + {x_{11}},{x_{02}} + {t_{22}} + {x_{12}}
\end{array} \right)
\end{array}\]
紅框中表示0時刻轉移到1時刻的標簽為1的每個路徑的分值,取e指數然后求和就得到了1時刻標簽為1的總分;1時刻標簽為2同理。
所以,previous的值為
\[previous = [\log ({e^{{x_{01}} + {t_{11}} + {x_{11}}}} + {e^{{x_{02}} + {t_{21}} + {x_{11}}}}),\log ({e^{{x_{01}} + {t_{12}} + {x_{12}}}} + {e^{{x_{02}} + {t_{22}} + {x_{12}}}})]\]
注:這里求和是對某個標簽求和,是在豎直方向求值,含義是:我這個標簽這個時刻的總分
TotalScore為
\[\begin{array}{l}
TotalScore({w_0} \to {w_1}) = \log ({e^{previous[0]}} + {e^{previous[1]}})\\
TotalScore({w_0} \to {w_1}) = \log ({e^{\log ({e^{{x_{01}} + {t_{11}} + {x_{11}}}} + {e^{{x_{02}} + {t_{21}} + {x_{11}}}})}} + {e^{\log ({e^{{x_{01}} + {t_{12}} + {x_{12}}}} + {e^{{x_{02}} + {t_{22}} + {x_{12}}}})}})\\
TotalScore({w_0} \to {w_1}) = \log ({e^{{x_{01}} + {t_{11}} + {x_{11}}}} + {e^{{x_{02}} + {t_{21}} + {x_{11}}}} + {e^{{x_{01}} + {t_{12}} + {x_{12}}}} + {e^{{x_{02}} + {t_{22}} + {x_{12}}}})
\end{array}\]
在w2時刻
obs = [x21, x22]
previous = [log(ex01+x11+t11+ex02+x11+t21), log(ex01+x12+t12+ex02+x12+t22)]
擴展和復制維度
\[previous = \left( \begin{array}{l}
\log ({e^{{x_{01}} + {t_{11}} + {x_{11}}}} + {e^{{x_{02}} + {t_{21}} + {x_{11}}}}),\log ({e^{{x_{01}} + {t_{11}} + {x_{11}}}} + {e^{{x_{02}} + {t_{21}} + {x_{11}}}})]\\
\log ({e^{{x_{01}} + {t_{12}} + {x_{12}}}} + {e^{{x_{02}} + {t_{22}} + {x_{12}}}}),\log ({e^{{x_{01}} + {t_{12}} + {x_{12}}}} + {e^{{x_{02}} + {t_{22}} + {x_{12}}}})]
\end{array} \right)\]
\[obs = \left( \begin{array}{l}
{x_{21}},{x_{22}}\\
{x_{21}},{x_{22}}
\end{array} \right)\]
socres
\[\begin{array}{l}
scores = \left( \begin{array}{l}
\log ({e^{{x_{01}} + {t_{11}} + {x_{11}}}} + {e^{{x_{02}} + {t_{21}} + {x_{11}}}}),\log ({e^{{x_{01}} + {t_{11}} + {x_{11}}}} + {e^{{x_{02}} + {t_{21}} + {x_{11}}}})\\
\log ({e^{{x_{01}} + {t_{12}} + {x_{12}}}} + {e^{{x_{02}} + {t_{22}} + {x_{12}}}}),\log ({e^{{x_{01}} + {t_{12}} + {x_{12}}}} + {e^{{x_{02}} + {t_{22}} + {x_{12}}}})
\end{array} \right) + \left( \begin{array}{l}
{t_{11}},{t_{12}}\\
{t_{21}},{t_{22}}
\end{array} \right) + \left( \begin{array}{l}
{x_{21}},{x_{22}}\\
{x_{21}},{x_{22}}
\end{array} \right)\\
scores = \left( \begin{array}{l}
\log ({e^{{x_{01}} + {t_{11}} + {x_{11}}}} + {e^{{x_{02}} + {t_{21}} + {x_{11}}}}) + {t_{11}} + {x_{21}},\log ({e^{{x_{01}} + {t_{11}} + {x_{11}}}} + {e^{{x_{02}} + {t_{21}} + {x_{11}}}}) + {t_{12}} + {x_{22}}\\
\log ({e^{{x_{01}} + {t_{12}} + {x_{12}}}} + {e^{{x_{02}} + {t_{22}} + {x_{12}}}}) + {t_{21}} + {x_{21}},\log ({e^{{x_{01}} + {t_{12}} + {x_{12}}}} + {e^{{x_{02}} + {t_{22}} + {x_{12}}}}) + {t_{12}} + {x_{22}}
\end{array} \right)
\end{array}\]
計算previous
\[\begin{array}{l}
previous = [\\
\log ({e^{\log ({e^{{x_{01}} + {t_{11}} + {x_{11}}}} + {e^{{x_{02}} + {t_{21}} + {x_{11}}}}) + {t_{11}} + {x_{21}}}} + {e^{\log ({e^{{x_{01}} + {t_{12}} + {x_{12}}}} + {e^{{x_{02}} + {t_{22}} + {x_{12}}}}) + {t_{21}} + {x_{21}}}}),\log ({e^{\log ({e^{{x_{01}} + {t_{11}} + {x_{11}}}} + {e^{{x_{02}} + {t_{21}} + {x_{11}}}}) + {t_{12}} + {x_{22}}}} + {e^{\log ({e^{{x_{01}} + {t_{12}} + {x_{12}}}} + {e^{{x_{02}} + {t_{22}} + {x_{12}}}}) + {t_{12}} + {x_{22}}}})\\
]
\end{array}\]
正確的路徑得分(Real Path Score)
很明顯,在所有的路徑中只有一條是真正的路徑,如上述例子 START B-Person I-Person O B-Organization O END 這種路徑就只有一條,是唯一的,eSi是在第某個時刻某個標簽為i的得分,eS1+eS2+......+eSN為某個時刻所有標簽的總得分
如何去計算Si:Si = EmissionScore + TransitionScore
Emission Score:
Emission Score = x0,START + x1,B-Person + x2,I-Person + x3,O + x4,B-Organization + x5,O + x6,END
- xindex, label是詞xth被選中時的分數
- 這些分數全部來自BiLSTM的輸出
- 對於開始和結束標志的分數,我們設置為0
Transition Score:
Transition Score = tSTART->B-Person + tB-Person->I-Person + tI-Person->O + tO->B-Organization + tB-Organization->O + tO->END
- tlabel1->label2是轉移矩陣中label1到label2的分數
- 這個分數來自CRF層,或許可以說這是CRF層的參數
4. 損失函數
正確路徑的概率公式為:
\[\Pr {\rm{o}}{{\rm{b}}_{{\mathop{\rm Re}\nolimits} alPath}} = \frac{{{P_{{\mathop{\rm Re}\nolimits} alPath}}}}{{{P_1} + {P_2} + ... + {P_N}}}\]
我們一般遇到概率問題,一般是用MLE(極大似然)來計算loss,所以Loss Function為
\[\begin{array}{l}
LossFunction = - \log \frac{{{e^{{S_{{\mathop{\rm Re}\nolimits} alPath}}}}}}{{{e^{{S_1}}} + {e^{{S_2}}} + ... + {e^{{S_N}}}}}\\
LossFunction = - ({S_{{\mathop{\rm Re}\nolimits} alPath}} - \log ({e^{{S_1}}} + {e^{{S_2}}} + ... + {e^{{S_N}}}))\\
LossFunction = - (\sum\nolimits_{i = 1}^N {{x_{i,{y_i}}} + \sum\nolimits_{i = 1}^{N - 1} {{t_{{y_i},{y_{i + 1}}}}} } - \log ({e^{{S_1}}} + {e^{{S_2}}} + ... + {e^{{S_N}}}))
\end{array}\]
從上面推導可以看出
\[{e^{{S_1}}} + {e^{{S_2}}} + ... + {e^{{S_N}}}\]
就是我們計算的所有路徑總得分;再減去一個真實路徑下在預測時的分值
\[\sum\nolimits_{i = 1}^N {{x_{i,{y_i}}} + \sum\nolimits_{i = 1}^{N - 1} {{t_{{y_i},{y_{i + 1}}}}} } \]
注:xi, yi表示在編碼層輸出的值, tyi, yi+1表示轉移矩陣的值;最后的值可以看成是總分 - 真實路徑得分,這也符合我們的常識,如果所有路徑的得分等於真實路徑的分的話,那么loss就是0。
5.進行預測
首先我們還是定義Emission score矩陣和Transition score矩陣,這兩個矩陣都是已經訓練好了的,還是一個句子有3個字
Emission score
l1 | l2 | |
w0 | x01 | x02 |
w1 | x11 | x12 |
w2 | x21 | x22 |
Transition score
l1 | l2 | |
l1 | t11 | t12 |
l2 | t21 | t22 |
采用Viterbi algorithm來進行預測
w0時
因為w0為第一個字,所有它的最后結果就是[x01, x02],如果第一個時刻編碼器對於標簽的輸出是[0.2, 0.8],那么第一個時刻的標簽就為2;因為在第一個時刻,它不從任何地方轉移而來。所有沒有轉移矩陣的作用。
w0->w1時
obs = [x11, x12]
previous = [x01, x02]
previous擴展並復制維度
\[{\rm{pre}}vious = \left( \begin{array}{l}
previous[0],previous[0]\\
previous[1],previous[1]
\end{array} \right) = \left( \begin{array}{l}
{x_{01}},{x_{01}}\\
{x_{02}},{x_{02}}
\end{array} \right)\]
obs擴展並復制維度
\[obs = \left( \begin{array}{l}
obs[0],obs[0]\\
obs[1],obs[1]
\end{array} \right) = \left( \begin{array}{l}
{x_{11}},{x_{12}}\\
{x_{11}},{x_{12}}
\end{array} \right)\]
對previous,obs和轉移矩陣求和
\[scores = \left( \begin{array}{l}
{x_{01}},{x_{01}}\\
{x_{02}},{x_{02}}
\end{array} \right) + \left( \begin{array}{l}
{t_{11}},{t_{12}}\\
{x_{21}},{t_{22}}
\end{array} \right) + \left( \begin{array}{l}
{x_{11}},{x_{12}}\\
{x_{11}},{x_{12}}
\end{array} \right) = \left( \begin{array}{l}
{x_{01}} + {t_{11}} + {x_{11}},{x_{01}} + {t_{12}} + {x_{12}}\\
{x_{02}} + {t_{21}} + {x_{11}},{x_{02}} + {t_{22}} + {x_{12}}
\end{array} \right)\]
下面的計算與上節所描述的有所不同
\[previous = [\max (scores[00],scores[10]),\max (scores[01],scores[11])]\]
如果我們的分數如下
\[scores = \left( \begin{array}{l}
{x_{01}} + {t_{11}} + {x_{11}},{x_{01}} + {t_{12}} + {x_{12}}\\
{x_{02}} + {t_{21}} + {x_{11}},{x_{02}} + {t_{22}} + {x_{12}}
\end{array} \right) = \left( \begin{array}{l}
0.2,0.3\\
0.5,0.4
\end{array} \right)\]
這個時刻的previous,這里不用求e指數求和,因為上面設計到了歸一化因子,所以才要指數求和,而且上面也說了CRF在設計的時候就提出了假設
\[previous = [\max (scores[00],scores[10]),\max (scores[01],scores[11])] = [0.5,0.4]\]
注:這個表示了在這個時刻每個標簽的最大的分值
那么這個時候的路徑就為
\[path = [{l_2} \to {l_1}:0.5,{l_2} \to {l_2}:0.4]\]
在w2的時候
obs = [x21, x22]
previous = [0.5, 0.4]
previous擴展並復制維度
\[{\rm{pre}}vious = \left( \begin{array}{l}
previous[0],previous[0]\\
previous[1],previous[1]
\end{array} \right) = \left( \begin{array}{l}
0.5,0.5\\
0.4,0.4
\end{array} \right)\]
obs擴展並復制維度
\[obs = \left( \begin{array}{l}
obs[0],obs[0]\\
obs[1],obs[1]
\end{array} \right) = \left( \begin{array}{l}
{x_{21}},{x_{22}}\\
{x_{21}},{x_{22}}
\end{array} \right)\]
求scores
\[scores = \left( \begin{array}{l}
0.5,0.5\\
0.4,0.4
\end{array} \right) + \left( \begin{array}{l}
{t_{11}},{t_{12}}\\
{t_{21}},{t_{22}}
\end{array} \right) + \left( \begin{array}{l}
{x_{21}},{x_{22}}\\
{x_{21}},{x_{22}}
\end{array} \right) = \left( \begin{array}{l}
0.5 + {t_{11}} + {x_{21}},0.5 + {t_{12}} + {x_{22}}\\
0.4 + {t_{21}} + {x_{21}},0.4 + {t_{22}} + {x_{22}}
\end{array} \right)\]
假如我們的得到的分數為
\[scores = \left( \begin{array}{l}
0.6,0.9\\
0.8,0.7
\end{array} \right)\]
得到previous
\[previous = [0.8,0.9]\]
得到path
\[path = [{l_2} \to {l_2} \to {l_1}:0.8,{l_2} \to {l_1} \to {l_2}:0.9]\]
所以最優路徑為
\[{l_2} \to {l_1} \to {l_2}\]