無監督訓練用堆疊自編碼器是否落伍?ML博士對比了8個自編碼器
柏林工業大學深度學習方向博士生 Tilman Krokotsch 在多項任務中對比了 8 種自編碼器的性能。
深度學習中的自編碼器。圖源:https://debuggercafe.com/autoencoders-in-deep-learning/
目前,很多研究者仍在使用堆疊自編碼器進行無監督預訓練。柏林工業大學深度學習方向博士生 Tilman Krokotsch 對此感到疑惑:堆疊自編碼器難道不是算力低下時代訓練深度模型的變通方案嗎?現在算力相對充足了,為什么還要用?
于是,他決定在多項不同任務中對比原版深度自編碼器(AE)和堆疊自編碼器。
項目地址:https://github.com/tilman151/ae_bakeoff
Krokotsch 對比了原版深度自編碼器所有改變潛在空間行為方式或有可能提升下游任務性能的變體,不包括應用特定的損失(如圖像領域的 VGG19 損失)和編碼器與解碼器類型(如 LSTM vs. CNN)。最終,Krokotsch 選擇了以下八種自編碼器進行對比:
- 淺層自編碼器
- 深度自編碼器(原版 AE)
- 堆疊自編碼器
- 稀疏自編碼器
- 去噪自編碼器
- 變分自編碼器(VAE)
- Beta 變分自編碼器(beta-VAE)
- 向量量化變分自編碼器(vq-VAE)
Krokotsch 不僅介紹了這些自編碼器的獨特性,還在以下方面進行了對比:
- 重建質量
- 對來自潛在空間的樣本的解碼質量
- 潛在空間插值質量
- 利用 UMAP 可視化得到的潛在空間結構
- 利用重建誤差的異常檢測 ROC 曲線
- 擬合自編碼器特征的線性層的分類準確率
所有自編碼器均使用相同的簡單架構,該架構使用全連接編解碼器、批歸一化和 ReLU 激活函數,輸出層使用 sigmoid 激活函數。除了淺層自編碼器以外,所有自編碼器均具備三個編碼器和解碼器層。
潛在空間的維度和網絡參數量基本恒定。這意味著變分自編碼器比原版有更多參數,因為編碼器為維度為 n 的潛在空間生成 2n 個輸出。在測試過程中,每個自編碼器執行兩次訓練運行:一次潛在空間的維度為 20,一次維度為 2。第二次訓練的模型用于異常檢測,第一次的模型用于其他任務。
對比測試使用的數據集為 MNIST。Krokotsch 從訓練數據集中隨機采樣 5000 個樣本作為驗證集,將默認訓練 / 測試分割進一步劃分為訓練 / 驗證 / 測試分割。
接下來我們來看這些自編碼器變體及其對比情況。
「參賽選手」:8 個自編碼器
Krokotsch 介紹了這些自編碼器的工作原理及獨特性,并嘗試對其性能做出一些假設。
淺層自編碼器
淺層自編碼器算不上真的競爭對手,因為它的能力遠遠落后于其他變體。在這里,它作為基線存在。

上式為淺層自編碼器的重建公式,從中可以看出自編碼器如何以半數學的方式重建樣本 x。
淺層自編碼器的特點是編碼器和解碼器中只有一個層。它與 PCA 的區別是在編碼器中使用 ReLU 激活函數,在解碼器中使用 sigmoid 函數,因此它是非線性的。
一般情況下,自編碼器的默認重建損失是均方誤差。而 Krokotsch 使用的是二值交叉熵 (binary cross-entropy, BCE),因為它能在初步實驗中獲得更美觀的圖像。所有自編碼器均使用以下 BCE 版本:

其中 x^(i)_j 是第 i 個輸入圖像的第 j 個像素,x̂^(i)_j 是對應的重建。損失即匯總每張圖像再基于 batch 求平均。這一決策對于變分自編碼器非常重要。
深度自編碼器
深度自編碼器(原版自編碼器)是淺層自編碼器的擴大版。它們基本相同,只不過深度自編碼器擁有更多層。它們的重建公式是一樣的。
深度自編碼器的潛在空間沒有約束,因此應當能夠編碼最多信息。
堆疊自編碼器
堆疊自編碼器即通過僅訓練淺層自編碼器來得到深度自編碼器。只不過訓練方式不是端到端,而是逐層貪婪訓練:首先,以第一個編碼器和最后一個解碼器形成一個淺層自編碼器;訓練完這些層之后,使用編碼層編碼整個數據集;然后基于第二個編碼器和倒數第二個解碼器層形成另一個淺層自編碼器,使用編碼得到的數據集訓練第二個淺層自編碼器;重復這一過程,直到到達最內層。最終得到的深度自編碼器由許多個淺層自編碼器堆疊而成。
堆疊自編碼器與深度自編碼器只在訓練過程上存在區別,因此它們也具備相同的重建函數。堆疊自編碼器的潛在空間沒有約束,但是由于貪婪訓練,其編碼能力略差。
稀疏自編碼器
稀疏自編碼器在潛碼方面存在稀疏約束,潛碼中每個元素的活躍概率為 p。為此在訓練過程中需要為其添加輔助損失:

其中 z¯(i) 是潛碼中第 i 個元素基于 batch 的平均激活值。這一損失函數對應于 p 和 z¯(i) 二項式分布之間的 KL 散度 |z| 的總和。可能存在其他實現,可以滿足該稀疏約束。
為了使該稀疏損失成為可能,我們需要將潛碼的范圍縮放至 [0,1],以便將其理解為概率。這通過 sigmoid 激活函數完成,重建公式如下:

稀疏自編碼器的完整損失結合了重建損失和稀疏損失:

在所有實驗中,p 值設置為 0.25,β 值設置為 1。
去噪自編碼器
去噪自編碼器的潛在空間沒有約束,它旨在通過對輸入數據應用噪聲來學習更高效的編碼。去噪自編碼器并未將輸入數據直接饋入網絡,而是添加了高斯噪聲:

其中 clip 表示將輸入裁剪為 [0,1],標量 β 表示噪聲的方差。因此,去噪自編碼器的訓練方式是基于噪聲輸入數據重建干凈樣本,重建公式如下:

不過,噪聲輸入僅在訓練過程中使用。在評估該自編碼器時,使用的是原始輸入數據。去噪自編碼器使用的損失函數與之前的自編碼器相同。在所有實驗中, β 值被設置為 0.5。
變分自編碼器
理論上,變分自編碼器 (VAE) 與原版 AE 關聯不大。但在實踐中,其實現和訓練均很類似。VAE 將重建解釋為隨機過程,使之具備不確定性。編碼器不輸出潛碼,而是輸出表示潛碼概率分布的參數;然后,解碼器從這一分布中接收樣本。默認的分布族選擇是高斯 N(μ;diag(Σ))。其重建公式如下:

其中 enc_μ(x) 和 enc_Σ(x) 將 x 編碼為μ 和 Σ,兩個編碼器共享大部分參數。在實踐中,單個編碼器獲得兩個輸出層而不是一個。問題在于,從分布中采樣必須要具備梯度和從解碼器到編碼器的反向傳播。解決方法叫做「重參數化」,將來自標準高斯分布的樣本轉換為來自被 μ 和 Σ 參數化的高斯分布的樣本:

該公式的梯度與 μ 和 Σ 有關,也可以實現反向傳播。
變分自編碼器要求高斯分布類似于標準高斯,從而進一步約束其潛在空間。其分布參數接受 KL 散度的懲罰:

KL 散度基于 batch 求平均值。重建損失按照上文方式求平均,以保留重建損失和散度損失之間正確的比率。完整訓練損失如下:

我們盡量使編碼器輸出標準高斯,這樣就可以直接解碼來自標準高斯分布的樣本。這種無條件采樣是 VAE 的一種獨特屬性,使其成為類似 GAN 的生成模型。無條件采樣的公式如下:

Beta 變分自編碼器(beta-VAE)
beta-VAE 是 VAE 的泛化,只改變了重建損失和散度損失之間的比率。散度損失的影響因子用標量 β 來表示,因此損失函數如下所示:

β<1 放松了對潛在空間的約束,而 β>1 則加劇了這一約束。前者會得到更好的重建結果,后者則得到更好的無條件采樣。Krokotsc 在嚴格版本中使用了 β=2,在寬松版本中使用了 β=0.5。
向量量化變分自編碼器(vq-VAE)
vq-VAE 使用均勻的類別分布來生成潛碼。編碼器輸出中的每個元素都被該分布中的類別值取代,后者是其最近鄰。這是一種量化,意味著潛在空間不再是連續的,而是離散的。

類別本身可以通過將誤差平方和最小化為編碼器輸出來學得:

其中 z 表示編碼器的輸出,ẑ 表示對應的量化后潛碼,sg 表示停止梯度算子(stop gradient operator)。另外,編碼器輸出的編碼結果類似于通過誤差平方和得到的類別:

這叫做 commitment 損失。KL 散度損失并非必要,因為 KL 散度是均勻類別分布的的常量。將這種損失與重建損失結合起來,得到:

實驗中將 β 的值設置為 1。
由于 vq-VAE 是生成模型,我們也可以執行無條件采樣。
自編碼器「大亂斗」
重建質量
首先,我們來看每種自編碼器對輸入的重建質量。以下是不同自編碼器在 MNIST 測試集中 16 張圖像上的結果:


淺層自編碼器無法準確重建一些測試樣本。4 和 9 勉強可以辨認,一些數字則完全看不出來。其他自編碼器的效果要好一些,但也并不完美:去噪自編碼器會使一些細線消失;稀疏和堆疊自編碼器則在重建筆畫異常的數字(如 5 和第一個 9)。整體的重建結果都有一點模糊,這對于自編碼器而言是正常的。vq-VAE 的重建結果沒有那么模糊,其作者認為這是離散潛在空間的緣故。
不同自編碼器的重建質量區別不大。下表列舉了基于樣本集合的二值交叉熵平均值:

不出所料,表現最差的是淺層自編碼器,它缺乏捕捉 MNIST 結構的能力。原版自編碼器表現不錯,與稀疏自編碼器和 vq-VAE 名列前茅。但稀疏自編碼器和 vq-VAE 似乎并未經歷潛在空間約束,而 VAE 和 beta-VAE 由于潛在空間約束獲得了更高的誤差。此外,VAE 中的采樣過程引入了損害重建誤差的噪聲。
采樣
該試驗僅包括四個可執行無條件采樣的自編碼器:VAE、寬松和嚴格版本的 beta-VAE、vq-VAE。對每個自編碼器,采樣 16 個潛碼并解碼。對于 VAE 和 beta-VAE,從標準高斯分布中采樣。而 vq-VAE 的潛碼則從其學得類別中均勻采樣得到。

上圖中最有意義的生成樣本來自嚴格版 beta-VAE。這是因為其訓練重點放在了高斯先驗上,編碼器輸出最接近來自標準高斯的樣本,從而使得解碼器成功解碼采樣自真正標準高斯的潛碼。另外,其生成圖像的變化較小,例如右側數字既像 5 又像 6。
寬松版 beta-VAE 生成圖像則更多樣化,盡管可識別的圖像較少。標準 VAE 的表現在二者之間。令人略感失望的是 vq-VAE,它采樣的圖像完全不像 MNIST 數字。
插值
插值任務展示了潛在空間區域的密集程度。Krokotsch 從測試集中編碼了兩個圖像 2 和 7,并執行線性插值。然后將插值解碼以接收新圖像。如果來自插值潛碼的圖像能夠顯示有意義的數字,則類別區域之間的潛碼可被自編碼器高效利用。

