當深度學習趕上動態規劃

傳統意義上的算法一直都很優雅。html

命名實體識別任務

Hong Kong is part of China.算法

若是要讓機器理解上面的句子的「情感」,那麼實際上就是將句子視爲一個總體並作分類;若是要讓機器細化地理解句子中每個組成部分之間的關係,那麼就須要首先擁有找出句子組成部分的能力,好比,機器要能識別出其中的"Hong Kong"是一個實體,而不是兩個獨立的單詞。這時機器作的就是 對句子中每個詞分類。分類的結果可能以下:網絡

這就是命名實體識別(named entity recognition,如下簡稱NER)的通俗理解。NER須要將文本中的元素分紅預約的類,粗粒度爲3大類(實體類、時間類、數字類),細粒度7小類(人名、地名、組織名、機構名、時間、日期、貨幣、百分比)或更加精細的類別。函數

而NER處理過的命名實體序列能夠爲更多的下游任務提供方便,好比知識圖譜、文本理解、輿情分析。性能

和情感分類任務不一樣的是,NER任務也是 大小寫敏感的,很好理解,一個詞若是由大寫開始,那麼該詞頗有多是人名、地名等,所以有不少模型在設計上考慮到了字符級(character-level)特徵的提取。有用LSTM的[1],也有用CNN的[2]。學習

DNN/算法設計

我在PyTorch的官網找到了有關序列標註的詳盡代碼:ADVANCED: MAKING DYNAMIC DECISIONS AND THE BI-LSTM CRF[3],這份教程的代碼寫得十分精煉,且和論文[1]中的思路有不少類似之處。翻譯

LSTM-CRF模型

LSTM

LSTM已經見得多了,其做用就是從輸入的詞向量序列中抽取上下文信息,提取到的信息送至下游分類任務。而下游任務能夠是使用全鏈接層直接預測,也能夠是後接CRF分類。設計

在論文[1]中,做者對比了多種不一樣結構模型的效果,最終得出結論:LSTM+CRF的組合性能最好code

CRF

CRF的核心思想就是:在爲某一個詞分類的時候,同時考慮該詞附近的詞的性質。htm

舉個例子,「主-謂-賓」符合語法,是一種機率很大的分類序列,而「主-系-賓」這種序列,雖然系語出如今句子中間部分的機率很大,可是「系-賓」搭配就很怪異。

借用論文[1]中的表示方式:

  1. 輸入模型的待預測序列爲X=(x_1,x_2,\dots,x_n)
  2. LSTM等「上游特徵提取器」的輸出是一個矩陣P_{n \times k}p_{i,j}表示第i個詞是標籤j的分數,也就是考慮「詞-標籤」的轉化;
  3. 下游預測任務用到了另一個矩陣A_{(k+2) \times (k+2)}a_{i,j}表示從標籤i和標籤j相鄰的可能性,也就是考慮「標籤-標籤」的轉化;之因此是k+2階矩陣,是考慮到startend標籤;
  4. 模型輸出預測序列爲\textbf{y}=(y_1,y_2,\dots,y_n),其中序列長度爲n,預測類別數爲k

爲了肯定一個標註序列的好壞,定義評分標準以下:

s(X,\textbf{y}) = \sum_{i=0}^{n}{A_{y_i,y_{i+1}}} + \sum_{i=1}^{n}{P_{i,y_i}}

自定義的損失函數

以上的s(X,\textbf{y})僅是分數,須要再使用Softmax從分數映射到機率:

p(\textbf{y}|X) = \frac{\exp{s(X,\textbf{y})}}{\sum_{\tilde{y} \in Y_X}{\exp{s(X,\tilde{\textbf{y}})}}}

Y_X是全部可能的序列。訓練過程就是讓目標序列機率最大化,做者對上式求了對數,是一種等價的作法:

\begin{aligned}
  \log(p(\textbf{y}|X)) &= s(X,\textbf{y}) - \log(\sum_{\tilde{y} \in Y_X}{\exp{s(X,\tilde{\textbf{y}})}}) \\
  &= s(X,\textbf{y}) - logadd_{\tilde{y} \in Y_X}\exp{s(X,\tilde{\textbf{y}})}
\end{aligned}

這即是該模型的損失函數,模型的學習過程就是使用 梯度上升 最大化\log(p(\textbf{y}|X)),或者使用__梯度降低__ 最小化-\log(p(\textbf{y}|X))

這裏還有另一個問題:若是一個句子很長,而且待標記的標籤數衆多,枚舉每一種可能的路徑會致使時間複雜度爆炸。

在代碼實現[1]中,做者在BiLSTM_CRF._forward_alg函數中實現了……

解碼

LSTM-CRF模型的解碼方式用到了動態規劃——Viterbi算法,對應代碼實現[1]中的BiLSTM_CRF._viterbi_decode。由於「從網絡輸出中解碼出固定個數的標籤」這個問題實際上能夠抽象爲圖論問題,即從源點到終點的最優路徑。

與Beam Search的區別

Viterbi是動態規劃算法,而與其有着類似算法步驟的Beam search,卻淪爲貪心算法。

我的理解,實際上這二者的本質區別不在於其算法自己,而在於應用場景。Viterbi算法被普遍應用於分類,而Beam search一般用於翻譯,這兩類任務預測數據規模上的區別造就了算法類型的本質區別。分類任務輸出值是標籤,標籤空間大小一般不會很大,所以能夠枚舉每一種狀態,便於找出全局最優解;而翻譯任務的輸出是詞,詞庫的大小不容許算法精確枚舉每一種狀況,只能退而求其次記錄局部最優,所以退化爲貪心算法。

LSTM-Stack模型

學過編譯原理的人必定記得SR算法。在論文[1]中除了使用LSTM外,仍是借用了SR算法的思想,

參考

  1. Neural Architectures for Named Entity Recognition
  2. End-to-end Sequence Labeling via Bi-directional LSTM-CNNs-CRF
  3. ADVANCED: MAKING DYNAMIC DECISIONS AND THE BI-LSTM CRF
相關文章
相關標籤/搜索