變分自編碼器(Variational Autoencoder)

最近想了解一下生成模型(generative model),這兩三天看了很多關於變分自編碼器(Variational Autoencoder)的資料,發現VAE實現起來比較簡單,但是因爲沒什麼概率圖模型的基礎,對於它的理論感覺理解起來很費力,所以開始在空閒的時候看Coursera上面那門Koller的概率圖模型的公開課

個人覺得Variational Autoencoder比較有用的資料:
1. Oliver Dürr的VAE的PPT(非常推薦,講得很清晰)
2. Jaan Altossar 的VAE Tutorial

1. 結構

這裏寫圖片描述

這樣來看,變分子編碼器的結構和傳統自編碼器的結構最大的區別就是變分子編碼器的encoder和decoder輸出的都是概率密度函數的參數。對於z而言已經假設它符合標準正態分佈,因此encoder network的輸出形狀爲(Batch_size, 2*latent_dims),其中一半表示latent variable z的均值,另一半表示方差。

需要注意

實際編程時,通常讓encoder輸出z_log_sigma_sq=lnσ2 ,而不是直接輸出σ 。因爲σ 取值只能爲正數,log_sigma_sq 取值爲R,更適合作爲網絡的輸出。
或者也可以用softplus激活函數,讓網絡輸出處在0-1區間,來表示σ

2. Reparameterization

在得到了z的概率密度函數參數之後,就可以對z進行採樣,然而隨機採樣的話就無法使用誤差反向傳遞來訓練網絡了,因此這裏使用了Reparameterization Trick來得到z,即:

zi=μi+σi×ε

其中,ε 符合標準正態分佈。
#定義計算圖
...
eps_placeholder = tf.placeholder("float",shape=[None, latent_dims])
...
z_mean, z_log_sigma_sq = encoder_network()
z = tf.add(z_mean, tf.multiply(tf.sqrt(tf.exp(z_log_sigma_sq)),eps_placeholder))
...
# 訓練
eps = np.random.normal(loc=0.0,scale=1.0,size=(batch_size,latent_dims])
# feed_dict={..., eps_placeholder:eps...}

3. 關於Decoder的輸出

這裏應該分爲兩種情況,一種是輸入x爲二值型的,另一種是輸入x爲連續的。

3.1 x爲二值型

在Github上面有不少VAE的實現都是使用MNIST作爲例子,然後在輸入時可以把圖片轉換爲二值的。
對於二值型的樣本,decoder network的輸出就認爲是符合伯努利分佈的,輸出的就是值爲1的概率,因此應該使用sigmoid函數,讓輸出在0-1區間內。

3.2 x爲連續的

對於連續的樣本,decoder network的輸出認爲是符合正態分佈的,輸出應該像z一樣一半是均值,一般是方差,但在實現代碼時,通常只輸出均值。
如果輸入樣本是經過歸一化,取值在0-1區間,decoder network的輸出也應該用sigmoid函數。

4. 目標函數

目標函數分爲兩部分,一部分爲Q(z|x)和標準正態分佈的KL散度,另一部分可看作輸入x和重構得到的x˜ 的差距。

4.1 Q(z|x)和標準正態分佈的KL散度

這裏寫圖片描述

4.2 輸入x和重構得到的x˜ 的差距

對於二值型的,這一部分可以使用交叉熵。
對於連續型的,這一部分爲Squared Error。

發佈了31 篇原創文章 · 獲贊 26 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章