自動編碼器【轉(zhuǎn)】

查看原文

1 簡介

Deep Learning最簡單的一種方法是利用人工神經(jīng)網(wǎng)絡(luò)的特點,人工神經(jīng)網(wǎng)絡(luò)(ANN)本身就是具有層次結(jié)構(gòu)的系統(tǒng),如果給定一個神經(jīng)網(wǎng)絡(luò),我們假設(shè)其輸出與輸入是相同的,然后訓練調(diào)整其參數(shù)卦羡,得到每一層中的權(quán)重。自然地麦到,我們就得到了輸入I的幾種不同表示(每一層代表一種表示)绿饵,這些表示就是特征。自動編碼器就是一種盡可能復現(xiàn)輸入信號的神經(jīng)網(wǎng)絡(luò)瓶颠。為了實現(xiàn)這種復現(xiàn)拟赊,自動編碼器就必須捕捉可以代表輸入數(shù)據(jù)的最重要的因素,就像PCA那樣粹淋,找到可以代表原信息的主要成分吸祟。

2 具體過程

2.1 給定無標簽數(shù)據(jù),用非監(jiān)督學習學習特征


在我們之前的神經(jīng)網(wǎng)絡(luò)中桃移,如第一個圖屋匕,我們輸入的樣本是有標簽的,即(input, target)借杰,這樣我們根據(jù)當前輸出和target(label)之間的差去改變前面各層的參數(shù)过吻,直到收斂。但現(xiàn)在我們只有無標簽數(shù)據(jù)蔗衡,也就是右邊的圖纤虽。那么這個誤差怎么得到呢乳绕?

如上圖,我們將input輸入一個encoder編碼器廓推,就會得到一個code刷袍,這個code也就是輸入的一個表示,那么我們怎么知道這個code表示的就是input呢樊展?我們加一個decoder解碼器,這時候decoder就會輸出一個信息堆生,那么如果輸出的這個信息和一開始的輸入信號input是很像的(理想情況下就是一樣的)专缠,那很明顯,我們就有理由相信這個code是靠譜的淑仆。所以涝婉,我們就通過調(diào)整encoder和decoder的參數(shù),使得重構(gòu)誤差最小蔗怠,這時候我們就得到了輸入input信號的第一個表示了墩弯,也就是編碼code了。因為是無標簽數(shù)據(jù)寞射,所以誤差的來源就是直接重構(gòu)后與原輸入相比得到渔工。


2.2 通過編碼器產(chǎn)生特征,然后訓練下一層桥温。

這樣逐層訓練:那上面我們就得到第一層的code引矩,我們的重構(gòu)誤差最小讓我們相信這個code就是原輸入信號的良好表達了,或者牽強點說侵浸,它和原信號是一模一樣的(表達不一樣旺韭,反映的是一個東西)。那第二層和第一層的訓練方式就沒有差別了掏觉,我們將第一層輸出的code當成第二層的輸入信號区端,同樣最小化重構(gòu)誤差,就會得到第二層的參數(shù)澳腹,并且得到第二層輸入的code织盼,也就是原輸入信息的第二個表達了。其他層就同樣的方法炮制就行了(訓練這一層遵湖,前面層的參數(shù)都是固定的悔政,并且他們的decoder已經(jīng)沒用了,都不需要了)延旧。


2.3 有監(jiān)督微調(diào)

經(jīng)過上面的方法谋国,我們就可以得到很多層了。至于需要多少層(或者深度需要多少迁沫,這個目前本身就沒有一個科學的評價方法)需要自己試驗調(diào)了芦瘾。每一層都會得到原始輸入的不同的表達捌蚊。當然了,我們覺得它是越抽象越好了近弟,就像人的視覺系統(tǒng)一樣缅糟。

到這里,這個AutoEncoder還不能用來分類數(shù)據(jù)祷愉,因為它還沒有學習如何去連結(jié)一個輸入和一個類窗宦。它只是學會了如何去重構(gòu)或者復現(xiàn)它的輸入而已《或者說赴涵,它只是學習獲得了一個可以良好代表輸入的特征,這個特征可以最大程度上代表原輸入信號订讼。那么髓窜,為了實現(xiàn)分類,我們就可以在AutoEncoder的最頂?shù)木幋a層添加一個分類器(例如羅杰斯特回歸欺殿、SVM等)寄纵,然后通過標準的多層神經(jīng)網(wǎng)絡(luò)的監(jiān)督訓練方法(梯度下降法)去訓練。

也就是說脖苏,這時候程拭,我們需要將最后層的特征code輸入到最后的分類器,通過有標簽樣本帆阳,通過監(jiān)督學習進行微調(diào)哺壶,這也分兩種:

一種是只調(diào)整分類器(黑色部分)


另一種:通過有標簽樣本,微調(diào)整個系統(tǒng)
(如果有足夠多的數(shù)據(jù)蜒谤,這個是最好的山宾。end-to-end learning端對端學習)

一旦監(jiān)督訓練完成,這個網(wǎng)絡(luò)就可以用來分類了鳍徽。神經(jīng)網(wǎng)絡(luò)的最頂層可以作為一個線性分類器资锰,然后我們可以用一個更好性能的分類器去取代它。

在研究中可以發(fā)現(xiàn)阶祭,如果在原有的特征中加入這些自動學習得到的特征可以大大提高精確度绷杜,甚至在分類問題中比目前最好的分類算法效果還要好!

3 分類

3.1 稀疏編碼器

3.1.1 Sparse AutoEncoder稀疏自動編碼器

當然濒募,我們還可以繼續(xù)加上一些約束條件得到新的Deep Learning方法鞭盟,如:如果在AutoEncoder的基礎(chǔ)上加上L1的Regularity限制(L1主要是約束每一層中的節(jié)點中大部分都要為0,只有少數(shù)不為0瑰剃,這就是Sparse名字的來源)齿诉,我們就可以得到Sparse AutoEncoder法。


