1. 程式人生 > >【演算法】BILSTM+CRF中的條件隨機場

【演算法】BILSTM+CRF中的條件隨機場

BILSTM+CRF中的條件隨機場

tensorflow中crf關鍵的兩個函式是訓練函式tf.contrib.crf.crf_log_likelihood和解碼函式tf.contrib.crf.viterbi_decode

crf_log_likelihood(inputs, tag_indices, sequence_lengths, transition_params=None)
    Computes the log-likelihood of tag sequences in a CRF.
    
    Args:
      inputs: A [batch_size, max_seq_len, num_tags] tensor of unary potentials
          to use as input to the CRF layer.
      tag_indices: A [batch_size, max_seq_len] matrix of tag indices for which we
          compute the log-likelihood.
      sequence_lengths: A [batch_size] vector of true sequence lengths.
      transition_params: A [num_tags, num_tags] transition matrix, if available.
    Returns:
      log_likelihood: A scalar containing the log-likelihood of the given sequence
          of tag indices.
      transition_params: A [num_tags, num_tags] transition matrix. This is either
          provided by the caller or created in this function.
viterbi_decode(score, transition_params)
    Decode the highest scoring sequence of tags outside of TensorFlow.
    
    This should only be used at test time.
    
    Args:
      score: A [seq_len, num_tags] matrix of unary potentials.
      transition_params: A [num_tags, num_tags] matrix of binary potentials.
    
    Returns:
      viterbi: A [seq_len] list of integers containing the highest scoring tag
          indicies.
      viterbi_score: A float containing the score for the Viterbi sequence.

看著這兩個函式定義,我懵逼了。在看完了李航的《統計學習方法》後,我以為我可以輕鬆搞定bilstm+crf中的crf。然而對著這兩個函式發呆了半天,發現怎麼跟書上的理論對不上號?特徵函式呢?轉移函式呢?怎麼訓練完之後就只有個transition_params,維度還是num_tags x num_tags。這是什麼東西。

鬱悶的在網上找資料,終於看到了參考資料裡面的講解,總算是醍醐灌頂看懂了。這裡記錄一下。

bilstm和crf的作用

在bilstm+crf結構中,bilstm的輸出已經是各個標籤取值的概率了,crf的作用僅僅是根據標籤間的關係做結果調整。借用參考資料裡的圖片

那麼,bilstm已經輸出標籤取值概率了,為什麼還需要crf層呢。因為直接用bilstm輸出的標籤有些並不合理,比如B-Person,I-Organization就是一個不合理的序列。crf做的就是在bilstm輸出的基礎上,調整輸出標籤,使得標籤結果順序更為合理。

crf細節

與之前介紹的標準形式相似,在條件\(x\)的情況下,序列\(y\)出現的概率\(P(y|x)\)可以表達為:
\[P(y|x)=\frac{e^s}{e^{s_1}+e^{s_2}+e^{s_3}+...+e^{s_n}}\]
\(e^s\)是當前序列的分數,分母是所有序列分數的和。
可以對比一下之前介紹crf那篇的公式,到這裡跟傳統的crf都是一樣的,只是表達上現在的公式化簡了一些。

下面就是和前一篇不同的地方了,區別就在於\(s\)。在之前的介紹中,\(s\)由狀態特徵函式和轉移特徵函式組成,並有各自的權重。而bilstm+crf中的crf其\(s\)的組成要簡單很多。
先介紹兩個重要變數:
\(EmissionScore\): bilstm輸出的每個位置是各個標籤的概率。是一個\(seq\_len\times num\_tags\)的矩陣。如上圖黃色矩形部分。
\(TransitionScore\): 標籤間的轉移概率。是一個\(num\_tags\times num\_tags\)的矩陣

上面矩陣的含義是,如果前一個標籤是START,而後一個標籤為B-Person的概率為0.8,而START後接I-Organization的概率只有0.0008。這是符合人們的認知的。

這樣,就可以介紹\(s_i\)的組成了。
\[s_i=EmissionScore+TransitionScore\]

對於序列來說,比如有一個序列是“START B-Person I-Person O B-Organization O END”,則
\[EmissionScore=x_{0,START}+x_{1,B-Person}+x_{2,I-Person}+x_{3,O}+x_{4,B-Organization}+x_{5,O}+x_{6,END}\]
\[TransitionScore=t_{START->B-Person} + t_{B-Person->I-Person} + t_{I-Person->O} + t_{0->B-Organization} + t_{B-Organization->O} + t_{O->END}\]
\[e^s=e^{EmissionScore+TransitionScore}\]

看到這裡就知道bilstm之上的crf與普通crf的區別了。普通crf的樣本概率受特徵函式和相關權值的影響。而bilstm上的crf則沒有特徵函式,也沒有權值,結果受bilstm層輸出的各個位置標籤概率,以及標籤間的狀態轉移矩陣影響。對於bilstm+crf的crf層來說,要學習的就只有標籤間狀態轉移矩陣而已。

看到這,再對應tensorflow的函式定義,就很明白了。
crf_log_likelihood函式輸出的transition_params,就是要求解的狀態轉移矩陣。
viterbi_decode(score, transition_params),就是通過bilstm的輸出score和求解的狀態轉移矩陣transition_params來解碼最終結果。

參考資料

  1. https://createmomo.github.io/2017/09/12/CRF_Layer_on_the_Top_of_BiLSTM_1/
  2. https://createmomo.github.io/2017/09/23/CRF_Layer_on_the_Top_of_BiLSTM_2/
  3. https://createmomo.github.io/2017/10/08/CRF-Layer-on-the-Top-of-BiLSTM-3/
  4. https://createmomo.github.io/2017/10/17/CRF-Layer-on-the-Top-of-BiLSTM-4/
  5. https://createmomo.github.io/2017/11/11/CRF-Layer-on-the-Top-of-BiLSTM-5/
  6. https://createmomo.github.io/2017/11/24/CRF-Layer-on-the-Top-of-BiLSTM-6/