前言:html
本次實驗是用EM來學習HMM中的參數,並用學好了的HMM對一些kinect數據進行動做分類。實驗內容請參考coursera課程:Probabilistic Graphical Models 中的的最後一個assignmnet.實驗用的是kinect關節點數據,因爲HMM是一個時序模型,且含有隱變量,因此這個實驗不是很好作。你們對HMM不熟悉的話能夠參考網友的實驗:code.git
kinect人體關節數據中, 每一個關節點由3個座標數據構成,多個關節點數據(實驗中爲10個)構成一個pose,多個pose構成一個action,每一個action所包含的pose個數可能不等。其示意圖以下:github
圖中有3個action: clap, high kick, low kick. 而每一個action能夠由不一樣的pose序列構成,上面的每一個action中列舉出了3種狀況,其長短可不一。在HMM模型中,上面模型中每一個節點表明的是觀察節點,表明一個pose,該pose可由狀態變量(隱變量)產生,好比具備3個pose的action示意圖以下:算法
其中的狀態變量S1,S2,S3並非該pose的action標籤,而是介於pose和action之間的一個隱藏類別,它與action和pose數據同時有關,這裏state的物理意義不是十分明確,state節點的個數可由驗證集經過實驗來肯定。dom
實驗中一些函數的簡單說明:wordpress
[P loglikelihood ClassProb] = EM_cluster(poseData, G, InitialClassProb, maxIter):函數
實驗1的內容。poseData大小爲N*10*3,表示N個pose的數據。G,P和練習八意思同樣,爲模型的結構信息。InitialClassProb大小爲N*K,表示這N個樣本分別屬於K個類別的初始機率,ClassProb表示EM聚類完成後這N個樣本屬於各個類別的機率值。loglikelihood中保存的是每次EM迭代時的log似然值。模型中的隱變量爲每一個樣本所屬的類別。程序中的E步是:給定模型中的參數(每一個關節點的CLG參數),求出每一個樣本屬於各個類別的機率。M步爲:給定每一個樣本屬於K個類別的機率後,來求模型中每一個關節點的參數。tornado
[mu sigma] = FitG(X, W):學習
該函數相似於練習八中的FitGaussianParameters(),只是這裏每一個樣本多了一個可信度權值,求高斯參數的時候須要把這個權值考慮進去。測試
[Beta sigma] = FitLG(X, U, W):
該函數相似於練習八中的FitGaussianParameters(),也是多了一個參數W,表示輸入進來的數據X和父節點數據U的可信度爲W中對應的值。每一個state都會學習到的本身的參數beta和sigma,爲HMM模型中的發射矩陣。
out = logsumexp(A):
很明顯是求exp(A),而後求和,最後取log值,內部採用了防止數據溢出的方法。若是A是一個矩陣,則上面的操做是針對A的每一行進行的。
[P loglikelihood ClassProb PairProb] = EM_HMM(actionData, poseData, G, InitialClassProb, InitialPairProb, maxIter):
實驗2的內容。參數結構比較複雜,簡單介紹下。
actionData結構體向量:該向量中的每個元素都是一個action。action.action表示對應動做的名稱,在本函數中,由於是訓練某個類別的HMM模型,因此其名稱都同樣。action.marg_ind,表示該action的pose數據在poseData向量中的行索引,同時也爲pose屬於各個state的機率值在ClassProb中的索引。action.pair_ind:action中連續的pose之間的邊在PairProb中的索引,PairProd矩陣中的每一行表示對應edge兩端之間的state轉移機率。
poseData, G, InitialClassProb,maxIter和前面的差很少。
InitialPairProb:大小爲V*K^2的矩陣,其中V爲模型中邊的數目,K爲HMM模型中狀態的個數,該矩陣與HMM轉移矩陣的計算有關。
博文前面的HMM action示意圖中對應的poseData, PairProb值形式以下所示:
返回值P和之前的P結構稍有不一樣,由於這裏考慮到了HMM之間的狀態轉移,因此有P.transMatrix來表示HMM中狀態轉移矩陣,尺寸爲K*K。另外P.c再也不表示每一個pose所屬action的機率分佈,而是初始狀態分佈。P.c表示在這些數據下,這個action對應state的先驗機率。
EM_HMM()函數的做用是:用某個action的序列樣本actionData來訓練它的HMM模型,對應的模型參數包括轉移機率,發射機率(包括各個狀態下的關節點參數),初始機率。主要分爲2個步驟:E步:給定參數,經過clique tree求數據;M步:給定數據,求HMM參數,好比初始狀態分佈計算:
轉移機率的計算公式爲:
與發射機率相關的CLG參數計算參考練習八。
[M, PCalibrated] = ComputeExactMarginalsHMM(F):
F爲HMM模型的factorlist,M爲在該模型上進行精確推導的條件機率,與之前練習4實驗中的推理相似。PCalibrated爲校訂好的clique tree,
[accuracy, predicted_labels] = RecognizeActions(datasetTrain, datasetTest, G, maxIter):
實驗3的內容。datasetTrain爲訓練HMM模型時的樣本,它是長度爲3的向量(本實驗只有3個動做類別),每一個元素都是一個結構體。第1個結構體表示動做clap的數據,結構體中包含了actionData, poseData, InitialClassProb, InitialPairProb信息。第2個結構體爲high_kick動做的數據,第3個結構體爲low_kick動做的數據。datasetTest爲測試樣本,也是一個結構體,裏面有actionData,poseData和labels. labels對應每一個action的標籤,「clap」 = 1, 「high kick」 = 2, 「low kick」 = 3。實現該函數時首先用datasetTrain訓練3個HMM模型參數,而後針對datasetTest中的每一個action數據,計算它的posedata在每一個模型各個狀態下的機率。而後在這3個模型上分別創建clique tree,並算出生成這些樣本的機率,機率值最大的那個模型對應的action爲其分類類別。
相關理論知識點:
這部分可參考Corsera中的課件以及網友demonstrate的blog:PGM 讀書筆記節選(十四)
不徹底數據(incomplete data)主要包含2部分:缺失數據(missing data)和含隱變量的數據。
缺失數據又分2種狀況:一是數據樣本中有一些沒有被觀察到的量,通常用問號代替。另一種是數據樣本中直接少了一些數據,至於少了哪些數據,在哪些位置(序列數據)少了數據,都沒法知道。
Missing at Random(MAR):隨機缺失的一些樣本,此時在給定觀察到的樣本條件下,沒被觀察的樣本與控制缺失的開關變量相互獨立。
帶有隱變量的Likelihood函數值會有多個極值點,而且極值點的個數與隱變量的個數成指數關係(實際上,這些局部極值的log似然值也不相同)。帶缺失數據的情形與之相似。有多個極值點的函數時即便學習到了其中一個極值點的參數,這組參數也未必就是模型中的true parameters. 隱變量的likelihood的另外一個缺點就是likelihood函數不能按照變量和CPD等來局部分解,而且模型中一些不相關的參數也開始相關了(引入了新的v-structure)。
帶隱變量likelihood函數參數的求解雖然能夠採用一些高級的梯度降低法,但實際中用得較多的是EM算法。關於EM算法能夠參考我前面的博文對EM算法的簡單理解. 在隱變量likelihood這裏,簡單來講E步爲給定模型參數,產生」徹底」數據(把那些隱變量的數據也生成出來);M步爲給定」徹底」數據,計算模型參數。EM算法的特色是在前面迭代過程當中收斂速度較快,越到後面收斂越慢。
梯度降低法是沿着一條直線進行搜索,而EM算法是沿着一個凸函數曲線來搜索其極值,有理論保證EM算法迭代過程當中對應似然函數值不會降低。
參考資料:
coursera課程:Probabilistic Graphical Models