生成模型初探:從PCA到AE

生成模型初探:從PCA到AE

 

人類較機器蘊含智能,其中最重要的是一種創造性。無論是作詩繪畫還是音樂,藝術家都得在一定規則的限定下帶着腳鐐舞蹈,但是他們卻可以跳出少數幾個機械的規則,創造出無窮無盡的作品,這便是機械難以做到的事情。傳統的機械學習,僅僅從數據庫中檢索答案似乎與創造新信息相去甚遠;後來的統計學習,將隨機性引入,但是面對龐大的參數空間卻無能爲力。直到神經網絡的出現,才初步解決了這個問題,基於神經網絡強大的非線性擬合能力可以對輸入數據分佈進行學習,只要對學習到的分佈進行採樣,就可以生成新的數據,這就是生成模型的基本形式。但是將隨機性與採樣引入深度學習還有很多其他的問題(比如採樣這個操作是不可導的),對這些問題的研究衍生了現在很多生成模型,比如VAE、GAN、pixelCNN等等,這些將在後續的文章進一步補充,本文作爲生成模型的初探,主要將順着傳統機器學習的軌跡,去解構“生成與創造”智能的本質。

 

PCA

乍看上去,PCA 是傳統的數據挖掘手段,好像與生成模型這種“先進”概念相去甚遠。而本文要說的是PCA做的不僅僅是降維,更是自編碼器一個基本的雛形,其意義不僅在於壓縮參數,更在通過壓縮後的參數重現原始信息。

PCA(principal component analysis),主成分分析法,是KL變換在協方差矩陣下的引申,KL變換是最優的正交變換,PCA也是這樣一個正交變換。正如線性代數中的施密特正交化方法,將一個矩陣做正交變換是很有必要的,因爲變換之後的矩陣在新的空間中可以由正交基分解,而每個正交基之間有最小的相關性:因爲它們兩兩垂直。因此,PCA的目的是降低離散隨機變量的相關性,使得數據在一個正交變換之後的新空間中具有最小的相關性,這樣獨立成分就可以被最大化分離,這是直觀定性理解。

考慮這樣一個數據集X$_{n*m}$(有m個樣本,每一個樣本有n個屬性,組成一個n維度列向量),我們假設樣本矩陣X已經歸一化了(X的協方差矩陣和自相關矩陣相同)。我們的操作就是想通過一個正交變換矩陣D$_{n*l}$將一個l維度的向量c變換回x而且要求變換回的x具有真實數據的最多的信息。顯然這是一個最優化問題:

                                                              $ \mathop{argmin}\limits_{\textbf{D}} $\left \| \textbf{X}-\textbf{D}\textbf{D}$^{T}$ \textbf{X}||\right \|$^{2}$,s.t.\textbf{D}^{T}\textbf{D}=\textbf{I}

爲了要求c變換回的x具有最大的信息保留我們還必須有:

                                                            \textbf{c}$^{*}$=$ \mathop{argmin}\limits_{\textbf{c}} $\left \| \textbf{x}-\textbf{Dc}\right \|$^{2}$ \quad for \quad \textbf{x} \quad in \quad \textbf{X}

在這個最優化問題中對c求導可以得到滿足最大信息的c滿足\textbf{c}=\textbf{D}^T\textbf{x},將這個代入第一個最優化問題有:

                                                        $ \mathop{argmin}\limits_{\textbf{D}} $\left \| \textbf{X}-\textbf{D}\textbf{D}$^{T}$ \textbf{X}||\right \|$^{2}$,s.t.\textbf{D}^{T}\textbf{D}=\textbf{I}\\ =$\mathop{argmin}\limits_{\textbf{D}}$\,tr(\textbf{D}^T\textbf{XX}^T\textbf{D})

這個是個二次型最大值的求解,顯然,二次型最大值與\textbf{XX}^T的特徵值的最大值息息相關。而D也應該是\textbf{XX}^T特徵值對應的特徵向量組成的矩陣,其中特徵值越大,D作爲分解的正交基佔的比重越大。而那些小的特徵值對於原始矩陣X信息貢獻最小,完全可以忽略,這樣就達到了降維的目的。具體的操作是對歸一化的數據矩陣X求其協方差矩陣\textbf{XX}^T,然後對其做特徵分解並將特徵值排序,得到D,只要取前l個最大的,就可以降維到c了。

具體的代碼如下:

# -*- coding: utf-8 -*-
"""
Created on Thu Oct 17 21:32:37 2019

@author: lenovo
"""

import matplotlib.pyplot as plt # plt 用於顯示圖片
import matplotlib.image as mpimg # mpimg 用於讀取圖片
import numpy as np

imag = mpimg.imread('1.jpg') 
#將rbg轉換爲灰度圖
def rgb2gray(rgb):
  return np.dot(rgb[...,:3], [0.299, 0.587, 0.114])
gray = rgb2gray(imag)
plt.subplot(211)
plt.imshow(imag) # 顯示圖片
plt.axis('off') # 不顯示座標軸
plt.show()
plt.subplot(212)
plt.imshow(gray,cmap='Greys_r') # 顯示圖片
plt.axis('off') # 不顯示座標軸
plt.title('original image')
plt.show()

