KSVD
K-SVD是一個用于稀疏表示的字典學習算法,是一個迭代算法,是K-Means算法的泛化。
對于問題(1)
K-SVD的算法流程如下:
I)固定字典,利用追蹤算法(Pursuit Algorithm)求得(近似)最優的系數矩陣;
II)每次更新一個列(用SVD求解),固定字典的其它所有的列。計算新的列及其相對應系數,使得問題(1)最小化;
III)重復I)、II)直至收斂。
接下來我們會詳細的討論K-SVD算法:
在稀疏編碼階段,固定字典,問題(1)的懲罰項可以重寫為
那么問題(1)可以被分解為個獨立的問題
這個問題可以用OMP、BP、FOCUSS等追蹤算法(Pursuit Algorithm)算法求解(這也體現了K-SVD算法的靈活性;FOCUSS能夠得到更好地解,但OMP在保證比較好的解的同時,效率更高),并且如果足夠小,我們就可以得到非常好的近似最優解。
第二階段(更新字典的列)會稍微復雜一點,假設固定和,只關注字典的某一列及其相應的系數(系數矩陣的第行),問題(1)的懲罰項可以重寫為問題(2)
其中,假設項是固定的,我們要更新的是第項,矩陣表示除去第個字典項后的所有的個樣本的誤差。
也許有人會嘗試利用SVD得到可選的和,盡管SVD能夠有效的最小化上式誤差,但是由于我們沒有設置稀疏約束,所以新的向量會幾乎被填滿。
有一個簡單直觀的方法可以解決上面問題。
定義存儲用到字典項的樣本索引,也就是的非零索引,即:
定義大小為的矩陣,矩陣元素為1,其他矩陣元素均為0。
定義向量(長度為)即只保留系數中的非零值,矩陣(大小為),矩陣(大小為),即只保留與中非零位置相對應的那些列。
現在回到問題(2),由于有跟相同的支持度,所以問題(2)等價于問題(3)
現在可以直接用SVD解決問題(3),得到。最終我們得到的第一列為,乘以為。
此解決方案必須滿足兩個條件:i)的列保持規范化;ii)所有表示的支持度保持不變或者變小。
字典列的更新與稀疏表示系數更新結合在一起加快了算法的收斂。
下圖截自原論文,其中詳細描述了K-SVD算法。
總結
K-SVD一般用在字典學習中,是K-means的擴展形式。
為何叫K-SVD,是因為在字典的K個代表中,求解的時候才用的是SVD分解
下面講講K-SVD的核心
我 們在sparse?representation中知道,||Y-Dx||^2,||x||的0范都足夠最小的時候,就是表示我們的字典D最好的時候,其 含義就是我要尋找字典D,并且x中的每個向量要足夠稀疏,使得Y能夠被字典D在一定的誤差內給表示出來。這個就是核心。(當然,在訓練D的時候,有人會 想,我就用訓練集Y來代替字典不就可以了嗎?是可以,但是這樣在你以后用字典重構其他數據的時候,計算時間會很高,所以為何要減少D中的數量,以典型的代 表來代表這個字典)。
我們假設dj為D中的第j個向量,那么我們的思想是一次我就優化一個字典向量,優化完了就優化第二個,然后再迭代上面的步驟,一直到誤差小于某個范圍的時候就可以了。
那么我們的式子可以描述為?minimize||Y-SUM(j=1?to?k?(?dj?*?xjt?))||,其中xjt表示X中的第j行
設Q=Y-(D-di*xit),那么上面可以描述為||Q-?di*xit||,那么到這里就基本上差不多了。
怎么更新di和xi呢
可以對Q進行SVD分解,分解為UEV的形式,然后將U的第一列(類似于最大主元)給di,將E的第一個奇異值乘以V的第一行元素賦值給xi,然后按照上述方法更新下一個d和x
但 是這里我們要注意,我們必須要是xi滿足稀疏,那么我們這里要做一些處理,以xi的非零元素的位置構建一個矩陣,矩陣為N*M(M是xi的非零元素的個 數,N為字典中每個向量的維數)的O矩陣,然后將一Y,Pi,xi更新為Y*O,?Pi*O,xit*O,得到新的||Q-di*xit||,這個時候在 才用上面的SVD即可,
這里談下為什么,上面乘以O的操作其實就是把字典中沒有做貢獻的向量給移除掉,從而將字典空間和xi都縮減了,這樣就不會造成直接分解之前的Q的時候種V的行向量不是稀疏的性質了。
至 于為何要選用SVD,當你把SVD的最大的特征值對應的U,V向量取出來的時候,相當于一個列向量乘以一個行向量,在乘上大小?,是不是很類似與LSA, 而且就滿足了dj和xjt相乘的形式。還有一個感性的認識就是,既然要減小||Q-?di*xit||,那么只需要當di,xit等于最大的左特正向量和 右特征向量的時候,就代表了最大的接近去Q的形式了,是不是很類似最大主元PCA的方法???
就這樣吧,個人理解,有紕漏還希望大家見諒,多多指正
轉載地址:http://blog.nrdang.com/?p=35
總結
- 上一篇: 线性代数导论5——SVD分解
- 下一篇: 常用激活函数比较