VAE粗略理解

AE

自編碼是一種表示學習的技術,是deep learning的核心問題

讓輸入等於輸出,取中間的一層作爲embedding, 即編碼

對中間的隱層進行約束,就可以得到不同類型的編碼

h<x,這就是普通的降維編碼

h>x, 並且約束其稀疏性,就得到稀疏編碼

自編碼網絡,可以理解爲,

https://images2018.cnblogs.com/blog/312753/201805/312753-20180523175436599-2072640413.png

完成訓練後,Decoder部分就沒有用了

 

SAE

堆疊自編碼器

 

 

各種自編碼的變形

 

VAE的差別

和普通autoencoding比,

VAE的Encoder會輸出兩個向量,你可以把其中一個看成mean,另一個看成variance,還加入一個誤差error,這個error是從一個高斯分佈sample出來的(額外的loss,原文中KL散度計算正態與標準正態)

最終把這3個向量合成成code(variance要乘上一個noise,這個噪聲來模擬取樣,然後加在mean上)

 

https://images2018.cnblogs.com/blog/312753/201807/312753-20180702144331156-417780954.png

 

 

VAE漫談

變分自編碼器

分佈變換

通常我們會拿 VAE 跟 GAN 比較,的確,它們兩個的目標基本是一致的——希望構建一個從隱變量 Z 生成目標數據 X 的模型,但是實現上有所不同。

更準確地講,它們是假設了服從某些常見的分佈(比如正態分佈或均勻分佈),然後希望訓練一個模型 X=g(Z),這個模型能夠將原來的概率分佈映射到訓練集的概率分佈,也就是說,它們的目的都是進行分佈之間的變換

http://5b0988e595225.cdn.sohucs.com/images/20180323/db8e4c893f004e73b61c91971d3109b8.jpeg

生成模型的難題就是判斷生成分佈與真實分佈的相似度,因爲我們只知道兩者的採樣結果,不知道它們的分佈表達式。

那現在假設服從標準的正態分佈,那麼我就可以從中採樣得到若干個 Z1,Z2,…,Zn,然後對它做變換得到 X̂1=g(Z1),X̂2=g(Z2),…,X̂n=g(Zn),我們怎麼判斷這個通過 f 構造出來的數據集,它的分佈跟我們目標的數據集分佈是不是一樣的呢?

有讀者說不是有 KL 散度嗎?當然不行,因爲 KL 散度是根據兩個概率分佈的表達式來算它們的相似度的,然而目前我們並不知道它們的概率分佈的表達式。

我們只有一批從構造的分佈採樣而來的數據 {X̂1,X̂2,…,X̂n},還有一批從真實的分佈採樣而來的數據 {X1,X2,…,Xn}(也就是我們希望生成的訓練集)。我們只有樣本本身,沒有分佈表達式,當然也就沒有方法算 KL 散度。

 

雖然遇到困難,但還是要想辦法解決的。GAN 的思路很直接粗獷:既然沒有合適的度量,那我乾脆把這個度量也用神經網絡訓練出來吧

就這樣,WGAN 就誕生了,詳細過程請參考互懟的藝術:從零直達 WGAN-GP。而 VAE 則使用了一個精緻迂迴的技巧。

 

VAE慢談

對於生成模型而言,最關鍵的是要求出P(x),有了P(x),只需要sampleP較大的x,就能得到比較合理的結果圖片。

首先我們有一批數據樣本 {X1,…,Xn},其整體用 X 來描述,我們本想根據 {X1,…,Xn} 得到 X 的分佈 p(X),如果能得到的話,那我直接根據 p(X) 來採樣,就可以得到所有可能的 X 了(包括 {X1,…,Xn} 以外的),這是一個終極理想的生成模型了。

當然,這個理想很難實現,P(x)又取決於選用什麼模型,比如後面用混合高斯模型

https://images2018.cnblogs.com/blog/312753/201807/312753-20180711141414649-446688595.png

高斯混合,是有若干個高斯分佈疊加成的,比如m個,

所以首先選中某個高斯的weight爲p(m),p(x|m)就符合該選中的高斯分佈

 

於是我們將分佈改一改:

http://5b0988e595225.cdn.sohucs.com/images/20180323/7e5aa0a51b954b3c998cc243f993daa7.png

這裏我們就不區分求和還是求積分了,意思對了就行。此時 p(X|Z) 就描述了一個由 Z 來生成 X 的模型,而我們假設 Z 服從標準正態分佈,也就是 p(Z)=N(0,I)。如果這個理想能實現,那麼我們就可以先從標準正態分佈中採樣一個 Z,然後根據 Z 來算一個 X,也是一個很棒的生成模型

接下來就是結合自編碼器來實現重構,保證有效信息沒有丟失,再加上一系列的推導,最後把模型實現。框架的示意圖如下:

http://5b0988e595225.cdn.sohucs.com/images/20180323/1621408ad4334d2183da5a38691de360.jpeg

看出了什麼問題了嗎?如果像這個圖的話,我們其實完全不清楚:究竟經過重新採樣出來的 Zk,是不是還對應着原來的 Xk,所以我們如果直接最小化 D(X̂ k,Xk)^2(這裏 D 代表某種距離函數)是很不科學的,而事實上你看代碼也會發現根本不是這樣實現的

也就是說,很多教程說了一大通頭頭是道的話,然後寫代碼時卻不是按照所寫的文字來寫,可是他們也不覺得這樣會有矛盾。

VAE初現

其實,在整個 VAE 模型中,我們並沒有去使用 p(Z)(先驗分佈)是正態分佈的假設,我們用的是假設 p(Z|X)(後驗分佈)是正態分佈

具體來說,給定一個真實樣本 Xk,我們假設存在一個專屬於 Xk 的分佈 p(Z|Xk)(學名叫後驗分佈),並進一步假設這個分佈是(獨立的、多元的)正態分佈。

爲什麼要強調“專屬”呢?因爲我們後面要訓練一個生成器 X=g(Z),希望能夠把從分佈 p(Z|Xk) 採樣出來的一個 Zk 還原爲 Xk

如果假設 p(Z) 是正態分佈,然後從 p(Z) 中採樣一個 Z,那麼我們怎麼知道這個 Z 對應於哪個真實的 X 呢?現在 p(Z|Xk) 專屬於 Xk,我們有理由說從這個分佈採樣出來的 Z 應該要還原到 Xk 中去

再次強調,這時候每一個 Xk 都配上了一個專屬的正態分佈,才方便後面的生成器做還原。但這樣有多少個 X 就有多少個正態分佈了。我們知道正態分佈有兩組參數:均值 μ 和方差 σ^2(多元的話,它們都是向量)

那我怎麼找出專屬於 Xk 的正態分佈 p(Z|Xk) 的均值和方差呢?好像並沒有什麼直接的思路。

VAE相當於一個,連續的高斯混合,即這裏有無限個高斯分佈選擇到某個高斯分佈的weight爲P(z), 符合標準高斯分佈z代表選中第z個高斯分佈,然後P(x|z)的高斯分佈的參數,mean,variance是通過nn求得

那好吧,我就用神經網絡來擬合出來。這就是神經網絡時代的哲學:難算的我們都用神經網絡來擬合,在 WGAN 那裏我們已經體驗過一次了,現在再次體驗到了。

於是我們構建兩個神經網絡 μk=f1(Xk),logσ^2=f2(Xk) 來算它們了。我們選擇擬合 logσ^2 而不是直接擬合 σ^2,是因爲 σ^2 總是非負的,需要加激活函數處理,而擬合 logσ^2 不需要加激活函數,因爲它可正可負。

到這裏,我能知道專屬於 Xk 的均值和方差了,也就知道它的正態分佈長什麼樣了,然後從這個專屬分佈中採樣一個 Zk 出來,然後經過一個生成器得到 X̂k=g(Zk)。

現在我們可以放心地最小化 D(X̂k,Xk)^2,因爲 Zk 是從專屬 Xk 的分佈中採樣出來的,這個生成器應該要把開始的 Xk 還原回來。於是可以畫出 VAE 的示意圖:

http://5b0988e595225.cdn.sohucs.com/images/20180323/8da0009b298c462b9dba190f21f594f5.jpeg