'''
PCA 
圖片是1200*1920的,可以看作是1920個1200維的數據
'''
#歸一化:
N = 10 #降維的目標維度數目100
mean = np.mean(gray,axis = -1)
norm_gray = gray - mean.reshape([1200,1])
cov = np.dot(norm_gray,norm_gray.T)      #求出協方差矩陣,維度是1200*1200,相當於每一個維度互相的關係
e_vals,e_vecs = np.linalg.eig(cov)       #對協方差矩陣進行特徵分解,得到特徵值與特徵向量

D = e_vecs[:,:N]                         #由於特徵值已經排列好大小了,取其中最大的N個對應的特徵向量組成D

encoded = np.dot(D.T,norm_gray)          #數據降維
print('降維後的維度:',encoded.shape)

decoded = np.dot(D,encoded)               #數據重建                                      

plt.figure(2)
plt.imshow(decoded,cmap ='Greys_r')
plt.title('encode in 10 dim')

#%%
#下面是不同的降維維度對應的恢復效果
plt.figure(3)
N = [5,10,15,20]
for i in range(4):
    D = e_vecs[:,:N[i]]
    encoded = np.dot(D.T,norm_gray)  
    decoded = np.dot(D,encoded)   
    plt.subplot(2,2,i+1)
    plt.imshow(decoded,cmap ='Greys_r')
    plt.title('_{}_dim'.format(N[i]))

下圖是一個對新垣結衣圖片壓縮的演示,我們把圖片看作X矩陣,就可以進行PCA降維,圖中給了不同壓縮維度l的壓縮復原效果:

                                                                   

                                     

可以發現,在降維至5,基本就是人鬼模辯狀態,隨着l上升,可以看到更多的細節,當l=n,就可以完美復原,這個時候c也就成了完備編碼。當然實際的圖像壓縮肯定不能用PCA,因爲PCA對不同的數據壓縮都要求不同的變換矩陣D,而且在傳輸時,也必須吧碼錶D傳輸,所以實際的音頻或是圖像的壓縮常採用的是DCT(離散餘弦變換),它是固定變換矩陣的,而且一定條件下是KL變換的最好近似。此外大規模求解特徵值是一件極其消耗計算資源的事情,特別是在維度很高的情況下,一般對於高維數據,PCA的求解是通過奇異值分解(SVD),比如在sklearn庫中就可以快速進行PCA,一般這種標準庫中的PCA求解特徵值是以求解奇異值來快速計算的。

       將一幅圖分解,然後復原好像有點模糊的圖,好像除了能讓存儲空間小一點就沒啥用了,這又與我們所述的創造性與人工智能有什麼關係?我們再仔細觀察這幾個圖片,當l=5時就是選取了前5個最大的特徵值,而這個時候人臉的基本輪廓就初步有了,而後面的10、20乃至更高維,就是在這個基礎上修修補補一些細節而已。這時候我們已經發現了一些壓縮變量維度的規律,就是前幾個變量代表圖片中主要的輪廓,而後面的多數維度,都僅僅是一些細節。從信號處理的角度來說,就是前幾維是圖片信息的低頻,而後面都是高頻信息,說到低頻高頻,很多小朋友都會聯想到一個著名的變換:傅里葉變換,而且巧合的是,離散傅里葉變換的矩陣也是正交的,它是一個正交變換,只不過在複數域上,叫做酉變換;更進一步,離散傅里葉變換的變換矩陣來自於數據的循環矩陣的特徵值分解(這裏請翻看具體的信號處理書籍),看來它也很類似PCA嘛。到這裏,知道壓縮後的維度對應輪廓還是細節、低頻還是高頻意味着什麼呢?意味着,我們可以通過操縱這些維度,去控制生成的不同的圖案。珊珊來遲,終於到了生成的時候。

 

        我們想要生成新的圖片,一般來說就是生成不同的輪廓以及不同的細節,但是多數人臉輪廓基本一致,而其細節千變萬化,所以我們真正需要改變的就是那些後面的維度,而這些維度不但對應着細節,更多還對應着噪聲(正是因爲如此,忽略後面的維度可以降維而去除了噪聲干擾),給不同的噪聲好像就可以生成不同的細節?事實上,即使到現在類似VAE亦或是GAN的模型,其實也基本上實現的就是給不同噪聲的操作,因爲我們可以認爲圖案的細節就是分佈被嚴格限制的噪聲。當然要學習到這種噪聲的分佈需要擬合能力很強的神經網絡。

         當然,真實世界的多數數據沒有像聲音、圖像這麼有完備的解釋,壓縮出的維度既不對應低頻也不對應高頻,相互雜糅着,存在於我們這些小腦瓜難以想象的高維中。爲了擬合複雜的分佈,我們可以想到的方法就是用多次PCA,每次降維一小點,提取足夠的信息再降維一小點,這就是AE(自編碼器的雛形),實際上PCA就是隻有一個隱層的線性自編碼器,只要誤差函數一致優化結果是等效的,只不過,自編碼器由於激活函數的存在,被賦予了更多的非線性擬合能力,這也是PCA所難以企及的,也爲其真正用於真實數據奠定基礎。

 

                                        

獲得數據的壓縮僅僅是生成的第一步,我們必須知道不同壓縮維度的實際含義,並且予以限制(VAE),進一步,我們希望某些維度可以僅僅控制某些具體的屬性(對抗訓練)。。。。。。這些將在後續的生成模型文章進一步介紹。

 

————————————————————————————————

想要進一步瞭解機器學習現在的發展,關注vx公衆號:機器學習俱樂部,點贊轉發還有獨家代碼相關書籍資源分享哦!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章