基於TensorFlow的變分自編碼器實現
變分自編碼器(VAEs)是學習低維數據表示的強大模型。TensorFlow的分發包提供了一種簡單的方法來實現不同類型的VAE。在這篇文章中,我將引導你完成在MNIST上訓練簡單VAE的步驟,主要側重於實戰。
1.定義網路:
VAE由三部分組成:編碼器q(z|x),先驗p(z),解碼器p(x|z)。
編碼器將圖像映射到針對該圖像的代碼的分布上。這種分布也被稱為後驗(posterior),因為它反映了我們關於代碼應該用於給定圖像之後的準確度。
先驗(prior)是固定的,上面我們還定義了我們期望的代碼塊分布。這對VAE可以使用的代碼塊提供了一個非常彈性的選擇空間。它通常只是一個零均值和單位方差的正態分布。
解碼器需要編寫一個代碼塊並將其映射回合理的圖像分布。它允許我們重建圖像,或為我們選擇的任何代碼塊生成新圖像。
在這裡,我們對數據使用伯努利分布,將像素建模為二進位值。根據數據的類型和領域,您可能需要以不同的方式對其進行建模,例如再次以正態分布的形式進行建模。
該tfd.Independent(..., 2)告訴TensorFlow,內部兩個尺寸——(寬度和高度)。在我們的例子中,屬於同一個數據點,即使他們有獨立的參數。這使我們能夠評估分布下圖像的概率,而不僅僅是單個像素。
2.重新使用模型
我們希望使用解碼器網路兩次,計算下一節中描述的重構損失,以及一些隨機採樣的可視化代碼塊。
在TensorFlow中,如果您調用兩次網路功能,它將創建兩個獨立的網路。TensorFlow模板允許您打包一個函數,以便多次調用它將重用相同的網路參數。
之前沒有可訓練的參數,所以我們不需要將其包裝到模板中。
3.定義損失
我們希望找到為我們的數據集分配最高可能性的網路參數。然而,數據點的可能性取決於最好的代碼塊,這點在訓練中是我們不知道。
代替的,我們將使用(ELBO)對數據可能性進行近似訓練。
這裡的重要細節是,ELBO僅使用給定我們當前對其代碼塊的估計的數據點的可能性,我們可以對其進行抽樣。
一個直觀的解釋是,最大化ELBO可以最大限度地提供給定當前代碼的數據的可能性,同時鼓勵代碼接近我們先前的代碼應該是什麼樣子的信念。
4.運行訓練
我們使用梯度下降來最大化ELBO。這是一個非常可行的方案,因為採樣操作是在內部使用重新參數化技巧來實現的,所以TensorFlow可以通過它們反向傳播。
而且,我們從之前的樣本中抽取一些隨機代碼來可視化VAE學到的相應圖像。這就是上面我們使用的原因,讓我們再次調用解碼器網路。
最後,我們載入數據並創建一個會話來運行訓練:
如果你想玩代碼,看看完整的代碼示例,它也包含在這篇文章中其他省略的繪圖,以及前幾個訓練階段的解碼樣本。
正如你所看到的,潛在的空間很快就會被分成幾組不同的數字。如果您為代碼塊和較大的網路使用更多維度,您還將看到生成的圖像變得越來越清晰。
5.結論
我們已經學會在TensorFlow中建立一個VAE,並在MNIST數字上訓練它。下一步,您可以自己運行代碼並對其進行擴展,例如使用CNN編碼器和解碼器。


TAG:AI講堂 |