事實上,VAE 是爲每個樣本構造專屬的正態分佈,然後採樣來重構。

分佈標準化

讓我們來思考一下,根據上圖的訓練過程,最終會得到什麼結果。

首先,我們希望重構 X,也就是最小化 D(X̂k,Xk)^2,但是這個重構過程受到噪聲的影響,因爲 Zk 是通過重新採樣過的,不是直接由 encoder 算出來的

顯然噪聲會增加重構的難度,不過好在這個噪聲強度(也就是方差)通過一個神經網絡算出來的,所以最終模型爲了重構得更好,肯定會想盡辦法讓方差爲0。

而方差爲 0 的話,也就沒有隨機性了,所以不管怎麼採樣其實都只是得到確定的結果(也就是均值),只擬合一個當然比擬合多個要容易,而均值是通過另外一個神經網絡算出來的。

說白了,模型會慢慢退化成普通的 AutoEncoder,噪聲不再起作用

這樣不就白費力氣了嗎?說好的生成模型呢?

別急,其實 VAE 還讓所有的 p(Z|X) 都向標準正態分佈看齊,這樣就防止了噪聲爲零,同時保證了模型具有生成能力。

怎麼理解“保證了生成能力”呢?如果所有的 p(Z|X) 都很接近標準正態分佈 N(0,I),那麼根據定義:

http://5b0988e595225.cdn.sohucs.com/images/20180323/0f0ef0e95f5b40fda562b26225dc48c3.png

這樣我們就能達到我們的先驗假設:p(Z) 是標準正態分佈。然後我們就可以放心地從 N(0,I) 中採樣來生成圖像了。

 

 

這個前面解釋過了

 

那怎麼讓所有的 p(Z|X)都向 N(0,I) 看齊呢?如果沒有外部知識的話,其實最直接的方法應該是在重構誤差的基礎上中加入額外的 loss:

http://5b0988e595225.cdn.sohucs.com/images/20180323/a92214f4386448c798ebe7ab85169cd9.png

因爲它們分別代表了均值 μk 和方差的對數 logσ^2,達到 N(0,I) 就是希望二者儘量接近於 0 了。不過,這又會面臨着這兩個損失的比例要怎麼選取的問題,選取得不好,生成的圖像會比較模糊。

所以,原論文直接算了一般(各分量獨立的)正態分佈與標準正態分佈的 KL 散度 KL(N(μ,σ^2)‖N(0,I))作爲這個額外的 loss,計算結果爲:

http://5b0988e595225.cdn.sohucs.com/images/20180323/d69bc3ca4e32407b84b8cabbbae5114f.png

這裏的 d 是隱變量 Z 的維度,而 μ(i) 和 σ_{(i)}^{2} 分別代表一般正態分佈的均值向量和方差向量的第 i 個分量。直接用這個式子做補充 loss,就不用考慮均值損失和方差損失的相對比例問題了。

顯然,這個 loss 也可以分兩部分理解

http://5b0988e595225.cdn.sohucs.com/images/20180323/a71479e7e1b447f1ba6da9eb4056f635.png

 

推導

由於我們考慮的是各分量獨立的多元正態分佈,因此只需要推導一元正態分佈的情形即可,根據定義我們可以寫出:

http://5b0988e595225.cdn.sohucs.com/images/20180323/449d5b8c1ad54a548d916b5260cd98da.jpeg

整個結果分爲三項積分,第一項實際上就是 −logσ^2 乘以概率密度的積分(也就是 1),所以結果是 −logσ^2;第二項實際是正態分佈的二階矩,熟悉正態分佈的朋友應該都清楚正態分佈的二階矩爲 μ^2+σ^2;而根據定義,第三項實際上就是“-方差除以方差=-1”。所以總結果就是:

http://5b0988e595225.cdn.sohucs.com/images/20180323/148babfac2c748ec99d02a9155e7bf1e.png

 

重參數技巧

最後是實現模型的一個技巧,英文名是 Reparameterization Trick,我這裏叫它做重參數吧。

http://5b0988e595225.cdn.sohucs.com/images/20180323/11a4f3c7717e40b2b2939f57a49bc791.png

