深度学习(二十六)——VAE
https://antkillerfarm.github.io/
VAE
變分自編碼器(Variational Auto-Encoder,VAE)是Autoencoder的一種擴展。
論文:
《Auto-Encoding Variational Bayes》
以下部分主要摘自:
https://kexue.fm/archives/5253
變分自編碼器(一):原來是這么一回事
分布變換
通常我們會拿VAE跟GAN比較,的確,它們兩個的目標基本是一致的——希望構建一個從隱變量Z生成目標數據X的模型,但是實現上有所不同。更準確地講,它們是假設了Z服從某些常見的分布(比如正態分布或均勻分布),然后希望訓練一個模型X=g(Z)X=g(Z)X=g(Z),這個模型能夠將原來的概率分布映射到訓練集的概率分布,也就是說,它們的目的都是進行分布之間的映射。
現在假設Z服從標準的正態分布,那么我就可以從中采樣得到若干個Z1,Z2,…,ZnZ_1, Z_2, \dots, Z_nZ1?,Z2?,…,Zn?,然后對它做變換得到X^1=g(Z1),X^2=g(Z2),…,X^n=g(Zn)\hat{X}_1 = g(Z_1),\hat{X}_2 = g(Z_2),\dots,\hat{X}_n = g(Z_n)X^1?=g(Z1?),X^2?=g(Z2?),…,X^n?=g(Zn?),我們怎么判斷這個通過f構造出來的數據集,它的分布跟我們目標數據集的分布是不是一樣的呢?
生成模型的難題就是判斷生成分布與真實分布的相似度,因為我們只知道兩者的采樣結果,不知道它們的分布表達式。
有讀者說不是有KL散度嗎?當然不行,因為KL散度是根據兩個概率分布的表達式來算它們的相似度的,然而目前我們并不知道它們的概率分布的表達式,我們只有一批從構造的分布采樣而來的數據{X^1,X^2,…,X^n}\{\hat{X}_1,\hat{X}_2,\dots,\hat{X}_n\}{X^1?,X^2?,…,X^n?},還有一批從真實的分布采樣而來的數據{X1,X2,…,Xn}\{X_1,X_2,\dots,X_n\}{X1?,X2?,…,Xn?}(也就是我們希望生成的訓練集)。我們只有樣本本身,沒有分布表達式,當然也就沒有方法算KL散度。
雖然遇到困難,但還是要想辦法解決的。GAN的思路很直接粗獷:既然沒有合適的度量,那我干脆把這個度量也用神經網絡訓練出來吧。而VAE則使用了一個精致迂回的技巧。
VAE的傳統理解
首先我們有一批數據樣本{X1,…,Xn}\{X_1,\dots,X_n\}{X1?,…,Xn?},其整體用X來描述,我們本想根據{X1,…,Xn}\{X_1,\dots,X_n\}{X1?,…,Xn?}得到X的分布p(X),如果能得到的話,那我直接根據p(X)來采樣,就可以得到所有可能的X了(包括{X1,…,Xn}\{X_1,\dots,X_n\}{X1?,…,Xn?}以外的),這是一個終極理想的生成模型了。當然,這個理想很難實現,于是我們將分布改一改:
p(X)=∑Zp(X∣Z)p(Z)p(X)=\sum_Z p(X|Z)p(Z)p(X)=Z∑?p(X∣Z)p(Z)
此時p(X∣Z)p(X\mid Z)p(X∣Z)就描述了一個由Z來生成X的模型,而我們假設Z服從標準正態分布,也就是p(Z)=N(0,I)p(Z)=\mathcal{N}(0,I)p(Z)=N(0,I)。如果這個理想能實現,那么我們就可以先從標準正態分布中采樣一個Z,然后根據Z來算一個X,也是一個很棒的生成模型。接下來就是結合自編碼器來實現重構,保證有效信息沒有丟失,再加上一系列的推導,最后把模型實現。框架的示意圖如下:
看出了什么問題了嗎?如果像這個圖的話,我們其實完全不清楚:究竟經過重新采樣出來的ZkZ_kZk?,是不是還對應著原來的XkX_kXk?,所以我們如果直接最小化D(X^k,Xk)2\mathcal{D}(\hat{X}_k,X_k)^2D(X^k?,Xk?)2(這里D代表某種距離函數)是很不科學的,而事實上你看代碼也會發現根本不是這樣實現的。
VAE初現
其實,在整個VAE模型中,我們并沒有去使用p(Z)(先驗分布)是正態分布的假設,我們用的是假設p(Z∣X)p(Z\mid X)p(Z∣X)(后驗分布)是正態分布!!
具體來說,給定一個真實樣本XkX_kXk?,我們假設存在一個專屬于XkX_kXk?的分布p(Z∣Xk)p(Z\mid X_k)p(Z∣Xk?)(學名叫后驗分布),并進一步假設這個分布是(獨立的、多元的)正態分布。為什么要強調“專屬”呢?因為我們后面要訓練一個生成器X=g(Z)X=g(Z)X=g(Z),希望能夠把從分布p(Z∣Xk)p(Z\mid X_k)p(Z∣Xk?)采樣出來的一個ZkZ_kZk?還原為XkX_kXk?。如果假設p(Z)是正態分布,然后從p(Z)中采樣一個Z,那么我們怎么知道這個Z對應于哪個真實的X呢?現在p(Z∣Xk)p(Z\mid X_k)p(Z∣Xk?)專屬于XkX_kXk?,我們有理由說從這個分布采樣出來的Z應該要還原到XkX_kXk?中去。
這樣有多少個X就有多少個正態分布了。我們知道正態分布有兩組參數:均值μ\muμ和方差σ2\sigma^2σ2(多元的話,它們都是向量),那我怎么找出專屬于XkX_kXk?的正態分布p(Z∣Xk)p(Z\mid X_k)p(Z∣Xk?)的均值和方差呢?好像并沒有什么直接的思路。那好吧,就用神經網絡擬合出來吧!
于是我們構建兩個神經網絡μk=f1(Xk),log?σ2=f2(Xk)\mu_k = f_1(X_k),\log \sigma^2 = f_2(X_k)μk?=f1?(Xk?),logσ2=f2?(Xk?)來算它們了。我們選擇擬合log?σ2\log \sigma^2logσ2而不是直接擬合σ2\sigma^2σ2,是因為σ2\sigma^2σ2總是非負的,需要加激活函數處理,而擬合log?σ2\log \sigma^2logσ2不需要加激活函數,因為它可正可負。到這里,知道專屬于XkX_kXk?的均值和方差,也就知道它的正態分布長什么樣了,然后從這個專屬分布中采樣一個ZkZ_kZk?出來,經過一個生成器得到X^k=g(Zk)\hat{X}_k=g(Z_k)X^k?=g(Zk?),現在我們可以放心地最小化D(X^k,Xk)2\mathcal{D}(\hat{X}_k,X_k)^2D(X^k?,Xk?)2,因為ZkZ_kZk?是從專屬XkX_kXk?的分布中采樣出來的,這個生成器應該要把開始的XkX_kXk?還原回來。
分布標準化
讓我們來思考一下,根據上圖的訓練過程,最終會得到什么結果。
首先,我們希望重構X,也就是最小化D(X^k,Xk)2\mathcal{D}(\hat{X}_k,X_k)^2D(X^k?,Xk?)2,但是這個重構過程受到噪聲的影響,因為ZkZ_kZk?是通過重新采樣過的,不是直接由encoder算出來的。顯然噪聲會增加重構的難度,不過好在這個噪聲強度(也就是方差)通過一個神經網絡算出來的,所以最終模型為了重構得更好,肯定會想盡辦法讓方差為0。而方差為0的話,也就沒有隨機性了,所以不管怎么采樣其實都只是得到確定的結果(也就是均值)。說白了,模型會慢慢退化成普通的AutoEncoder,噪聲不再起作用。
為了使模型具有生成能力,VAE決定讓所有的p(Z∣X)p(Z\mid X)p(Z∣X)都向標準正態分布看齊。如果所有的p(Z∣X)p(Z\mid X)p(Z∣X)都很接近標準正態分布N(0,I)\mathcal{N}(0,I)N(0,I),那么根據定義:
p(Z)=∑Xp(Z∣X)p(X)=∑XN(0,I)p(X)=N(0,I)∑Xp(X)=N(0,I)p(Z)=\sum_X p(Z|X)p(X)=\sum_X \mathcal{N}(0,I)p(X)=\mathcal{N}(0,I) \sum_X p(X) = \mathcal{N}(0,I)p(Z)=X∑?p(Z∣X)p(X)=X∑?N(0,I)p(X)=N(0,I)X∑?p(X)=N(0,I)
這樣我們就能達到我們的先驗假設:p(Z)是標準正態分布。然后我們就可以放心地從N(0,I)\mathcal{N}(0,I)N(0,I)中采樣來生成圖像了。
那怎么讓所有的p(Z∣X)p(Z\mid X)p(Z∣X)都向N(0,I)\mathcal{N}(0,I)N(0,I)看齊呢?如果沒有外部知識的話,其實最直接的方法應該是在重構誤差的基礎上中加入額外的loss:
Lμ=∥f1(Xk)∥2,Lσ2=∥f2(Xk)∥2\mathcal{L}_{\mu}=\Vert f_1(X_k)\Vert^2,\mathcal{L}_{\sigma^2}=\Vert f_2(X_k)\Vert^2Lμ?=∥f1?(Xk?)∥2,Lσ2?=∥f2?(Xk?)∥2
因為它們分別代表了均值μk\mu_kμk?和方差的對數log?σ2\log \sigma^2logσ2,達到N(0,I)\mathcal{N}(0,I)N(0,I)就是希望二者盡量接近于0了。不過,這又會面臨著這兩個損失的比例要怎么選取的問題,選取得不好,生成的圖像會比較模糊。所以,原論文直接算了一般(各分量獨立的)正態分布與標準正態分布的KL散度KL(N(μ,σ2)∥N(0,I))KL\Big(N(\mu,\sigma^2)\Big\Vert N(0,I)\Big)KL(N(μ,σ2)∥∥∥?N(0,I))作為這個額外的loss,計算結果為:
Lμ,σ2=12∑i=1d(μ(i)2+σ(i)2?log?σ(i)2?1)\mathcal{L}_{\mu,\sigma^2}=\frac{1}{2} \sum_{i=1}^d \Big(\mu_{(i)}^2 + \sigma_{(i)}^2 - \log \sigma_{(i)}^2 - 1\Big)Lμ,σ2?=21?i=1∑d?(μ(i)2?+σ(i)2??logσ(i)2??1)
這里的d是隱變量Z的維度,而μ(i)\mu_{(i)}μ(i)?和σ(i)2\sigma_{(i)}^2σ(i)2?分別代表一般正態分布的均值向量和方差向量的第i個分量。直接用這個式子做補充loss,就不用考慮均值損失和方差損失的相對比例問題了。顯然,這個loss也可以分兩部分理解:
Lμ,σ2=Lμ+Lσ2Lμ=12∑i=1dμ(i)2=12∥f1(X)∥2Lσ2=12∑i=1d(σ(i)2?log?σ(i)2?1)\begin{aligned}&\mathcal{L}_{\mu,\sigma^2}=\mathcal{L}_{\mu} + \mathcal{L}_{\sigma^2}\\ &\mathcal{L}_{\mu}=\frac{1}{2} \sum_{i=1}^d \mu_{(i)}^2=\frac{1}{2}\Vert f_1(X)\Vert^2\\ &\mathcal{L}_{\sigma^2}=\frac{1}{2} \sum_{i=1}^d\Big(\sigma_{(i)}^2 - \log \sigma_{(i)}^2 - 1\Big)\end{aligned}?Lμ,σ2?=Lμ?+Lσ2?Lμ?=21?i=1∑d?μ(i)2?=21?∥f1?(X)∥2Lσ2?=21?i=1∑d?(σ(i)2??logσ(i)2??1)?
Reparameterization Trick
這是實現模型的一個技巧。我們要從p(Z∣Xk)p(Z\mid X_k)p(Z∣Xk?)中采樣一個ZkZ_kZk?出來,盡管我們知道了p(Z∣Xk)p(Z\mid X_k)p(Z∣Xk?)是正態分布,但是均值方差都是靠模型算出來的,我們要靠這個過程反過來優化均值方差的模型,但是“采樣”這個操作是不可導的,而采樣的結果是可導的,于是我們利用了一個事實:
從N(μ,σ2)\mathcal{N}(\mu,\sigma^2)N(μ,σ2)中采樣一個Z,相當于從N(0,I)\mathcal{N}(0,I)N(0,I)中采樣一個ε\varepsilonε,然后讓Z=μ+ε×σZ=\mu + \varepsilon \times \sigmaZ=μ+ε×σ。
于是,我們將從N(μ,σ2)\mathcal{N}(\mu,\sigma^2)N(μ,σ2)采樣變成了從N(0,I)\mathcal{N}(0,I)N(0,I)中采樣,然后通過參數變換得到從N(μ,σ2)\mathcal{N}(\mu,\sigma^2)N(μ,σ2)中采樣的結果。這樣一來,“采樣”這個操作就不用參與梯度下降了,改為采樣的結果參與,使得整個模型可訓練了。
VAE本質
VAE本質上就是在我們常規的自編碼器的基礎上,對encoder的結果(在VAE中對應著計算均值的網絡)加上了“高斯噪聲”,使得結果decoder能夠對噪聲有魯棒性;而那個額外的KL loss(目的是讓均值為0,方差為1),事實上就是相當于對encoder的一個正則項,希望encoder出來的東西均有零均值。
那另外一個encoder(對應著計算方差的網絡)的作用呢?它是用來動態調節噪聲的強度的。直覺上來想,當decoder還沒有訓練好時(重構誤差遠大于KL loss),就會適當降低噪聲(KL loss增加),使得擬合起來容易一些(重構誤差開始下降);反之,如果decoder訓練得還不錯時(重構誤差小于KL loss),這時候噪聲就會增加(KL loss減少),使得擬合更加困難了(重構誤差又開始增加),這時候decoder就要想辦法提高它的生成能力了。
簡言之,重構的過程是希望沒噪聲的,而KL loss則希望有高斯噪聲的,兩者是對立的。所以,VAE跟GAN一樣,內部其實是包含了一個對抗的過程,只不過它們兩者是混合起來,共同進化的。
VAE vs AE
VAE和AE的差異在于:
1.兩者雖然都是X->Z->X’的結構,但是AE尋找的是單值映射關系,即:z=f(x)z=f(x)z=f(x)。
2.而VAE尋找的是分布的映射關系,即:DX→DZD_X\to D_ZDX?→DZ?。
為什么會有這個差別呢?我們不妨從生成模型的角度考慮一下。既然AE的decoder做的是Z->X’的變換,那么理論上它也可以作為生成器使用。但這里有個問題,顯然不是所有的RZR^ZRZ都是有效的Z,或者可以說Z只占了高維空間RZR^ZRZ的一部分。Z的邊界在哪里?如何得到有效的z,從而生成x?這些都不是AE能解決的。
VAE映射的是分布,而分布可以通過采樣得到有效的z,從而生成相應的x。
總結
以上是生活随笔為你收集整理的深度学习(二十六)——VAE的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 深度学习(二十五)——Attention
- 下一篇: 深度学习(二十八)——SOM, Grou