字典學習(Dictionary Learning)

2022-06-18 16:36:11 字數 3700 閱讀 1832

0.0 - 為什麼需要字典學習?

這裡引用這個部落格的一段話,我覺得可以很好的解釋這個問題。

回答這個問題實際上就是要回答「稀疏字典學習 」中的字典是怎麼來的。做乙個比喻,句子是人類社會最神奇的東西,人類社會的一切知識無論是已經發現的還是沒有發現的都必然要通過句子來表示出來(從某種意義上講,公式也是句子)。這樣說來,人類懂得的知識可要算是極為浩繁的。有人統計過人類每天新產生的知識可以裝滿乙個2t(2048g)大小的硬碟。但無論有多少句子需要被書寫,對於乙個句子來說它最本質的特徵是什麼呢?毫無疑問,是乙個個構成這個句子的單詞(對英語來說)或字(對漢語來說)。所以我們可以很傲嬌的這樣認為,無論人類的知識有多麼浩繁,也無論人類的科技有多麼發達,一本長不過20厘公尺,寬不過15厘公尺,厚不過4厘公尺的新華字典或牛津字典足以表達人類從古至今乃至未來的所有知識,那些知識只不過是字典中字的排列組合罷了!直到這裡,我相信相當一部分讀者或許在心中已經明白了字典學習的第乙個好處——它實質上是對於龐大資料集的一種降維表示。第二,正如同字是句子最質樸的特徵一樣,字典學習總是嘗試學習蘊藏在樣本背後最質樸的特徵(假如樣本最質樸的特徵就是樣本最好的特徵),這兩條原因同時也是這兩年深度學習之風日盛的情況下字典學習也開始隨之公升溫的原因。題外話:現代神經科學表明,哺乳動物大腦的初級視覺皮層幹就事情就是影象的字典表示。

0.1 - 為什麼需要稀疏表示?

同樣引用這個部落格的一段話,我覺得可以很好的解釋這個問題。

回答這個問題毫無疑問就是要回答「稀疏字典學習」中稀疏兩字的來歷。不妨再舉乙個例子。相信大部分人都有這樣一種感覺,當我們在解涉及到新的知識點的數學題時總有一種累心(累腦)的感覺。但是當我們通過艱苦卓絕的訓練將新的知識點牢牢掌握時,再解決與這個知識點相關的問題時就不覺得很累了。這是為什麼呢?義大利羅馬大學的fabio babiloni教授曾經做過一項實驗,他們讓新飛行員駕駛一架飛機並採集了他們駕駛狀態下的腦電,同時又讓老飛行員駕駛飛機並也採集了他們駕駛狀態下的腦電。如下圖所示:

左圖是新飛行員(不熟練的飛行員)的大腦。圖中黃色的部分,是被認為活躍的腦區。右圖是老飛行員(熟練的飛行員)的大腦,黃色區域相比左邊的圖有明顯的減少。換言之,針對某一特定任務(這裡是飛行),熟練者的大腦可以調動盡可能少的腦區消耗盡可能少的能量進行同樣有效的計算(所以熟悉知識點的你,大腦不會再容易覺得累了),並且由於調動的腦區很少,大腦計算速度也會變快,這就是我們稱熟練者為熟練者的原理所在。站在我們所要理解的稀疏字典學習的角度上來講就是大腦學會了知識的稀疏表示。

稀疏表示的本質:用盡可能少的資源表示盡可能多的知識,這種表示還能帶來乙個附加的好處,即計算速度快。

其中$\mathbf$是已知的,現在需要用$\mathbf$和$\mathbf$來近似學習物件$\mathbf$。直觀地描述即是,現存在知識$\mathbf$,要直接從存在知識中查詢開銷太大($m$和$n$可能太大),那麼可以近似成給定乙個查詢矩陣$\mathbf$和對應的字典$\mathbf$,能夠使得查詢出來的知識和存在的知識差不多就滿足要求,並且其中查詢矩陣越簡單越好(越稀疏越好)。總的來說,即是用兩個簡單的矩陣來表示乙個複雜的矩陣的過程。

將上述問題抽象成優化問題並用數學語言描述如下,

$$\min_,\mathbf}\left \|\mathbf-\mathbf\mathbf\right \|^2_f,\ s.t. \forall i,\left \|x_i\right \|_0\leq t_0, $$

或者,也可以描述為如下,

$$\min\sum_\left \|x_i\right \|_0,\ s.t.\min_,\mathbf}\left \|\mathbf-\mathbf\mathbf\right \|^2_f\leq t_1, $$