其實很簡單,就是我們要從 p(Z|Xk) 中採樣一個 Zk 出來,儘管我們知道了 p(Z|Xk) 是正態分佈,但是均值方差都是靠模型算出來的,我們要靠這個過程反過來優化均值方差的模型,但是“採樣”這個操作是不可導的,而採樣的結果是可導的,於是我們利用了一個事實:

http://5b0988e595225.cdn.sohucs.com/images/20180323/be4121f0a35f4eba981568ff185049b7.png

所以,我們將從 N(μ,σ^2) 採樣變成了從 N(μ,σ^2) 中採樣,然後通過參數變換得到從 N(μ,σ^2) 中採樣的結果。這樣一來,“採樣”這個操作就不用參與梯度下降了,改爲採樣的結果參與,使得整個模型可訓練了。

具體怎麼實現,大家把上述文字對照着代碼看一下,一下子就明白了。

 

本質是什麼

VAE 的本質是什麼?VAE 雖然也稱是 AE(AutoEncoder)的一種,但它的做法(或者說它對網絡的詮釋)是別具一格的。

在 VAE 中,它的 Encoder 有兩個,一個用來計算均值,一個用來計算方差,這已經讓人意外了:Encoder 不是用來 Encode 的,是用來算均值和方差的,這真是大新聞了,還有均值和方差不都是統計量嗎,怎麼是用神經網絡來算的?

事實上,我覺得 VAE 從讓普通人望而生畏的變分和貝葉斯理論出發,最後落地到一個具體的模型中,雖然走了比較長的一段路,但最終的模型其實是很接地氣的。它本質上就是在我們常規的自編碼器的基礎上,對 encoder 的結果(在VAE中對應着計算均值的網絡)加上了高斯噪聲,使得結果 decoder 能夠對噪聲有魯棒性;而那個額外的 KL loss(目的是讓均值爲 0,方差爲 1),事實上就是相當於對 encoder 的一個正則項,希望 encoder 出來的東西均有零均值。那另外一個 encoder(對應着計算方差的網絡)的作用呢?它是用來動態調節噪聲的強度的。直覺上來想 decoder 還沒有訓練好時(重構誤差遠大於 KL loss),就會適當降低噪聲(KL loss 增加),使得擬合起來容易一些(重構誤差開始下降)。反之,如果 decoder 訓練得還不錯時(重構誤差小於 KL loss),這時候噪聲就會增加(KL loss 減少),使得擬合更加困難了(重構誤差又開始增加),這時候 decoder 就要想辦法提高它的生成能力了

http://5b0988e595225.cdn.sohucs.com/images/20180323/b65176b6c8314465b3639222933dd6e4.jpeg

說白了,重構的過程是希望沒噪聲的,而 KL loss 則希望有高斯噪聲的,兩者是對立的。所以,VAE 跟 GAN 一樣,內部其實是包含了一個對抗的過程,只不過它們兩者是混合起來,共同進化的

從這個角度看,VAE 的思想似乎還高明一些,因爲在 GAN 中,造假者在進化時,鑑別者是安然不動的,反之亦然。當然,這只是一個側面,不能說明 VAE 就比 GAN 好。

GAN 真正高明的地方是:它連度量都直接訓練出來了,而且這個度量往往比我們人工想的要好(然而 GAN 本身也有各種問題,這就不展開了)。

正態分佈?

對於 p(Z|X) 的分佈,讀者可能會有疑惑:是不是必須選擇正態分佈?可以選擇均勻分佈嗎?

首先,這個本身是一個實驗問題,兩種分佈都試一下就知道了。但是從直覺上來講,正態分佈要比均勻分佈更加合理,因爲正態分佈有兩組獨立的參數:均值和方差,而均勻分佈只有一組。

前面我們說,在 VAE 中,重構跟噪聲是相互對抗的,重構誤差跟噪聲強度是兩個相互對抗的指標,而在改變噪聲強度時原則上需要有保持均值不變的能力,不然我們很難確定重構誤差增大了,究竟是均值變化了(encoder的鍋)還是方差變大了(噪聲的鍋)

而均勻分佈不能做到保持均值不變的情況下改變方差,所以正態分佈應該更加合理。

 