如上圖,其實就是限制每次得到的表達code盡量稀疏粤剧。因為稀疏的表達往往比其他的表達要有效(人腦好像也是這樣的歇竟,某個輸入只是刺激某些神經(jīng)元决左,其他的大部分的神經(jīng)元是受到抑制的)秃流。
Sparse autoencoder的一個網(wǎng)絡(luò)結(jié)構(gòu)圖如下所示:


3.1.2 損失函數(shù)的求法

無稀疏約束時網(wǎng)絡(luò)的損失函數(shù)表達式如下:


稀疏編碼是對網(wǎng)絡(luò)的隱含層的輸出有了約束,即隱含層節(jié)點輸出的平均值應(yīng)盡量為0疮绷,這樣的話弧关,大部分的隱含層節(jié)點都處于非activite狀態(tài)盅安。因此,此時的sparse autoencoder損失函數(shù)表達式為:



后面那項為KL距離世囊,其表達式如下:

  

隱含層節(jié)點輸出平均值求法如下:
  

其中的參數(shù)一般取很小宽堆,比如說0.05,也就是小概率發(fā)生事件的概率茸习。這說明要求隱含層的每一個節(jié)點的輸出均值接近0.05(其實就是接近0,因為網(wǎng)絡(luò)中activite函數(shù)為sigmoid函數(shù))壁肋,這樣就達到稀疏的目的了号胚。KL距離在這里表示的是兩個向量之間的差異值。從約束函數(shù)表達式中可以看出浸遗,差異越大則”懲罰越大”猫胁,因此最終的隱含層節(jié)點的輸出會接近0.05。

3.1.3 損失函數(shù)的偏導數(shù)的求解

如果不加入稀疏規(guī)則跛锌,則正常情況下由損失函數(shù)求損失函數(shù)偏導數(shù)的過程如下:



而加入了稀疏性后弃秆,神經(jīng)元節(jié)點的誤差表達式由公式:



變成公式:

3.1.4 梯度下降法求解

有了損失函數(shù)及其偏導數(shù)后就可以采用梯度下降法來求網(wǎng)絡(luò)最優(yōu)化的參數(shù)了,整個流程如下所示:

  

  從上面的公式可以看出髓帽,損失函數(shù)的偏導其實是個累加過程菠赚,每來一個樣本數(shù)據(jù)就累加一次。這是因為損失函數(shù)本身就是由每個訓練樣本的損失疊加而成的郑藏,而按照加法的求導法則衡查,損失函數(shù)的偏導也應(yīng)該是由各個訓練樣本所損失的偏導疊加而成。從這里可以看出必盖,訓練樣本輸入網(wǎng)絡(luò)的順序并不重要拌牲,因為每個訓練樣本所進行的操作是等價的,后面樣本的輸入所產(chǎn)生的結(jié)果并不依靠前一次輸入結(jié)果(只是簡單的累加而已歌粥,而這里的累加是順序無關(guān)的)塌忽。

3.2 降噪編碼器

當采用無監(jiān)督的方法分層預訓練深度網(wǎng)絡(luò)的權(quán)值時,為了學習到較魯棒的特征失驶,可以在網(wǎng)絡(luò)的可視層(即數(shù)據(jù)的輸入層)引入隨機噪聲土居,這種方法稱為Denoise Autoencoder(簡稱dAE),由Bengio在08年提出,見其文章Extracting and composing robust features with denoising autoencoders.使用dAE時装盯,可以用被破壞的輸入數(shù)據(jù)重構(gòu)出原始的數(shù)據(jù)(指沒被破壞的數(shù)據(jù))坷虑,所以它訓練出來的特征會更魯棒。本篇博文主要是根據(jù)Benigio的那篇文章簡單介紹下dAE埂奈,然后通過2個簡單的實驗來說明實際編程中該怎樣應(yīng)用dAE迄损。這2個實驗都是網(wǎng)絡(luò)上現(xiàn)成的工具稍加改變而成,其中一個就是matlab的Deep Learning toolbox账磺,見https://github.com/rasmusbergpalm/DeepLearnToolbox芹敌,另一個是與python相關(guān)的theano,參考:http://deeplearning.net/tutorial/dA.html.

基礎(chǔ)知識:
首先來看看Bengio論文中關(guān)于dAE的示意圖垮抗,如下:


由上圖可知氏捞,樣本x按照qD分布加入隨機噪聲后變?yōu)?,按照文章的意思,這里并不是加入高斯噪聲冒版,而是以一定概率使輸入層節(jié)點的值清為0液茎,這點與上篇博文介紹的dropout(Deep learning****:四十一(Dropout****簡單理解))很類似,只不過dropout作用在隱含層辞嗡。此時輸入到可視層的數(shù)據(jù)變?yōu)槔Φ龋[含層輸出為y,然后由y重構(gòu)x的輸出z续室,注意此時這里不是重構(gòu) 栋烤,而是x.
Bengio對dAE的直觀解釋為:

  1. dAE有點類似人體的感官系統(tǒng),比如人眼看物體時挺狰,如果物體某一小部分被遮住了明郭,人依然能夠?qū)⑵渥R別出來
  2. 多模態(tài)信息輸入人體時(比如聲音,圖像等)丰泊,少了其中某些模態(tài)的信息有時影響也不大薯定。
  3. 普通的autoencoder的本質(zhì)是學習一個相等函數(shù),即輸入和重構(gòu)后的輸出相等趁耗,這種相等函數(shù)的表示有個缺點就是當測試樣本和訓練樣本不符合同一分布沉唠,即相差較大時,效果不好苛败,明顯满葛,dAE在這方面的處理有所進步。

當然作者也從數(shù)學上給出了一定的解釋罢屈。

  1. 流形學習的觀點嘀韧。一般情況下,高維的數(shù)據(jù)都處于一個較低維的流形曲面上缠捌,而使用dAE得到的特征就基本處于這個曲面上锄贷,如下圖所示译蒂。而普通的autoencoder,即使是加入了稀疏約束谊却,其提取出的特征也不是都在這個低維曲面上(雖然這樣也能提取出原始數(shù)據(jù)的主要信息)柔昼。

      
  2. 自頂向下的生成模型觀點的解釋。
  3. 信息論觀點的解釋炎辨。
  4. 隨機法觀點的解釋捕透。