對于所有 VAE 類型,Krokotsch 在瓶頸操作之前即執行插值。這意味著對于 VAE 和 beta-VAE,先插值高斯參數,再進行采樣;對于 vq-VAE,則先插值再量化。
從上圖中可以看到 VAE 和 beta-VAE 可以生成相對有意義的插值。其他自編碼器則完全不行。
潛在空間結構
Krokotsch 利用 UMAP 算法可視化潛在空間結構,該算法可以將潛在空間縮減至二維,并保留潛碼的近鄰。下圖展示了自編碼器每個自編碼器潛在空間的散點圖,每個點表示測試集中一個圖像的潛碼,顏色表示圖像中的數字。

這些圖之間存在一些明顯的相似性。首先,原版、堆疊、稀疏、去噪自編碼器和 vq-VAE 很相似。0(藍色)、1(橙色)、2(綠色)和 6(粉色)的簇總能得到很好地分割,因此它們與其他數字看起來區別較大。還有 4-7-9 和 3-5-8 的簇,這表明這些數字之間存在連接,如在 3 上添加兩個直線可以得到 8。這些自編碼器可以編碼數字之間的結構相似性。
但淺層自編碼器很難將數字分類為簇。VAE 和 beta-VAE 與其他不同,我們可以從中看到散度損失的影響。
分類
潛在空間圖表明很多自編碼器擅長將 MNIST 數字分簇,盡管它們并未接收到任何標簽。那么如何利用這一點來執行 MNIST 數字分類呢?
Krokotsch 使用 20 維潛碼擬合稠密分類層,該層僅在來自訓練集的 550 個標注樣本訓練。也就是說,使用這些自編碼器做半監督學習。從頭訓練原版編碼器和分類層獲得的準確率是 0.4364。下表展示了這些自編碼器的改進效果:

幾乎所有自編碼器都基于基線有所改進,除了稀疏自編碼器。去噪自編碼器獲得最優結果,其次是原版自編碼器和 vq-VAE。去噪自編碼器添加的輸入噪聲似乎產生了最適合分類任務的特征。
最有趣的一點是,即使淺層自編碼器也能稍微提升準確率,即使它只有一層,參數也更少。這再一次表明,智能數據使用往往勝過大模型。
VAE 和 beta-VAE 再一次表明,散度損失對潛在空間的約束。稀疏自編碼器的結果比基線還差,似乎是因為稀疏特征完全不適合用于分類 MNIST 數字。對于其效果,還需要在其他數據集上再進行測試。
異常檢測
使用自編碼器執行異常檢測任務相對直接。使用訓練好的模型,為測試樣本計算重建損失,得到異常分數。如果樣本的重建結果較好,則它可能類似于訓練數據;如果重建結果較差,則樣本被認為是異常值。自編碼器可以利用訓練數據之間的關聯來學習有效的低維表示。只要這些關聯出現,則測試樣本就可以得到不錯地重建。反之,則自編碼器無法進行很好地重建。
該任務的一大挑戰是找出異常分數的最優閾值。下圖展示了 ROC 曲線圖和曲線下面積:

淺層自編碼器以 0.91 的 AUC 將其他自編碼器甩在身后,緊隨其后的是堆疊自編碼器。而且對于不同數字和潛在空間維度而言,不同自編碼器的排序是不變的。
為什么這兩個在其他任務中拖后腿的自編碼器如此擅長異常檢測呢?原因似乎在于其他任務依賴潛在空間的泛化能力。而異常檢測無需泛化,至少不需要太好的泛化能力。
結論
經過對比實驗后,Krokotsch 并未找出自編碼器中的王者,他認為選擇哪種自編碼器取決于任務本身。想要基于噪聲生成人臉?使用變分自編碼器。圖像過于模糊?試試 vq-VAE。分類任務?選擇去噪自編碼器。如果要做異常檢測任務,或許可以嘗試淺層自編碼器或 PCA。有時,少即是多。