變分在哪裏

還有一個有意思(但不大重要)的問題是:VAE 叫做“變分自編碼器”,它跟變分法有什麼聯繫?在VAE 的論文和相關解讀中,好像也沒看到變分法的存在?

其實如果讀者已經承認了 KL 散度的話,那 VAE 好像真的跟變分沒多大關係了,因爲 KL 散度的定義是:

http://5b0988e595225.cdn.sohucs.com/images/20180323/9662d78e3e6340a2b9f802ba115fb823.png

如果是離散概率分佈就要寫成求和,我們要證明:已概率分佈 p(x)(或固定q(x))的情況下,對於任意的概率分佈 q(x)(或 p(x)),都有 KLp(x)‖q(x))≥0,而且只有當p(x)=q(x)時才等於零

因爲 KL(p(x)‖q(x))實際上是一個泛函,要對泛函求極值就要用到變分法,當然,這裏的變分法只是普通微積分的平行推廣,還沒涉及到真正複雜的變分法。而 VAE 的變分下界,是直接基於 KL 散度就得到的。所以直接承認了 KL 散度的話,就沒有變分的什麼事了。

一句話,VAE 的名字中“變分”,是因爲它的推導過程用到了 KL 散度及其性質。

 

VAE簡短總結:爲採樣的真實樣本中的每一個樣本,構造專屬的正態分佈,其中的均值和方差採用神經網絡進行擬合,這個專屬的後驗分佈p(Z|Xk)是正態的,而且向標準正態分佈看齊,防止隨着神經網絡擬合噪聲(方差)慢慢趨於0(這樣的話模型慢慢退化爲AutoEncoder,噪聲不再起作用),看齊的方式是在重構損失上加上額外的損失,即計算均值和方差的loss,從這個專屬的正態分佈中採樣出一個Zk出來,這個Zk對應着原來的Xk,然後通過生成器得到X̂k=g(Zk),然後最小化D(Xk, X̂k),D是某個距離度量函數。

 

 

VAE爲什麼會有作用?

先看一種intuituive的解釋,左邊的圖,對於普通的AE,如果在滿月和絃月的code的中間調一個點,去做decode會得到什麼?答案是不確定,因爲你對code的分佈並沒有任何的約束而VAE引入了noise,所以對於相同的input經過encoder後雖然得到的mean和variance是相同的,但是noise是不同的,所以會有一些較小的誤差如右邊的圖,所以對於VAE在這樣的一個誤差範圍內的點,而不是僅僅一個點都應該能decode到滿月或弦月那麼對於noise區間重合的地方,就會產生漸進的圖,要同時和滿月或弦月都比較相似,如最右圖所示

https://images2018.cnblogs.com/blog/312753/201807/312753-20180703145446034-1204470043.png

 

下圖顯示如何將original code轉化爲noise code可以看到這裏的variance是學習到的,這裏之所以要exp是保證variance爲正

 

https://images2018.cnblogs.com/blog/312753/201807/312753-20180703150630898-1360738813.png

好,那單純的這樣去訓練是不是會產生我們希望的效果?

答案是不會的,因爲惰性是存在萬事萬物中的,能簡單解決,網絡也不會把自己搞的很複雜.這裏如果沒有任何約束,那麼訓練出來只要variance全爲0就ok了,這樣就等同於普通的AE。

所以還需要加一個約束

https://images2018.cnblogs.com/blog/312753/201807/312753-20180703152228325-1896400476.png

這個約束的紅,藍部分,如果要minimize,相減爲0,這樣就保證variance接近於1 (variance = exp(a))

可以看到這個約束本身就會保證有一定的noise存在,然後後面的m平方的項是,L2 regularization,正則項。

這裏是前文提到的,讓所有的 p(Z|X) 都向標準正態分佈看齊,這樣就防止了噪聲爲零,同時保證了模型具有生成能力。

 

 

 

https://www.sohu.com/a/226209674_500659

https://www.zhihu.com/question/41490383/answer/103006793

https://www.bilibili.com/video/av10590361/?p=29

 

理論上formal的解釋

https://www.cnblogs.com/fxjwind/p/9099931.html

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