VAE:變分自編碼器的原理介紹(一)

本文轉載於以下博客地址:

https://www.cnblogs.com/huangshiyu13/p/6209016.html

如有冒犯,還望見解。

VAE(Variational Autoencoder)的原理

Kingma, Diederik P., and Max Welling. "Auto-encoding variational bayes." arXiv preprint arXiv:1312.6114 (2013).

論文的理論推導見:https://zhuanlan.zhihu.com/p/25401928

中文翻譯爲:變分自動編碼器

轉自:http://kvfrans.com/variational-autoencoders-explained/

下面是VAE的直觀解釋,不需要太多的數學知識。 

什麼是變分自動編碼器?

爲了理解VAE,我們首先從最簡單的網絡說起,然後再一步一步添加額外的部分。

一個描述神經網絡的常見方法是近似一些我們想建模的函數。然而神經網絡也可以被看做是攜帶信息的數據結構。

假如我們有一個帶有解卷積層的網絡,我們設置輸入爲值全爲1的向量,輸出爲一張圖像。然後,我們可以訓練這個網絡去減小重構圖像和原始圖像的平均平方誤差。那麼訓練完後,這個圖像的信息就被保留在了網絡的參數中。

 

現在,我們嘗試使用更多的圖片。這次我們用one-hot向量而不是全1向量。我們用[1, 0, 0, 0]代表貓,用[0, 1, 0, 0]代表狗。雖然這要沒什麼問題,但是我們最多隻能儲存4張圖片。當然,我們也可以增加向量的長度和網絡的參數,那麼我們可以獲得更多的圖片。

但是,這樣的向量很稀疏。爲了解決這個問題,我們想使用實數值向量而不是0,1向量。我們可認爲這種實數值向量是原圖片的一種編碼,這也就引出了編碼/解碼的概念。舉個例子,[3.3, 4.5, 2.1, 9.8]代表貓,[3.4, 2.1, 6.7, 4.2] 代表狗。這個已知的初始向量可以作爲我們的潛在變量。

如果像我上面一樣,隨機初始化一些向量去代表圖片的編碼,這不是一個很好的辦法,我們更希望計算機能幫我們自動編碼。在autoencoder模型中,我們加入一個編碼器,它能幫我們把圖片編碼成向量。然後解碼器能夠把這些向量恢復成圖片。

 

我們現在獲得了一個有點實際用處的網絡了。而且我們現在能訓練任意多的圖片了。如果我們把這些圖片的編碼向量存在來,那以後我們就能通過這些編碼向量來重構我們的圖像。我們稱之爲標準自編碼器。

但是,我們想建一個產生式模型,而不是一個只是儲存圖片的網絡。現在我們還不能產生任何未知的東西,因爲我們不能隨意產生合理的潛在變量。因爲合理的潛在變量都是編碼器從原始圖片中產生的。

這裏有個簡單的解決辦法。我們可以對編碼器添加約束,就是強迫它產生服從單位高斯分佈的潛在變量。正式這種約束,把VAE和標準自編碼器給區分開來了。

現在,產生新的圖片也變得容易:我們只要從單位高斯分佈中進行採樣,然後把它傳給解碼器就可以了。

事實上,我們還需要在重構圖片的精確度和單位高斯分佈的擬合度上進行權衡。

我們可以讓網絡自己去決定這種權衡。對於我們的損失函數,我們可以把這兩方面進行加和。一方面,是圖片的重構誤差,我們可以用平均平方誤差來度量,另一方面。我們可以用KL散度(KL散度介紹)來度量我們潛在變量的分佈和單位高斯分佈的差異。

 

爲了優化KL散度,我們需要應用一個簡單的參數重構技巧:不像標準自編碼器那樣產生實數值向量,VAE的編碼器會產生兩個向量:一個是均值向量,一個是標準差向量。

 

我們可以這樣來計算KL散度:

# z_mean and z_stddev are two vectors generated by encoder network

latent_loss = 0.5 * tf.reduce_sum(tf.square(z_mean) + tf.square(z_stddev) - tf.log(tf.square(z_stddev)) - 1,1)

當我們計算解碼器的loss時,我們就可以從標準差向量中採樣,然後加到我們的均值向量上,就得到了編碼去需要的潛在變量。

 

VAE除了能讓我們能夠自己產生隨機的潛在變量,這種約束也能提高網絡的產生圖片的能力。

爲了更加形象,我們可以認爲潛在變量是一種數據的轉換。

我們假設我們有一堆實數在區間[0, 10]上,每個實數對應一個物體名字。比如,5.43對應着蘋果,5.44對應着香蕉。當有個人給你個5.43,你就知道這是代表着蘋果。我們能用這種方法夠編碼無窮多的物體,因爲[0, 10]之間的實數有無窮多個。

但是,如果某人給你一個實數的時候其實是加了高斯噪聲的呢?比如你接受到了5.43,原始的數值可能是 [4.4 ~ 6.4]之間的任意一個數,真實值可能是5.44(香蕉)。

如果給的方差越大,那麼這個平均值向量所攜帶的可用信息就越少。

現在,我們可以把這種邏輯用在編碼器和解碼器上。編碼越有效,那麼標準差向量就越能趨近於標準高斯分佈的單位標準差。

這種約束迫使編碼器更加高效,並能夠產生信息豐富的潛在變量。這也提高了產生圖片的性能。而且我們的潛變量不僅可以隨機產生,也能從未經過訓練的圖片輸入編碼器後產生。

VAE的效果:

我做了一些小實驗來測試VAE在MNIST手寫數字數據集上的表現:

 

這裏有一些使用VAE好處,就是我們可以通過編碼解碼的步驟,直接比較重建圖片和原始圖片的差異,但是GAN做不到。

另外,VAE的一個劣勢就是沒有使用對抗網絡,所以會更趨向於產生模糊的圖片。

這裏也有一些結合VAE和GAN的工作:使用基本的VAE框架,但是用對抗網絡去訓練解碼器。更多細節參考:https://arxiv.org/pdf/1512.09300.pdfhttp://blog.otoro.net/2016/04/01/generating-large-images-from-latent-vectors/

你可以從這裏獲得一些這篇博客的代碼:https://github.com/kvfrans/variational-autoencoder 和一個整理好的版本: https://jmetzen.github.io/2015-11-27/vae.html

 

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