變分自編碼器VAE:一步到位的聚類方案

PaperWeekly發表於2018-09-18
由於 VAE 中既有編碼器又有解碼器(生成器),同時隱變數分佈又被近似編碼為標準正態分佈,因此 VAE 既是一個生成模型,又是一個特徵提取器。

在影像領域中,由於 VAE 生成的圖片偏模糊,因此大家通常更關心 VAE 作為影像特徵提取器的作用。提取特徵都是為了下一步的任務準備的,而下一步的任務可能有很多,比如分類、聚類等。本文來關心“聚類”這個任務。

一般來說,用 AE 或者 VAE 做聚類都是分步來進行的,即先訓練一個普通的 VAE,然後得到原始資料的隱變數,接著對隱變數做一個 K-Means 或 GMM 之類的。但是這樣的思路的整體感顯然不夠,而且聚類方法的選擇也讓我們糾結。

本文介紹基於 VAE 的一個“一步到位”聚類思路,它同時允許我們完成無監督地完成聚類和條件生成。

理論

一般框架

回顧 VAE 的 loss(如果沒印象請參考再談變分自編碼器VAE:從貝葉斯觀點出發):

變分自編碼器VAE:一步到位的聚類方案

通常來說,我們會假設 q(z) 是標準正態分佈,p(z|x),q(x|z) 是條件正態分佈,然後代入計算,就得到了普通的 VAE 的 loss。

然而,也沒有誰規定隱變數一定是連續變數吧?這裡我們就將隱變數定為 (z,y),其中 z 是一個連續變數,代表編碼向量;y 是離散的變數,代表類別。直接把 (1) 中的 z 替換為 (z,y),就得到:

變分自編碼器VAE:一步到位的聚類方案

這就是用來做聚類的 VAE 的 loss 了。

分步假設

啥?就完事了?呃,是的,如果只考慮一般化的框架,(2) 確實就完事了。 

不過落實到實踐中,(2) 可以有很多不同的實踐方案,這裡介紹比較簡單的一種。首先我們要明確,在 (2 )中,我們只知道 p̃(x)(通過一批資料給出的經驗分佈),其他都是沒有明確下來的。於是為了求解 (2),我們需要設定一些形式。一種選取方案為:

變分自編碼器VAE:一步到位的聚類方案

代入 (2) 得到:

變分自編碼器VAE:一步到位的聚類方案

其實 (4) 式還是相當直觀的,它分佈描述了編碼和生成過程:

1. 從原始資料中取樣到 x,然後通過 p(z|x) 可以得到編碼特徵 z,然後通過分類器 p(y|z) 對編碼特徵進行分類,從而得到類別;

2. 從分佈 q(y) 中選取一個類別 y,然後從分佈 q(z|y) 中選取一個隨機隱變數 z,再通過生成器 q(x|z) 解碼為原始樣本。

具體模型

(4) 式其實已經很具體了,我們只需要沿用以往 VAE 的做法:p(z|x) 一般假設為均值為 μ(x) 方差為變分自編碼器VAE:一步到位的聚類方案的正態分佈,q(x|z) 一般假設為均值為 G(z) 方差為常數的正態分佈(等價於用 MSE 作為 loss),q(z|y) 可以假設為均值為 μy 方差為 1 的正態分佈,至於剩下的 q(y),p(y|z),q(y) 可以假設為均勻分佈(它就是個常數),也就是希望每個類大致均衡,而 p(y|z) 是對隱變數的分類器,隨便用個 softmax 的網路就可以擬合了。 

最後,可以形象地將 (4) 改寫為:

變分自編碼器VAE:一步到位的聚類方案

其中 z∼p(z|x) 是重引數操作,而方括號中的三項 loss,各有各的含義:

1. −log q(x|z) 希望重構誤差越小越好,也就是 z 儘量保留完整的資訊;

2.變分自編碼器VAE:一步到位的聚類方案希望 z 能儘量對齊某個類別的“專屬”的正態分佈,就是這一步起到聚類的作用;

3. KL(p(y|z)‖q(y)) 希望每個類的分佈儘量均衡,不會發生兩個幾乎重合的情況(坍縮為一個類)。當然,有時候可能不需要這個先驗要求,那就可以去掉這一項。

實驗

實驗程式碼自然是 Keras 完成的了,在 MNIST 和 Fashion-MNIST 上做了實驗,表現都還可以。實驗環境:Keras 2.2 + TensorFlow 1.8 + Python 2.7。

程式碼實現

程式碼位於:

https://github.com/bojone/vae/blob/master/vae_keras_cluster.py 

其實註釋應該比較清楚了,而且相比普通的 VAE 改動不大。可能稍微有難度的是變分自編碼器VAE:一步到位的聚類方案這個怎麼實現。因為 y 是離散的,所以事實上這就是一個矩陣乘法(相乘然後對某個公共變數求和,就是矩陣乘法的一般形式),用 K.batch_dot 實現。 

其他的話,讀者應該先弄清楚普通的 VAE 實現過程,然後再看本文的內容和程式碼,不然估計是一臉懵的。

MNIST

這裡是 MNIST 的實驗結果圖示,包括類內樣本圖示和按類取樣圖示。最後還簡單估算了一下,以每一類對應的數目最多的那個真實標籤為類標籤的話,最終的 test 準確率大約有 84.5%,對比這篇文章 Unsupervised Deep Embedding for Clustering Analysis [1] 的結果(最高也是 84% 左右),感覺應該很不錯了。 

聚類圖示

變分自編碼器VAE:一步到位的聚類方案

按類取樣

變分自編碼器VAE:一步到位的聚類方案

Fashion-MNIST

這裡是 Fashion-MNIST [2] 的實驗結果圖示,包括類內樣本圖示和按類取樣圖示,最終的 test 準確率大約有 60.6%。 

聚類圖示

變分自編碼器VAE:一步到位的聚類方案

按類取樣

變分自編碼器VAE:一步到位的聚類方案

總結

文章簡單地實現了一下基於 VAE 的聚類演算法,演算法的特點就是一步到位,結合“編碼”、“聚類”和“生成”三個任務同時完成,思想是對 VAE 的 loss 的一般化。

感覺還有一定的提升空間,比如式 (4) 只是式 (2) 的一個例子,還可以考慮更加一般的情況。程式碼中的 encoder 和 decoder 也都沒有經過仔細調優,僅僅是驗證想法所用。

相關文章