viterbi 維特比解碼過程,狀態轉移矩陣
阿新 • • 發佈:2020-12-16
viterbi過程
1.hmm類似。 狀態轉移,發射概率
2.逐次計算每個序列節點的所有狀態下的概率值,最大概率值對應的index。
3.概率值的計算,上一個節點的概率值*轉移概率+當前概率值。
4.最後取出最大的一個值對應的indexes
難點: 理解viterbi的核心點,在於每個時間步都保留每一個可視狀態,每一個可視狀態保留上一個時間步的最大隱狀態轉移,
每一個時間步t記錄上一個最大概率轉移過來的時間步t-1的資訊,包括index/概率值累積。
迭代完時間步,根據最後一個最大累積概率值,逐個往前找即可。 根據index對應的狀態逐個往前找。
應用: 狀態轉移求解最佳轉移路徑。 只要連續時間步,每個時間步有狀態分佈,前後時間步之間有狀態轉移,就可以使用viterbi進行最佳狀態轉移計算求解。
狀態轉移矩陣的作用在於 在每個狀態轉移概率計算時,和固有的狀態轉移矩陣進行加和,再計算。相當於額外的概率新增。
import numpy as np def viterbi_decode(score, transition_params): """ 保留所有可視狀態下,對seqlen中的每一步的所有可視狀態情況下的中間狀態求解概率最大值,如此 :param score: :param transition_params: :return: """ # score [seqlen,taglen] transition_params [taglen,taglen] trellis=np.zeros_like(score) trellis[0]=score[0] backpointers=np.zeros_like(score,dtype=np.int32) for t in range(1,len(score)): matrix_node=np.expand_dims(trellis[t-1],axis=1)+transition_params #axis=0 代表發射概率初始狀態 trellis[t]=score[t]+np.max(matrix_node,axis=0) backpointers[t]=np.argmax(matrix_node,axis=0) viterbi=[np.argmax(trellis[-1],axis=0)] for backpointer in reversed(backpointers[1:]): viterbi.append(backpointer[viterbi[-1]]) viterbi_score = np.max(trellis[-1]) viterbi.reverse() print(trellis) return viterbi,viterbi_score def calculate(): score = np.array([[1, 2, 3], [2, 1, 3], [1, 3, 2], [3, 2,1]]) # (batch_size, time_step, num_tabs) transition = np.array([ [2, 1, 3], [1, 3, 2], [3, 2, 1] ] )# (num_tabs, num_tabs) lengths = [len(score[0])] # (batch_size, time_step) # numpy print("[numpy]") # np_op = viterbi_decode( score=np.array(score[0]), transition_params=np.array(transition)) # print(np_op[0]) # print(np_op[1]) print("=============") # tensorflow # score_t = tf.constant(score, dtype=tf.int64) # transition_t = transition, dtype=tf.int64 tf_op = viterbi_decode( score, transition) print('--------------------') print(tf_op) if __name__=='__main__': calculate()