[轉] LSTM+ CRF中的損失函式
fromhttps://blog.csdn.net/u013963380/article/details/108696552
本文翻譯,原文地址:
https://createmomo.github.io/2017/10/08/CRF-Layer-on-the-Top-of-BiLSTM-3/
https://createmomo.github.io/2017/10/17/CRF-Layer-on-the-Top-of-BiLSTM-4/
https://createmomo.github.io/2017/11/11/CRF-Layer-on-the-Top-of-BiLSTM-5/
三、CRF損失函式
CRF損失函式由兩部分組成,真實路徑的分數 和 所有路徑的總分數。真實路徑的分數應該是所有路徑中分數最高的。
例如,我們的資料集中有如下幾種類別:
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
假設每種可能的路徑的分數為,共有條路徑,則路徑的總分是:
,是一個數學常量。(下節會詳細介紹如何計算,這裡你可以把它當作這條路徑的分數)。
如果第十條路徑是真實路徑,也就是說第十條是正確預測結果,那麼應該是所有可能路徑裡分數最高的。根據如下損失函式,在訓練過程中,BiLSTM-CRF模型的引數值將隨著訓練過程的迭代不斷更新,使得真實路徑所佔的比值越來越大。
那麼現在的問題就是:
- 如何定義路徑的分數
- 怎麼計算所有路徑的分數
- 當計算所有的路徑分時,是否需要窮舉多有可能的路徑?(答案是不需要)
四、真實路徑分數
很明顯,在所有的可能的路徑中有一條是真實的路徑。比如在上述的類別序列中,“START B-Person I-Person O B-Organization O END”是一條真實的路徑。不正確的路徑如“START B-Person B-Organization O I-Person I-Person B-Person”。是第條路徑的分數。
在訓練階段,crf的損失函式只需要兩種類別的分數,真實路徑的分數 和 所有路徑的總分數。在所有的可能路徑的分數中,真實路徑的分數應該是最高的。
當然計算是十分簡單的,下面讓我們聚焦如何來計算。
我們假設“START B-Person I-Person O B-Organization O END”是一條真實的路徑:
- 一個句子中有5個單詞,分別是
- 新增開始和結尾單詞,分別是
- 包含兩個部分,
tips:Emission Score 和 Transition Score在《BiLSTM中的CRF層(二)CRF層》一文中已經介紹。
(1)Emission Score(發射分數):
- 是第索引的單詞被標註為的分數
- 這些分數來自前一層BiLstm的輸出
- 可以設定為0
(2)Transition Score(轉移分數):
- 是從label1轉移到label2的分數
- 這些分數來自於CRF層。換句話說,這些分數其實是CRF層的引數
五、所有路徑的分數
上面提到所有路徑的分數。計算所有路徑的總分最簡單的方式是:窮舉所有可能的路徑,分別計算路徑分,最後求和。但是這種方式是十分低效的,而且訓練時間也是不可忍受的。
下面以一個簡單的例子來說明如何高效的計算所有路徑的分數。
Step1:recall the CRF loss function
CRF損失函式的定義是,我們把它變成log損失函式如下:
,由於我們訓練的目標通常是最小化損失函式,所以我們加上負號:
(原文中在求真實路徑的分數的時候,求和用的是N和N-1,但是從上面的求解發射分數和轉移分數公式看,這裡的N應該是句子的長度words,N-1應該是標籤數num_tag,所有的路徑總數N應該是N=(num_tag)^(words),否則對應不上。不知道是不是作者為了簡化統一用N表示,還是本人理解錯誤。。。囧囧囧)
在上面,我們已經知道如何計算真實路徑的分數,下面我們只需要找到一種高效的方式來計算。
Step2:recall the Emission and Transition Score
為了簡化說明,這裡我們假設我們訓練模型的句子只有3的長度,標籤只有2種:
我們從Bi-Lstm層獲得的發射分數如下:
tips:表示單詞被標籤為的分數。
從CRF層獲得的轉移分數如下:
tips:表示從標籤轉移到標籤的分數
Step3:START FIGHTING!
首先要記得我們的目標是
整個過程其實是分數累加的過程。它的思想和動態規劃如出一轍。總而言之就是,首先單詞的所有路徑的總分被計算出來;然後,計算從的所有路徑的得分,最後計算的所有路徑的得分,也就是我們最終要的結果。
接下來,你會看到兩個變數:obs和 previous。previous儲存了之前步驟的結果,obs代表當前單詞的資訊。
=======================================================================================================
:
如果我們的句子只有一個單詞,前一個步驟沒有任何的結果,因此previous=None。另外,我們只能獲取到,和是上面提到的從BiLSTM層獲得的發射分數。
因此,這裡單詞的所有路徑分數為:
=======================================================================================================
:
(1) 將previous擴充套件為:
(2) 將obs擴充套件為:
將previos和obs擴充套件是為了計算總分更加高效。下面將會看到
(3) 對previou、obs和轉移分數求和:
然後改變previos的值
到這裡,第二次迭代實際上已經完成了。然後,我們使用新的previous值來計算的所有路徑總分:
從上面公式可以看出,這就是我們的求解目標
在上述公式中:
=======================================================================================================
下面的手碼太累了,直接貼原文的截圖,截圖出自(https://createmomo.github.io/2017/11/11/CRF-Layer-on-the-Top-of-BiLSTM-5/),原理是一樣的。
=======================================================================================================
上述過程建議用手推一遍,對理解這個過程十分有用。。。
至此,我們完成了的求解過程。
六、如何利用CRF來推理
前面幾節介紹了Bi-Lstm-CRF的模型結構以及CRF損失函式。我們可以使用開源的深度學習框架(Keras、tensorflow等)來實現一個Bi-Lstm-CRF模型。而且用這些框架最好的是不用自己來實現反向傳播這個過程,更有的框架已經實現了CRF層,只需要新增一行程式碼就可以完全實現Bi-Lstm-CRF模型。
推理的過程和上述求解所有路徑總分的過程有點相似,每次獲取得分最高的路徑,最終選擇所有路徑中得分最高的路徑為最佳路徑。
詳細過程見原文:https://createmomo.github.io/2017/11/24/CRF-Layer-on-the-Top-of-BiLSTM-6/
這裡不再講述,因為整個過程十分簡單,理解了第五節中的求解過程即可。
/* 人應該感到渺小,在宇宙面前,在美面前,在智慧面前; 而在人群中,應該意識到自己的尊嚴。*/