天天看點

tf.contrib.crf.crf_log_likelihood()的用法

函數:

tf.contrib.crf.crf_log_likelihood(inputs, tag_indices, sequence_lengths, transition_params=None)
           

在一個條件随機場裡面計算标簽序列的log-likelihood,函數的目的是使用crf來計算損失,裡面用到最大似然估計的優化方法

參數:

inputs: 一個形狀為[batch_size, max_seq_len, num_tags] 的tensor,一般使用BILSTM處理之後輸出轉換為他要求的形狀作為CRF層的輸入

tag_indices: 一個形狀為[batch_size, max_seq_len] 的矩陣,其實就是真實标簽

sequence_lengths: 一個形狀為 [batch_size] 的向量,表示每個序列的長度

transition_params: 形狀為[num_tags, num_tags] 的轉移矩陣

傳回:

log_likelihood: 标量,log-likelihood

transition_params: 形狀為[num_tags, num_tags] 的轉移矩陣

例子:

log_likelihood,self.transition = contrib.crf.crf_log_likelihood(pred,self.Y,self.X_len)

cost = tf.reduce_mean(-log_likelihood)
           

上述例子中pred是預測出來的标簽,self.Y是正确答案的标簽,self.X_len是每一個句子的長度(ps:例子中的代碼是從命名實體識别的代碼中取出來的)

傳回:

log_likelihood:包含給定序列标簽索引的對數似然的标量

self.transition:一個[num_tags,num_tags]轉換矩陣,即轉移矩陣

上面代碼的含義是使pred與self.Y盡可能的相近時的參數值(不明白的可以查查最大似然估計是什麼含義)

題外話:

對于序列标注的問題,可以簡單的了解成分類問題,但和真正意義上的分類還是有差別的,這也是為什麼NLP中通常使用CRF/HMM而不是直接使用softmax等分類器。主要是序列标注問題的目标輸出序列本身會帶有一些上下文關聯,而softmax等分類器不能展現出這種聯系。CRF除了可以展現上下文的聯系,更重要的是利用viterbi算法,展現的是一種路徑規劃的機率。

另外,通常在NLP中,輸入每個batch的語句長度是不一樣的(單個batch語句長度可以通過padding補齊),如果用CNN做特征提取的話,batch之間的結果的次元是不同的,而采用CRF的話,就不用考慮這個次元不同的問題了

繼續閱讀