注意到,$\left \| x_i\right \| _0$為零階範數,但在求解過程中為了方便常常用一階範數代替。

用拉格朗日乘子法可以將上述約束問題轉化為如下無約束問題,

$$\min_,\mathbf}\left \|\mathbf-\mathbf\mathbf\right \|^2_f+\lambda\left \|x_i\right \|_1,$$

注意到,這裡有兩個需要優化的變數$\mathbf$和$\mathbf$,可以交替的固定乙個變數優化另乙個變數。

2.0 - 更新$\mathbf$

假設$\mathbf$已知,記$\mathbf_k$為字典矩陣$\mathbf$的第$k$列向量,$\mathbf^k_t$為查詢矩陣$\mathbf$的第$k$行向量,那麼有如下推導,

$$\left \|\mathbf-\mathbf\mathbf\right \|^2_f=\left \|\mathbf-\sum_^\mathbf_j\mathbf_t^j\right \|^2_f=\left \|\left (\mathbf-\sum_\mathbf_j\mathbf_t^j \right )-\mathbf_k\mathbf_t^k\right \|^2_f=\left \| \mathbf-\mathbf_k\mathbf_t^k\right \|^2_f, $$

其中,$\mathbf=\mathbf-\sum_\mathbf_j\mathbf_t^j$,因此現在的優化目標為,

$$\min__k,\mathbf_t^k}\left \| \mathbf-\mathbf_k\mathbf_t^k\right \|^2_f,$$

注意到,這裡在優化求解前應該做進一步的過濾,目的是把$\mathbf_t^k$中已經為$0$的對應位置都過濾掉,而後再對非$0$的位置求最優化問題(這裡的目的是要保證$\mathbf_t^k$的稀疏性,如果不過濾掉已經為$0$的位置,雖然也能求解出目標,但無法保證最後的$\mathbf$稀疏),過濾過程可以由下圖過程直觀描述,假設現在求解的是$k=0$(其中的數值均為隨機化賦值,不代表什麼意義),紅色實線框代表當前所求對應的$\mathbf_t^k$,紅色虛線框代表需要刪除的列,過濾後如右側所示。

因此,將上述最優化問題過濾成如下形式,

$$\min__k,\mathbf_t^}\left \| \mathbf_k}-\mathbf_k\mathbf_t^\right \|^2_f,$$

優化上述問題,可以將$\mathbf}$做奇異值分解(svd),記最大的奇異值為$\sigma_$,最大奇異值對應的左奇異矩陣$\mathbf$的列向量為$\mathbf_$,對應的右奇異矩陣$\mathbf$的行向量為$\mathbf_$,則令$\mathbf_k=\mathbf_$,$\mathbf_t^=\sigma_\mathbf_$,再更新到原來的$\mathbf_t^k$。(如果求得的奇異值矩陣的奇異值是從大到小排列,那麼上述$max=1$,可以替換表示為$\mathbf_t^=\sigma\left (1,1 \right )v(\cdot,1)^t$)。(我覺得上述過程可以這樣理解,奇異值分解出來的最大奇異值對應原矩陣最有代表性的特徵,刪除這個特徵可以使得剩下的整體最小,因此選取的是最大奇異值給對應的$\mathbf$賦值。)

2.1 - 更新$\mathbf$

假設$\mathbf$固定之後,可以看作是乙個監督問題,因此可以用lasso或者omp等演算法更新(但需要保證$\mathbf$的稀疏性)。

這裡選取了k分別等於20、50、100、300進行字典學習,獲得結果如下圖所示,python**可見於我的github。

python 字典學習

字典 一 字典的建立 1使用dict key value 生成字典 dict age 1 dict age 1,name 9 dict age 1,name shijian 2使用dict zip x y 1 2 將兩個列表,對應生存字典,當你需要輸出字典,必須給他乙個接收他的地方,即h dict ...

稀疏 字典學習

pre 面試發現自己老講不條理自己的研究工作,還是要先梳理下。鑑於motivation,本文是側重結構化的15分鐘talk draft,而非務求詳盡。有興趣的歡迎私下討論。abstract 1.sparse background 2.dl dictionary learning 是什麼,用途,為什麼...

k svd字典學習

k svd字典學習 一 字典學習 字典學習也可簡單稱之為稀疏編碼,字典學習偏向於學習字典d。從矩陣分解角度,看字典學習過程 給定樣本資料集y,y的每一列表示乙個樣本 字典學習的目標是把y矩陣分解成d x矩陣 同時滿足約束條件 x盡可能稀疏,同時d的每一列是乙個歸一化向量。d稱之為字典,d的每一列稱之...