這幾個觀點的解釋數(shù)學有一部分數(shù)學公式,大家具體去仔細看他的paper碴萧。

當在訓練深度網(wǎng)絡(luò)時乙嘀,且采用了無監(jiān)督方法預訓練權(quán)值,通常破喻,Dropout和Denoise Autoencoder在使用時有一個小地方不同:Dropout在分層預訓練權(quán)值的過程中是不參與的虎谢,只是后面的微調(diào)部分引入;而Denoise Autoencoder是在每層預訓練的過程中作為輸入層被引入曹质,在進行微調(diào)時不參與婴噩。另外,一般的重構(gòu)誤差可以采用均方誤差的形式羽德,但是如果輸入和輸出的向量元素都是位變量讳推,則一般采用交叉熵來表示兩者的差異。

3.3 收縮自動編碼器

Contractive autoencoder是autoencoder的一個變種玩般,其實就是在autoencoder上加入了一個規(guī)則項,它簡稱CAE(對應(yīng)中文翻譯為礼饱?)坏为。通常情況下,對權(quán)值進行懲罰后的autoencoder數(shù)學表達形式為:

  

這是直接對W的值進行懲罰的镊绪,而今天要講的CAE其數(shù)學表達式同樣非常簡單匀伏,如下:

  

其中的


是隱含層輸出值關(guān)于權(quán)重的雅克比矩陣,而

表示的是該雅克比矩陣的F范數(shù)的平方蝴韭,即雅克比矩陣中每個元素求平方

然后求和够颠,更具體的數(shù)學表達式為:

關(guān)于雅克比矩陣的介紹可參考雅克比矩陣&行列式——單純的矩陣和算子,關(guān)于F范數(shù)可參考我前面的博文Sparse coding中關(guān)于矩陣的范數(shù)求導中的內(nèi)容榄鉴。

有了loss函數(shù)的表達式履磨,采用常見的mini-batch隨機梯度下降法訓練即可。

關(guān)于為什么contrative autoencoder效果這么好庆尘?paper中作者解釋了好幾頁剃诅,好吧,我真沒完全明白驶忌,希望懂的朋友能簡單通俗的介紹下矛辕。下面是讀完文章中的一些理解:

好的特征表示大致有2個衡量標準:

  1. 可以很好的重構(gòu)出輸入數(shù)據(jù);
  2. 對輸入數(shù)據(jù)一定程度下的擾動具有不變形。

普通的autoencoder和sparse autoencoder主要是符合第一個標準。而deniose autoencoder和contractive autoencoder則主要體現(xiàn)在第二個聊品。而作為分類任務(wù)來說飞蹂,第二個標準顯得更重要。

雅克比矩陣包含數(shù)據(jù)在各種方向上的信息翻屈,可以對雅克比矩陣進行奇異值分解陈哑,同時畫出奇異值數(shù)目和奇異值的曲線圖,大的奇異值對應(yīng)著學習到的局部方向可允許的變化量妖胀,并且曲線越抖越好(這個圖沒看明白芥颈,所以這里的解釋基本上是直接翻譯原文中某些觀點)。

另一個曲線圖是contractive ratio圖赚抡,contractive ratio定義為:原空間中2個樣本直接的距離比上特征空間(指映射后的空間)中對應(yīng)2個樣本點之間的距離爬坑。某個點x處局部映射的contraction值是指該點處雅克比矩陣的F范數(shù)。按照作者的觀點涂臣,contractive ration曲線呈上升趨勢的話更好(why盾计?),而CAE剛好符合赁遗。

總之Contractive autoencoder主要是抑制訓練樣本(處在低維流形曲面上)在所有方向上的擾動署辉。

3.4 棧式自動編碼器

單自動編碼器,充其量也就是個強化補丁版PCA岩四,只用一次好不過癮哭尝。
于是Bengio等人在2007年的 **Greedy Layer-Wise Training of Deep Networks **中,
仿照stacked RBM構(gòu)成的DBN剖煌,提出Stacked AutoEncoder材鹦,為非監(jiān)督學習在深度網(wǎng)絡(luò)的應(yīng)用又添了猛將。
這里就不得不提 “逐層初始化”(Layer-wise Pre-training)耕姊,目的是通過逐層非監(jiān)督學習的預訓練桶唐,
來初始化深度網(wǎng)絡(luò)的參數(shù),替代傳統(tǒng)的隨機小值方法茉兰。預訓練完畢后尤泽,利用訓練參數(shù),再進行監(jiān)督學習訓練规脸。

3.4.1 原理


非監(jiān)督學習網(wǎng)絡(luò)訓練方式和監(jiān)督學習網(wǎng)絡(luò)的方式是相反的坯约。

在監(jiān)督學習網(wǎng)絡(luò)當中,各個Layer的參數(shù)W受制于輸出層的誤差函數(shù)莫鸭,因而Layer(i) 參數(shù)的梯度依賴于Layer(i+1)的梯度鬼店,形成了"一次迭代-更新全網(wǎng)絡(luò)"反向傳播。

但是在非監(jiān)督學習中黔龟,各個Encoder的參數(shù)W只受制于當前層的輸入妇智,因而可以訓練完Encoder(i)滥玷,把參數(shù)轉(zhuǎn)給Layer(i),利用優(yōu)勢參數(shù)傳播到Layer(i+1)巍棱,再開始訓練惑畴。形成"全部迭代-更新單層"的新訓練方式。這樣航徙,Layer(i+1) 效益非常高如贷,因為它吸收的是Layer(i)完全訓練奉獻出的精華Input。

3.4.2 代碼與實現(xiàn)

