變分自編碼器介紹、推導及實現
0. 預備知識
0.1 信息量
在信息理論中,我們用以下式子來量化一個事件

的信息量

:

當

底數為 e 時,信息量的單位為 nat(奈特),當

底數為 2 時,信息量的單位為 bit(比特)。
0.2 信息熵(Entropy)
此外,如果用以下兩個式子分別來表示隨機變量

在離散和連續情況下的信息熵

:

信息熵可以看做是對信息量的期望。
0.3 K-L 散度(Kullback-Leibler divergence)
K-L 散度又被稱為相對熵(relative entropy),是對兩個概率分布間差異的非對稱性度量。
假設

是隨機變量 上的兩個概率分布,則在離散和連續隨機變量的情形下,相對熵的定義分別為:

注意!K-L 散度不是對稱的,它不是描述兩個分布之間的距離,因為按照上述定義,

0.4 貝葉斯公式(Bayes Rule)
這個就不多講了,為了和下述的 notation 保持一致,公式表述如下

1. 什么是變分自編碼器
變分自編碼器的英文是 (variational auto-encoder,VAE),其實在將 VAE 之前,我們必須提一下自編碼器(auto-encoder,AE)。
在 AE 的結構中包含一個編碼器(encoder)和解碼器(decoder),其中 encoder 的作用是將我們的數據空間

映射到另一個隱變量(latent variable)空間

上去,具體來說,我們的一個輸入數據樣本

將被被編碼成一個 vector,這個 vector 中的每一維度就是一些該樣本的屬性;而 decoder 要干的事則剛好與 encoder 相反,它可以接受一個 latent vector,並且重新變回到原樣本空間上去。至於具體怎么轉化,這個很復雜,我們也不知道它中間到底是怎么變換的,怎么辦呢?神經網絡來幫忙,神經網絡理論上就是可以擬合任何一個函數的,不管你有多復雜。

(圖片來源網絡,侵刪)
如上圖所示,舉例類比我們人寫數字的行為來說,我現在讓你寫一個 4,在你聽到這句話之后且開始動筆之前,你會在大腦里想,哦,你讓我寫 4,4 應該先這樣彎一下,而且最后有一豎,筆畫應該寫長點... 類似這種,whatever,這些你思考的屬性就是 latent variable,也即 encode。然后,你的大腦再根據你所想的這些屬性指導你去把這個 4 寫出來,即 decode。至於大腦怎么指導這些空間變換的,誰知道呢!
說了這么多,終於可以開始將 VAE 了,它和 AE 的不同點就在於,AE 中間輸出的是隱變量的具體取值,而 VAE 中間要輸出的是隱變量的具體分布情況,這樣一來,我們就可以從這個分布中另外取樣,送入到 decoder,就可以生成類似輸入樣本

的其他樣本

了,並且這兩個會十分近似。 That is to say, the encoder in VAE will output the probability distribution of each latent attribution rather than telling us a single value to describe each latent state.
再舉個例子,這個示例來源於 [1] Variational autoencoders, Jenemy Jordan,如果我們有個人臉的數據集,在 AE 中,我們希望它完成下圖的工作:

(圖片創作於 Jenemy Jordan,侵刪)
即對每一個屬性,給出一個確切的取值。比如上面的 smile 屬性,現在取值是 0.99,那模型為什么輸出一個 0.99 呢?為啥不是 0.98,0.97 等等呢?是的,這就是 VAE 干的事情,VAE 希望學習到關於該 smile 屬性的概率分布,當然,該概率分布函數 y 取值最大時對應的 x 就是這里的 0.99,也即 AE 給出該屬性的那個確切值,如下圖所示:

(圖片創作於 Jenemy Jordan,侵刪)
好,那現在我知道當前這個人笑的燦爛程度是 0.99,並且長胡須的程度是 0.85,假如我現在想知道長胡須程度是 0.65 的人笑的燦爛程度是 0.89 的人臉會是怎樣的樣子怎么辦呢?那就取樣唄,反正 VAE 學習到了各個屬性的分布,然后再送入 decoder 變換回來,就類型下圖所示:

(圖片創作於 Jenemy Jordan,侵刪)
於是,VAE 的總體架構如下圖所示:

好了,終於說完了 VAE 是在做什么,接下來我將完成數學理論推導,請務必理解推導過程,別擔心,那很簡單!
2. 數學理論推導
現在我們假設知道的確有這樣的 latent variables,但是我們不知道它到底是一個怎樣的分布,現在能夠觀測到的就是樣本

,我們希望在給定

的條件下去推出

的分布,即

.
根據貝葉斯定理,可得:

然而,這個后驗概率

是不可解的,因為無法計算

,根據全概率公式可知:

如果 z 是一個維度很高的變量,你想想是不是有無窮多重的積分,會變成大概這樣的計算式子:

於是這里大致有兩種方法求解: - ① 蒙特卡羅算法(Mote Carlo method),不斷取樣 z,取樣越多 p(x) 越接近真實的分布。 - ② Variational Inference,既然

不可解,那我就嘗試用一個可解的分布

去近似

,即 approximation 的方式。
注意一下,你可能會在其他資料中看到這里的表述是

而不是

,其實這里無關緊要,只取決於你如何解釋它,因為當前的

是已經給出了的嘛, 請務必記住這點, 我個人還是習慣於寫成

的形式!好的,故事從這里開始。
我們想讓

去近似

,所以肯定希望這兩個分布間的差異越小越好,K-L 散度就可以派上用場, 我們希望

而根據 K-L 散度的定義,可知:

暫停一下,回顧一下我們是要干嘛,最小化上面這一大串,

是已經給定的,所以雖然我不知道

是多少,但它的確肯定是個定值,於是最小化

等價於最小化最后兩項,我們記作為

:

再次暫停,現在是要最小化

, 也等價於最大化

, 即最大化

這是啥?第一項就是說不斷在 z 上采樣,然后使得被重構的樣本中重構

的幾率最大;第二項就是說使得我們假設的后驗證分布

和先驗分布

盡量接近,這個式子也就差不多指引我們去構造一個 auto-encoder,所以這也是為什么這個模型叫 VAE 吧。

再深入研究一下

式:
第一項實際上是一個重建 error,為什么?好,我們說從

到

的轉換是神經網絡干的事情,它是一個函數,雖然說我們不知道它具體的表達式是什么,無論我輸入一個怎樣的 input,總是會給我一個相應的 output,所以

式的第一項中的

可以看作是

,假設 p 是一個正態分布,你自己想想會是什么!

loss!當然,如果你假設 p 是伯努利分布,那就是交叉熵了。
第二項,我們說是為了讓我們假設的后驗證分布

和先驗分布

盡量接近,論文中假設 p(z) 是一個標准高斯分布,為什么這么假設呢?
The key is to notice that any distribution in d dimensions can be generated by taking a set of d variables that are normally distributed and mapping them through a sufficiently complicated function.
所以,在 decoder 部分,你可以看做神經網絡的前幾層是將一個關於 z 的正態分布映射到其他對應的 latent value 上去,也就好似傳統 AE 中的 code vector 中一個個的 single value。
If f (z; q) is a multi-layer neural network, then we can imagine the network using its first few layers to map the normally distributed z’s to the latent values (like digit identity, stroke weight, angle, etc.) with exactly the right statitics. Then it can use later layers to map those latent values to a fully rendered digit.
為了好算,我們假設

也是高斯分布,然后就可以用一個閉式直接計算了。
3. 實現
在論文中,有提到一個 reparameterization trick, 主要是處理反向傳播時的求導問題,這個就不細說了,最后參考文獻中很多資料中都有提到。
下面用 Pytorch 在 MNIST 數據集上實現一下 VAE,代碼已經上傳到我的 Github,代碼中很大部分都參考了網上的一些實現。
LiUzHiAn/VAE-Pytorchgithub.com
下面是一些圖片重建和隨機生成的結果,我只訓練了 30 輪:
- 重建結果(依次為 10,20,30 輪的結果)

epoch-10

epoch-20

epoch-30
- 生成結果(依次為 10,20,30 輪的結果)

epoch-10

epoch-20

epoch-30
4. References
- 博客:
[1] Jenemy Jordan: Variational autoencoders
[2] Irhum Shafkat: Intuitively Understanding Variational Autoencoders
[3] 花式解釋 AutoEncoder 與 VAE
[4] 張俊: 變分自編碼器 VAE:原來是這么一回事
[5] Tensorflow: Convolutional Variational Autoencoder
- 視頻及幻燈片:
[6] Ali Ghodsi: Deep Learning, Variational Autoencoder (Oct 12 2017)
[7] Stanford CS231n: Lecture on Variational Autoencoders
[8] Sherlock: Raymond Yeh, Junting Lou, Teck-Yian Lim: CS598LAZ - Variational Autoencoders
- 論文:
[9] Diederik P Kingma, Max Welling: Auto-Encoding Variational Bayes
[10] CARL DOERSCH, Tutorial on Variational Autoencoders, Carnegie Mellon / UC Berkeley, August 16, 2016 說在前面的話