主要參考 http://deeplearning.net/tutorial/SdA.html
棧式機在構(gòu)造函數(shù)中到踏,構(gòu)造出各個Layer杠袱、Encoder,并且存起來窝稿。
Theano在構(gòu)建棧式機中楣富,易錯點是Encoder、Layer的參數(shù)轉(zhuǎn)移伴榔。
我們知道纹蝴,Python的列表有深淺拷貝一說。Theano所有被shared標記的變量都是淺拷貝踪少。

因而首先有這樣的錯誤寫法:

def __init__(self,rng,input,n_in,n_out,layerSize): 
  for i in xrange(len(layerSize)):
    da.W=hidenlayer.W
    da.bout=hidenlayer.b

然后你在外部為da做grad求梯度的時候就報錯了塘安,提示說params和cost函數(shù)不符合。

這是因為cost函數(shù)的Tensor表達式在寫cost函數(shù)時就確定了援奢,這時候da這個對象剛好構(gòu)造完兼犯,因而Tensor表達式中的da.W是構(gòu)造隨機值。

然后我們在da構(gòu)造完了之后集漾,手賤把da.W指向的內(nèi)存改變了(淺拷貝相當于引用)免都,這樣算出的grad根本就不對。

其實這樣寫反了帆竹,又改成了這樣

def __init__(self,rng,input,n_in,n_out,layerSize):
  for i in xrange(len(layerSize)):
    hidenlayer.W=da.W 
    hidenlayer.b=da.bout

好吧,這樣不會報錯了脓规,而且每訓練一個Encoder栽连,用get_value查看Layer的值確實改變了。但是侨舆,訓練Encoder(i+1)的時候秒紧,怎么感覺沒效果?

其實是真的沒效果挨下,因為Layer(i)的參數(shù)根本沒有傳播到Laye(ri+1)去熔恢。

Theano采用Python、C雙內(nèi)存區(qū)設(shè)計臭笆,在C代碼中訓練完Encoder(i)時叙淌,參數(shù)并沒有轉(zhuǎn)到Layer(i)中秤掌。但是我們明明建立了淺拷貝啊鹰霍?

原來updates函數(shù)在C內(nèi)存區(qū)中闻鉴,根本沒有覺察到淺拷貝關(guān)系,因為它在Python內(nèi)存區(qū)中茂洒。

正確做法是像教程這樣孟岛,在da構(gòu)造時建立淺拷貝關(guān)系,當編譯成C代碼之后督勺,所有Python對象要在C內(nèi)存區(qū)重新構(gòu)造渠羞,自然就在C內(nèi)存區(qū)觸發(fā)了淺拷貝。

da=dA(rng,layerInput,InputSize,self.layerSize[i],hidenlayer.W,hidenlayer.b)

或者訓練完Encoder(i)智哀,強制把Encoder(i)參數(shù)注入到C內(nèi)存區(qū)的Layer(i)里次询。

updateModel=function(inputs=[],outputs=[],updates=[(....)],updateModel()

Theano的寫法風格近似于函數(shù)式語言盏触,對象渗蟹、函數(shù)中全是數(shù)學模型。一旦構(gòu)造完了之后赞辩,就無法顯式賦值雌芽。

所以,在Python非構(gòu)造函數(shù)里為對象賦值是愚蠢的辨嗽,效果僅限于Python內(nèi)存區(qū)世落。但是大部分計算都在C內(nèi)存區(qū),所以需要updates手動把值打進C內(nèi)存區(qū)糟需。

updates是溝通兩區(qū)的橋梁屉佳,一旦發(fā)現(xiàn)Python內(nèi)存區(qū)中有建立淺拷貝關(guān)系,就會把C內(nèi)存區(qū)中值更新到Python內(nèi)存區(qū)洲押。(有利于Python中保存參數(shù))

但是絕對不會自動把Python內(nèi)存區(qū)值武花,更新到C內(nèi)存區(qū)當中。(這點必須小心)
這種做法可以擴展到杈帐,監(jiān)督訓練完之后体箕,參數(shù)的保存與導入。

3.5 變分自動編碼器

3.5.1 神秘變量與數(shù)據(jù)集

現(xiàn)在有一個數(shù)據(jù)集DX(dataset, 也可以叫datapoints)挑童,每個數(shù)據(jù)也稱為數(shù)據(jù)點累铅。X是一個實際的樣本集合,我們假定這個樣本受某種神秘力量操控站叼,但是我們也無從知道這些神秘力量是什么娃兽?那么我們假定這股神秘力量有n個,起名字叫power1,power2,…,powern吧尽楔,他們的大小分別是z1,z2,…,zn投储,稱之為神秘變量表示成一個向量就是
z=??????z1z2?zn??????
z也起個名字叫神秘組合第练。
一言以蔽之:神秘變量代表了神秘力量神秘組合關(guān)系。用正經(jīng)的話說就是:隱變量(latent variable)代表了隱因子(latent factor)的組合關(guān)系轻要。
這里我們澄清一下隸屬空間复旬,假設(shè)數(shù)據(jù)集DX是m個點,這m個點也應(yīng)該隸屬于一個空間冲泥,比如一維的情況驹碍,假如每個點是一個實數(shù),那么他的隸屬空間就是實數(shù)集凡恍,所以我們這里定義一個DX每個點都屬于的空間稱為XS志秃,我們在后面提到的時候,你就不再感到陌生了嚼酝。
神秘變量z可以肯定他們也有一個歸屬空間稱為ZS浮还。
下面我們就要形式化地構(gòu)造X與Z的神秘關(guān)系了,這個關(guān)系就是我們前面說的神秘力量闽巩,直觀上我們已經(jīng)非常清楚钧舌,假設(shè)我們的數(shù)據(jù)集就是完全由這n個神秘變量全權(quán)操控的,那么對于X中每一個點都應(yīng)該有一個n個神秘變量的神秘組合zj來神秘決定涎跨。
接下來我們要將這個關(guān)系再簡化一下洼冻,我們假設(shè)這n個神秘變量不是能夠操控X的全部,還有一些其他的神秘力量隅很,我們暫時不考慮撞牢,那么就可以用概率來彌補這個缺失,為什么呢叔营?舉個例子屋彪,假設(shè)我們制造了一個機器可以向一個固定的目標發(fā)射子彈,我們精確的計算好了打擊的力量和角度绒尊,但由于某些難以控制的因素畜挥,比如空氣的流動,地球的轉(zhuǎn)動導致命中的目標無法達到精準的目的婴谱,而這些因素可能十分巨大和繁多蟹但,但是他們并不是形成DX的主因素,根據(jù)大數(shù)定理勘究,這些所有因素產(chǎn)生的影響可以用高斯分布的概率密度函數(shù)來表示。它長這樣:p(x|μ,σ2)=12π√σe?12(x?μσ)2
當μ=0時斟冕,就變成了這樣:p(x|σ2)=12π√σe?x22σ2這是一維高斯分布的公式口糕,那么多維的呢?比較復雜磕蛇,推導過程見知乎景描,長這樣:
不管怎樣十办,你只要記住我們現(xiàn)在沒有能力關(guān)注全部的神秘變量,我們只關(guān)心若干個可能重要的因素超棺,這些因素的分布狀況可以有各種假設(shè)向族,我們回頭再討論他們的概率分布問題,我們現(xiàn)在假定我們對他們的具體分布情況也是一無所知棠绘,我們只是知道他們處于ZS空間內(nèi)件相。前面說到了一個神秘組合,如果一個數(shù)據(jù)集X對應(yīng)的神秘組合完全一樣氧苍,那么這個數(shù)據(jù)集就是一個單一的分類數(shù)據(jù)集夜矗,如果是多個,那么就是多分類數(shù)據(jù)集让虐,但如果是一個連續(xù)的組合數(shù)據(jù)紊撕,那么就是一個有點分不清界限的復雜數(shù)據(jù)集,就好比赡突,我們這個數(shù)據(jù)集是一條線段的集合对扶,線段的長度是唯一的神秘變量,那么只要長度在一個范圍內(nèi)連續(xù)變化惭缰,那么這個集合里的線段你就會發(fā)現(xiàn)分散的很均勻浪南,你幾乎沒有辦法區(qū)分開他們,也沒法給他們分成幾類从媚,但如果這個長度值只能選擇1,3,5逞泄,那么當你觀察這個數(shù)據(jù)集的時候,你會發(fā)現(xiàn)他們會聚在三堆兒里拜效。如果這個線段的生成完全依靠的是計算機喷众,那么每一堆兒都是完全重合的,但如果是人畫的紧憾,就可能因為誤差到千,沒法完全重合,這沒法重合的部分就是我們說的其他復雜因素赴穗,我們通常用一個高斯分布來把它代表了憔四。好,我們已經(jīng)基本清晰了般眉,我們該給這個神秘組合一個形式化的描述了了赵。假設(shè)有兩個變量,z∈ZS 和 x∈XS甸赃,存在一個確定性函數(shù)族f(z;θ)柿汛,族中的每個函數(shù)由θ∈Θ唯一確定,f:ZS×Θ→XS埠对,當θ固定络断,z是一個隨機變量(概率密度函數(shù)為Pz(z))時裁替,那么f(z;θ)就是定義在XS上的隨機變量x,對應(yīng)的概率密度函數(shù)可以寫成g(x)貌笨。那么我們的目標就是優(yōu)化θ從而尋找到一個f弱判,能夠是隨機變量x的采樣和X非常的像。這里需要注意一下锥惋,x是一個變量,DX是已經(jīng)現(xiàn)成的數(shù)據(jù)集昌腰,x不屬于DX,我特意將名字起的有區(qū)分度净刮。這樣剥哑,f就是那個神秘力量通道,他把這些神秘力量的力度淹父,通過f變成了x變量株婴,而這個x變量就是與數(shù)據(jù)集DX具有直接關(guān)系的隨機變量。
設(shè)一個數(shù)據(jù)集為DX暑认,那么這個數(shù)據(jù)集存在的概率為Pt(DX)困介,則根據(jù)貝葉斯公式有:
Pt(DX)=∫Pxz(DX|z;θ)Pz(z)dz; (1)
其中,Pxz(DX|z;θ)是我們新定義的概率密度函數(shù)蘸际,我們前面知道f是將z映射成x座哩,而x又與DX有某種直接的關(guān)系,這個直接關(guān)系可以表示成Px(DX|x)粮彤,那么Pt(DX)=∫Px(DX|x)g(x)dx
這樣我們就直接定義個Pxz(DX|z;θ) 來替換Px(DX|x)g(x)根穷,從而表示z與DX的關(guān)系了。
好了导坟,其實公式(1)就是我們的神秘力量與觀察到的數(shù)據(jù)集之間的神秘關(guān)系屿良,這個關(guān)系的意思我們直白的說就是:當隱秘變量按照某種規(guī)律存在時,就非常容易產(chǎn)生現(xiàn)在我們看到的這個數(shù)據(jù)集惫周。那么尘惧,我們要做的工作就是當我們假定有n個神秘力量時,我們能夠找到一個神奇的函數(shù)f递递,將神秘力量的變化轉(zhuǎn)化成神奇的x的變化喷橙,這個x能夠輕而易舉地生成數(shù)據(jù)集DX。從上面的描述里面我們看到登舞,f是生成轉(zhuǎn)換函數(shù)贰逾,公式(1)不表示這種轉(zhuǎn)換關(guān)系,而是這種關(guān)系的最大似然估計(maximum likelihood)菠秒,它的意思是找到最有可能生成DX這個數(shù)據(jù)集的主導函數(shù)f疙剑。
接下來我們回到討論Pxz(DX|z;θ)這個概率密度函數(shù)上來,我們前面說過,如果z是全部的神秘力量核芽,那么它產(chǎn)生的變量x就一定固定的,即當z取值固定時酵熙,x取值固定轧简,但是現(xiàn)實中還有很多其他的因素,因而x的取值還與他們有關(guān)匾二,他們的影響力哮独,最終反映成了高斯函數(shù),所以我們大膽假定Pxz是一個高斯分布的概率密度函數(shù)察藐,即Pxz(DX|z;θ)=N(DX|f(x;θ),σ2?I)
注意z的分布我們依然是未知的皮璧。
假定我們知道z現(xiàn)在取某一個或幾個特定值,那么我們就可以通過Gradient Descent來找到一個θ盡量滿足z能夠以極高的概率生成我們希望的數(shù)據(jù)集DX分飞。再一推廣悴务,就變成了,z取值某一范圍譬猫,但去幾個特定值或某一取值范圍是就面臨z各種取值的概率問題讯檐,我們回頭再討論這個棘手的問題,你現(xiàn)在只要知道冥冥之中染服,我們似乎可以通過學習參數(shù)θ尋找最優(yōu)解就行了别洪。
OK,我們還要說一個關(guān)鍵問題柳刮,就是我們確信f是存在的挖垛,我們認為變量與神秘變量之間的關(guān)系一定可以用一個函數(shù)來表示。

3.5.2 變分自編碼器(VAE)

本節(jié)秉颗,我們探討如何最大化公式(1)痢毒。首先,我們要討論怎樣確定神秘變量z站宗,即z應(yīng)該有幾個維度闸准,每個維度的作用域是什么?更為較真的梢灭,我們可能甚至要追究每一維度都代表什么夷家?他們之間是不是獨立的?每個維度的概率分布是什么樣的敏释?
如果我們沿著這個思路進行下去库快,就會陷入泥潭,我們可以巧妙地避開這些問題钥顽,關(guān)鍵就在于讓他們繼續(xù)保持“神秘”义屏!
我們不關(guān)心每一個維度代表什么含義,我們只假定存在這么一群相互獨立的變量,維度我們也回到之前的討論闽铐,我們雖然不知道有多少蝶怔,我們可以假定有n個主要因素,n可以定的大一點兄墅,比如假設(shè)有4個主因素踢星,而我們假定有10個,那么最后訓練出來隙咸,可能有6個長期是0沐悦。最后的問題需要詳細討論一下抱婉,比較復雜占哟,就是z的概率分布和取值問題蕾各。
既然z是什么都不知道栏渺,我們是不是可以尋找一組新的神秘變量w惦界,讓這個w服從標準正態(tài)分布N(0,I)倾芝。I是單位矩陣论衍,然后這個w可以通過n個復雜函數(shù)堰燎,轉(zhuǎn)換成z呢基矮?有了神經(jīng)網(wǎng)絡(luò)這些也是可行的继薛,假設(shè)這些復雜函數(shù)分別是h1,h2,…,hn,那么有z1=h1(w1),…,zn=hn(wn)愈捅。而z的具體分布是什么遏考,取值范圍是多少我們也不用關(guān)心了,反正由一個神經(jīng)網(wǎng)絡(luò)去算蓝谨」嗑撸回想一下P(DX|z;θ)=N(DX|f(z;θ),σ2×I),我們可以想象譬巫,如果f(z;θ)是一個多層神經(jīng)網(wǎng)絡(luò)咖楣,那么前幾層就用來將標準正態(tài)分布的w變成真正的隱變量z,后面幾層才是將z映射成x芦昔,但由于w和z是一一對應(yīng)關(guān)系诱贿,所以w某種意義上說也是一股神秘力量。就演化成w和x的關(guān)系了咕缎,既然w也是神秘變量珠十,我們就還是叫回z,把那個之前我們認為的神秘變量z忘掉吧凭豪。
好焙蹭,更加波瀾壯闊的歷程要開始了,請坐好嫂伞。
我們現(xiàn)在已經(jīng)有了
Pz(z)=N(0,I),
Pxz(DX|z;θ)=N(DX|f(x;θ),σ2?I),
Pt(DX)=∫Pxz(DX|z;θ)Pz(z)dz,
我們現(xiàn)在就可以專心攻擊f了孔厉,由于f是一個神經(jīng)網(wǎng)絡(luò)拯钻,我們就可以梯度下降了。但是另一個關(guān)鍵點在于我們怎么知道這個f生成的樣本撰豺,和DX更加像呢粪般?如果這個問題解決不了,我們根本都不知道我們的目標函數(shù)是什么污桦。

3.5.3 設(shè)定目標函數(shù)

我們先來定義個函數(shù) Q(z|DX)刊驴,數(shù)據(jù)集DX的發(fā)生,z的概率密度函數(shù)寡润,即如果DX發(fā)生,Q(z|DX)就是z的概率密度函數(shù)舅柜,比如一個數(shù)字圖像0梭纹,z隱式代表0的概率就很大,而那些代表1的概率就很小致份。如果我們有辦法搞到這個Q的函數(shù)表示变抽,我們就可以直接使用DX算出z的最佳值了。為什么會引入Q呢氮块?其實道理很簡單绍载,如果DX是x這個變量直接生成的,要想找回x的模型滔蝉,就要引入一個概率密度函數(shù)T(x|DX)击儡,亦即針對DX,我們要找到一個x的最佳概率密度函數(shù)◎鹨現(xiàn)在的問題就變成了阳谍,我們可以根據(jù)DX計算出Q(z|DX)來讓他盡量與理想的Pz(z|DX)盡量的趨同,這就要引入更加高深的功夫了——相對熵螃概,也叫KL散度(Kullback-Leibler divergence,用 D表示)矫夯。
離散概率分布的KL公式
KL(p∥q)=∑p(x)logp(x)q(x)
連續(xù)概率分布的KL公式
KL(p∥q)=∫p(x)logp(x)q(x)dx
Pz(z|DX)和Q(z|DX)的KL散度為
D[Q(z|DX)∥Pz(z|DX)]=∫Q(z|DX)[logQ(z|DX)–logPz(z|DX)]也可寫成D[Q(z|DX)∥Pz(z|DX)]=Ez~Q[logQ(z|DX)–logPz(z|DX)]
通過貝葉斯公式
Pz(z|DX)=P(DX|z)P(z)P(DX)這里不再給P起名,其實Pz(z)直接寫成P(z)也是沒有任何問題的吊洼,前面只是為了區(qū)分概念训貌,括號中的內(nèi)容已經(jīng)足以表意。
D[Q(z|DX)∥Pz(z|DX)]=Ez~Q[logQ(z|DX)–logP(DX|z)–logP(z)]+logP(DX)
因為logP(DX)與z變量無關(guān)冒窍,直接就可以提出來了递沪,進而得到閃閃發(fā)光的公式(2):
logP(DX)–D[Q(z|DX)∥P(z|DX)]=Ez~Q[logP(DX|z)]–D[Q(z|DX)∥P(z)]; (2)
公式(2)是VAE的核心公式,我們接下來分析一個這個公式综液。公式的左邊有我們的優(yōu)化目標P(DX)区拳,同時攜帶了一個誤差項,這個誤差項反映了給定DX的情況下的真實分布Q與理想分布P的相對熵意乓,當Q完全符合理想分布時樱调,這個誤差項就為0约素,而等式右邊就是我們可以使用梯度下降進行優(yōu)化的,這里面的Q(z|DX)特別像一個DX->z的編碼器笆凌,P(DX|z)特別像z->DX的解碼器圣猎,這就是VAE架構(gòu)也被稱為自編碼器的原因。
由于DX早已不再有分歧乞而,我們在這里把所有的DX都換成了X送悔。
我們現(xiàn)在有公式(2)的拆分:– 左側(cè)第一項:logP(X)– 左側(cè)第二項:D(Q(z|X∥P(z|X))– 右邊第一項:Ez~Q[logP(X|z)]– 右邊第二項:D[Q(z|X)∥P(z)]
還有下面這些:– P(z)=N(0,I),– P(X|z)=N(X|f(z),σ2?I),– Q(z|X)=N(z|μ(X),Σ(X))
我們再明確一下每個概率的含義:– P(X)——當前這個數(shù)據(jù)集發(fā)生的概率,但是他的概率分布我們是不知道爪模,比如欠啤,X的空間是一個一維有限空間,比如只能取值0-9的整數(shù)屋灌,而我們的 X = { 0, 1, 2, 3, 4 }洁段,那么當概率分布是均勻的時候,P(X)就是0.5共郭,但是如果不是這個分布祠丝,就不好說是什么了,沒準是0.1, 0.01除嘹,都有可能写半。P(X)是一個函數(shù),就好像是一個人尉咕,當你問他X=某個值的時候叠蝇,他能告訴發(fā)生的概率。– P(z) —— 這個z是我們后來引入的那個w年缎,還記得嗎蟆肆?他們都已經(jīng)歸順了正態(tài)分布,如果z是一維的晦款,那他就是標準正態(tài)分布N(0, I)炎功。– P(X|z) —— 這個函數(shù)的含義是如果z給定一個取值,那么就知道X取某個值的概率缓溅,還是舉個例子蛇损,z是一個神奇的變量,可以控制在計算機屏幕上出現(xiàn)整個屏幕的紅色并且控制其灰度坛怪,z服從N(0,1)分布淤齐,當z=0時代表純正的紅色,z越偏離0袜匿,屏幕的紅色就越深更啄,那么P(X|z)就表示z等于某個值時X=另一值的概率,由于計算機是精確控制的居灯,沒有額外的隨機因素祭务,所以如果z=0能夠?qū)е耎取一個固定色值0xFF0000内狗,那么P(X=0xFF0000|z=0)=1,P(x!=0xFF0000|z=0) = 0义锥,但如果現(xiàn)實世界比較復雜附加其他的隨機因素柳沙,那么就可能在z確定出來的X基礎(chǔ)值之上做隨機了。這就是我們之前討論的拌倍,大數(shù)定理赂鲤,P(X|z)=N(X|f(x),σ2?I)。f(z)就是X與z直接關(guān)系的寫照柱恤。– P(z|X) —— 當X發(fā)生時数初,z的概率是多少呢?回到剛才計算機屏幕的例子梗顺,就非常簡單了P(z=0|X=0xFF0000) = 1, P(z!=0|X=0xFF0000) = 0泡孩,但是由于概率的引入,X|z可以簡化成高斯關(guān)系荚守,相反,也可以簡化高斯關(guān)系练般。這個解釋對下面的Q同樣適用矗漾。– Q(z) —— 對于Q的分析和P的分析是一樣的,只不過Q和P的不同時薄料,我們假定P是那個理想中的分布敞贡,是真正決定X的最終構(gòu)成的背后真實力量,而Q是我們的親兒子摄职,試著弄出來的贗品誊役,并且希望在現(xiàn)實世界通過神經(jīng)網(wǎng)絡(luò),讓這個贗品能夠嘗試控制產(chǎn)生X谷市。當這個Q真的行為和我們理想中的P一模一樣的時候蛔垢,Q就是上等的贗品了,甚至可以打出如假包換的招牌迫悠。我們的P已經(jīng)簡化成N(0,I)鹏漆,就意味著Q只能向N(0, I)靠攏。– Q(z|X) —— 根據(jù)現(xiàn)實中X和Q的關(guān)系推導出的概率函數(shù)创泄, 當X發(fā)生時艺玲,對應(yīng)的z取值的概率分布情況。– Q(X|z) —— 現(xiàn)實中z發(fā)生時鞠抑,取值X的概率饭聚。
我們的目標是優(yōu)化P(X),但是我們不知道他的分布搁拙,所以根本沒法優(yōu)化秒梳,這就是我們沒有任何先驗知識法绵。所以有了公式(2),左邊第二項是P(z|X)和Q(z|X)的相對熵端幼,意味著X發(fā)生時現(xiàn)實的分布應(yīng)該與我們理想的分布趨同才對礼烈,所以整個左邊都是我們的優(yōu)化目標,只要左邊越大就越好婆跑,那么右邊的目標就是越大越好此熬。
右邊第一項:Ez~Q[logP(X|z)]就是針對面對真實的z的分布情況(依賴Q(z|X),由X->z的映射關(guān)系決定)滑进,算出來的X的分布犀忱,類似于根據(jù)z重建X的過程。右邊第二項:D[Q(z|X)∥P(z)] 就是讓根據(jù)X重建的z與真實的z盡量趨近扶关,由于P(z)是明確的N(0, I)阴汇,而Q(z|X)是也是正態(tài)分布,其實就是要讓Q(z|X)趨近與標準正態(tài)分布节槐。
現(xiàn)在我們對這個公式的理解更加深入了搀庶。接下來,我們要進行實現(xiàn)的工作铜异。

3.5.4 實現(xiàn)

針對右邊兩項分別實現(xiàn)第二項是Q(z|X)與N(0, I)的相對熵哥倔,X->z構(gòu)成了編碼器部分。Q(z|x)是正態(tài)分布揍庄,兩個正態(tài)分布的KL計算公式如下(太復雜了咆蒿,我也推不出來,感興趣的看[1]):
KL(N(μ,Σ)∥N(0,I))=12[?log[det(Σ)]?d+tr(Σ)+μTμ]
det是行列式蚂子,tr是算矩陣的秩沃测,d是I的秩即d=tr(I)。
變成具體的神經(jīng)網(wǎng)絡(luò)和矩陣運算食茎,還需要進一步變化該式:
KL(N(μ,Σ)∥N(0,I))=12∑i[?log(Σi)+Σi+μ2i–1]OK蒂破,這個KL我們也會計算了,還有一個事情就是編碼器網(wǎng)絡(luò)别渔,μ(X)和Σ(X)都使用神經(jīng)網(wǎng)絡(luò)來編碼就可以了寞蚌。
第一項是Ez~Q[logP(X|z)]代表依賴z重建出來的數(shù)據(jù)與X盡量地相同,z->X重建X構(gòu)成了解碼器部分钠糊,整個重建的關(guān)鍵就是f函數(shù)挟秤,對我們來說就是建立一個解碼器神經(jīng)網(wǎng)絡(luò)。
到此抄伍,整個實現(xiàn)的細節(jié)就全都展現(xiàn)在下面這張圖里了

由于這個網(wǎng)絡(luò)傳遞結(jié)構(gòu)的一個環(huán)節(jié)是隨機采樣艘刚,導致無法反向傳播,所以聰明的前輩又將這個結(jié)構(gòu)優(yōu)化成了這樣:

這樣就可以對整個網(wǎng)絡(luò)進行反向傳播訓練了截珍。
具體的實現(xiàn)代碼攀甚,我實現(xiàn)在了這里:
https://github.com/vaxin/TensorFlow-Examples/blob/master/examples/3_NeuralNetworks/variational_autoencoder.py
里面的每一步箩朴,都有配合本文章的對照解釋。

3.5.5 延伸思考

之所以關(guān)注VAE秋度,是從文獻[4]引發(fā)的炸庞,由于視覺早期的概念形成對于之后的視覺認知起了十分關(guān)鍵的作用,我們有理由相信荚斯,在神經(jīng)網(wǎng)絡(luò)訓練時埠居,利用這種遞進關(guān)系,先構(gòu)建具有基礎(chǔ)認知能力的神經(jīng)網(wǎng)絡(luò)事期,再做高級認知任務(wù)時會有極大的效果提升滥壕。但通過前面神秘變量的分析,我們發(fā)現(xiàn)兽泣,為了充分利用高斯分布绎橘,我們將w替換成了z,也就是說真正的隱變量隱藏在f的神經(jīng)網(wǎng)絡(luò)里面唠倦,而現(xiàn)在的z反而容易變成說不清楚的東西称鳞,這一不利于后續(xù)的時候,二來我們需要思考稠鼻,是否應(yīng)該還原真實的z冈止,從而在層次化遞進上有更大的發(fā)揮空間。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末枷餐,一起剝皮案震驚了整個濱河市靶瘸,隨后出現(xiàn)的幾起案子苫亦,更是在濱河造成了極大的恐慌毛肋,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件屋剑,死亡現(xiàn)場離奇詭異润匙,居然都是意外死亡,警方通過查閱死者的電腦和手機唉匾,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進店門孕讳,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人巍膘,你說我怎么就攤上這事厂财。” “怎么了峡懈?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵璃饱,是天一觀的道長。 經(jīng)常有香客問我肪康,道長荚恶,這世上最難降的妖魔是什么撩穿? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮谒撼,結(jié)果婚禮上食寡,老公的妹妹穿的比我還像新娘。我一直安慰自己廓潜,他們只是感情好抵皱,可當我...
    茶點故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著茉帅,像睡著了一般叨叙。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上堪澎,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天擂错,我揣著相機與錄音,去河邊找鬼樱蛤。 笑死钮呀,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的昨凡。 我是一名探鬼主播爽醋,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼便脊!你這毒婦竟也來了蚂四?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤哪痰,失蹤者是張志新(化名)和其女友劉穎遂赠,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體晌杰,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡跷睦,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了肋演。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片抑诸。...
    茶點故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖爹殊,靈堂內(nèi)的尸體忽然破棺而出蜕乡,到底是詐尸還是另有隱情,我是刑警寧澤梗夸,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布层玲,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏称簿。R本人自食惡果不足惜扣癣,卻給世界環(huán)境...
    茶點故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望憨降。 院中可真熱鬧父虑,春花似錦、人聲如沸授药。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽悔叽。三九已至莱衩,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間娇澎,已是汗流浹背笨蚁。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留趟庄,地道東北人括细。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像戚啥,于是被迫代替她去往敵國和親奋单。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,792評論 2 345

推薦閱讀更多精彩內(nèi)容