2021李宏毅機器學習筆記--19 unsupervised learning--Deep Auto-encoder
- 摘要
- 一、Auto-encoder簡介
- 二、與PCA的聯系
- 三、Deep Auto-encoder
- 四、應用
-
- 4.1、Text Retrieval文字檢索
- 4.2、Similar Image Search相似圖像搜尋
- 4.3、Pre-training DNN
- 4.4、CNN as Encoder
-
- 4.4.1、去池化層(Unpooling)
- 4.4.2、去卷積層(Deconvolution)
- 4.5、 Auto-encoder
-
- 4.5.1、De-noising Auto-encoder
- 4.5.2、Contractive Auto-encoder
- 4.5.3、Seq2Seq Auto-encoder
- 五、Generate
- 總結
摘要
文本介紹了自編碼器的基本思想,自編碼器就是将資料進行自我壓縮和解碼的過程。并且介紹了與PCA(主成分分析)的聯系,對資料做PCA以後可以得到資料的主成分資訊,這部分資訊可以很好的還原原資料,對應到自編碼器其實就是編碼和解碼的過程。自編碼器可以被應用于文字檢索,每一篇文章都表示成向量空間中的一個向量,把要查詢的詞彙也變成一個點,然後計算點之間的餘弦相似度可以檢索文章。自編碼器也可以用于相似圖像檢索,先用自編碼器對圖像進行降維和特征提取,然後再計算所要查詢的圖像的像素與圖庫中的像素的相似度進行檢索。當有大量沒有标注的資料時,可以用自編碼器做預訓練來找到比較好的參數初始化值。CNN用于圖像處理的思想就是交替使用卷積層和池化層,讓圖像越來越小,類似于編碼,那麼解碼的過程就是去卷積層和去池化層。
一、Auto-encoder簡介
Auto-encoder本質上就是一個自我壓縮和解壓的過程,我們想要擷取壓縮後的code,它代表了對原始資料的某種緊湊精簡的有效表達,即降維結果,這個過程中我們需要:
1、Encoder(編碼器),它可以把原先的圖像壓縮成更低次元的向量
2、Decoder(解碼器),它可以把壓縮後的向量還原成圖像

注意到,Encoder和Decoder都是Unsupervised Learning,由于code是未知的,對Encoder來說,我們手中的資料隻能提供圖像作為NN的input,卻不能提供code作為output;對Decoder來說,我們隻能提供圖像作為NN的output,卻不能提供code作為input。
是以Encoder和Decoder單獨拿出一個都無法進行訓練,我們需要把它們連接配接起來,這樣整個神經網絡的輸入和輸出都是我們已有的圖像資料,就可以同時對Encoder和Decoder進行訓練,而降維後的編碼結果就可以從最中間的那層hidden layer中擷取
二、與PCA的聯系
主成分分析算法(PCA)是最常用的線性降維方法,它的目标是通過某種線性投影,将高維的資料映射到低維的空間中,并期望在所投影的次元上資料的資訊量最大(方差最大),以此使用較少的資料次元,同時保留住較多的原資料點的特性。
實際上PCA用到的思想與之非常類似,PCA的過程本質上就是按元件拆分,再按元件重構的過程。
在PCA中,我們先把均一化後的x根據元件W分解到更低次元的c ,然後再将元件權重乘上元件的反置 W T W^T WT得到重組後的 x ^ \widehat x x
,同樣我們期望重構後的 x ^ \widehat x x
與原始的x越接近越好。
如果把這個過程看作是神經網絡,那麼原始的x就是input layer,重構 x ^ \widehat x x
就是output layer,中間元件分解權重c就是hidden layer,在PCA中它是linear的,我們通常又叫它瓶頸層(Bottleneck layer)
由于經過元件分解降維後的c,維數要遠比輸入輸出層來得低,是以hidden layer實際上非常窄,因而有瓶頸層的稱呼
對比于Auto-encoder,從input layer到hidden layer的按元件分解實際上就是編碼(encode)過程,從hidden layer到output layer按元件重構實際上就是解碼(decode)的過程。
三、Deep Auto-encoder
那麼實際上,可不可以用更多層hidden layer呢?肯定是可以的,對deep的自編碼器來說,實際上就是通過多級編碼降維,再經過多級解碼還原的過程。
1、從input layer到bottleneck layer的部分都屬于Encoder
2、從bottleneck layer到output layer的部分都屬于ecoder
3、bottleneck layer的output就是自編碼結果code
注意到,如果按照PCA的思路,則Encoder的參數 W i W_i Wi需要和Decoder的參數 W i T W_i^T WiT保持一緻的對應關系,這可以通過給兩者相同的初始值并設定同樣的更新過程得到,這樣做的好處是,可以節省一半的參數,降低overfitting的機率
但這件事情并不是必要的,實際操作的時候,你完全可以對神經網絡進行直接訓練而不用保持編碼器和解碼器的參數一緻
下圖給出了Hinton分别采用PCA和Deep Auto-encoder對手寫數字進行編碼解碼後的結果,從784維降到30維,可以看出,Deep的自編碼器還原效果比PCA要更好
如果将其降到二維平面做可視化,不同顔色代表不同的數字,可以看到
1、通過PCA降維得到的編碼結果中,不同顔色代表的數字被混雜在一起
2、通過Deep Auto-encoder降維得到的編碼結果中,不同顔色代表的數字被分散成一群一群的
四、應用
4.1、Text Retrieval文字檢索
Auto-encoder也可以被用在文字處理上
比如我們要做文字檢索,很簡單的一個做法是Vector Space Model,把每一篇文章都表示成空間中的一個vector
假設查詢者輸入了某個詞彙,那我們就把該查詢詞彙也變成空間中的一個點,并計算query和每一篇document之間的内積(inner product)或餘弦相似度(cos-similarity)
注:餘弦相似度有均一化的效果,可能會得到更好的結果
餘弦相似度的算法:向量空間中兩個向量夾角的餘弦值
餘弦值越接近1,表明夾角越接近0°,表明兩個向量越相似
下圖中跟query向量最接近的幾個向量的cosine-similarity是最大的,于是可以從這幾篇文章中去檢索
實際上這個模型的好壞,就取決于從document轉化而來的vector的好壞,它是否能夠充分表達文章資訊。
最簡單的vector表示方法是Bag-of-word,維數等于所有詞彙的總數,某一維等于1則表示該詞彙在這篇文章中出現,此外還可以根據詞彙的重要性将其權重;但這個模型是非常脆弱的,對它來說每個詞彙都是互相獨立的,無法展現出詞彙之間的語義(semantic)
雖然Bag-of-word不能直接用于表示文章,但我們可以把它作為Auto-encoder的input,通過降維來抽取有效資訊,以擷取所需的vector
同樣為了可視化,這裡将Bag-of-word降維到二維平面上,下圖中每個點都代表一篇文章,不同顔色則代表不同的文章類型
如果使用者做查詢,就把查詢的語句用相同的方式映射到該二維平面上,并找出屬于同一類别的所有文章即可
在矩陣分解(Matrix Factorization)中,我們介紹了LSA算法,它可以用來尋找每個詞彙和每篇文章背後的隐藏關系(vector),如果在這裡我們采用LSA,并使用二維latent vector來表示每篇文章,得到的可視化結果如上圖右下角所示,可見效果并沒有Auto-encoder好。
4.2、Similar Image Search相似圖像搜尋
Auto-encoder同樣可以被用在圖像檢索上
以圖找圖最簡單的做法就是直接對輸入的圖檔與資料庫中的圖檔計算pixel的相似度,并挑出最像的圖檔,但這種方法的效果是不好的,因為單純的pixel所能夠表達的資訊太少了
我們需要使用Auto-encoder對圖像進行降維和特征提取,并在編碼得到的code所在空間做檢索
下圖展示了Encoder的過程,并給出了原圖與Decoder後的圖像對比。
這麼做的好處如下:
1、Auto-encoder可以通過降維提取出一張圖像中最有用的特征資訊,包括pixel與pixel之間的關系
2、降維之後資料的size變小了,這意味着模型所需的參數也變少了,同樣的資料量對參數更少的模型來說,可以訓練出更精确的結果,一定程度上避免了過拟合的發生
3、Auto-encoder是一個無監督學習的方法,資料不需要人工打上标簽,這意味着我們隻需簡單處理就可以獲得大量的可用資料。
下圖給出了分别以原圖的pixel計算相似度和以auto-encoder後的code計算相似度的兩種方法在圖像檢索上的結果,可以看到,通過pixel檢索到的圖像會出現很多奇怪的物品,而通過code檢索到的圖像則都是人臉
可能有些人臉在原圖的pixel上看起來并不像,但把它們投影到256維的空間中卻是相像的,可能在投影空間中某一維就代表了人臉的特征,是以能夠被檢索出來
4.3、Pre-training DNN
在訓練神經網絡的時候,我們一般都會對如何初始化參數比較困擾,預訓練(pre-training)是一種尋找比較好的參數初始化值的方法,而我們可以用Auto-encoder來做pre-training
以MNIST資料集(手寫體數字的圖檔資料集)為例,我們對每層hidden layer都做一次auto-encoder,使每一層都能夠提取到上一層最佳的特征向量
為了友善表述,這裡用x − z − x來表示一個自編碼器,其中x 表述輸入輸出層的維數,z表示隐藏層的維數。
1、首先使input通過一個784 − 1000 − 784 的自編碼器,當該自編碼器訓練穩定後,就把參數 W 1 W^1 W1固定住,然後将資料集中所有784維的圖像都轉化為1000維的vector
注意:這裡做的不是降維而是升維,當編碼後的維數比輸入維數要高時,需要注意可能會出現編碼前後原封不動的情況,為此需要額外加一個正則項,比如L1 regularization,強迫使code的分布是分散的。
2、接下來再讓這些1000維的vector通過一個1000 − 1000 − 1000 的編碼器,當其訓練穩定後,再把參數 W 2 W^2 W2固定住,對資料集再做一次轉換
3、接下來再用轉換後的資料集去訓練第三個1000 − 500 − 1000 的自編碼器,訓練穩定後固定 W 3 W^3 W3,資料集再次更新轉化為500維
4、此時三個隐藏層的參數 W 1 W^1 W1、 W 2 W^2 W2、 W 3 W^3 W3就是訓練整個神經網絡時的參數初始值
5、然後随機初始化最後一個隐藏層到輸出層之間的參數 W 4 W^4 W4
6、再用反向傳播去調整一遍參數,因為 W 1 W^1 W1、 W 2 W^2 W2、 W 3 W^3 W3都已經是很好的參數值了,這裡隻是做微調,這個步驟也是以得名為Find-tune
由于現在訓練機器的條件比以往更好,是以pre-training并不是必要的,但它也有自己的優勢
如果你隻有大量的unlabeled data和少量的labeled data,那你可以先用這些unlabeled data把 W 1 W^1 W1、 W 2 W^2 W2、 W 3 W^3 W3先初始化好,最後再用labeled data去微調 W 1 W^1 W1~ W 4 W^4 W4即可
是以pre-training在有大量unlabeled data的場景下(如半監督學習)是比較有用的
4.4、CNN as Encoder
處理圖像通常都會用卷積神經網絡CNN,它的基本思想是交替使用卷積層和池化層,讓圖像越來越小,最終展平,這個過程跟Encoder編碼的過程其實是類似的
理論上要實作自編碼器,Decoder隻需要做跟Encoder相反的事即可,那對CNN來說,解碼的過程也就變成了交替使用去卷積層和去池化層即可
回顧一下去卷積層(Deconvolution)和去池化層(Unpooling)
4.4.1、去池化層(Unpooling)
做pooling的時候,假如得到一個4×4的matrix,就把每4個pixel分為一組,從每組中挑一個最大的留下,此時圖像就變成了原來的四分之一大小
如果還要做Unpooling,就需要提前記錄pooling所挑選的pixel在原圖中的位置,下圖中用灰色方框标注
然後做Unpooling,就要把目前的matrix放大到原來的四倍,也就是把2×2 matrix裡的pixel按照原先記錄的位置插入放大後的4×4 matrix中,其餘項補0即可
當然這不是唯一的做法,在Keras中,pooling并沒有記錄原先的位置,做Unpooling的時候就是直接把pixel的值複制四份填充到擴大後的matrix裡即可。
4.4.2、去卷積層(Deconvolution)
實際上,Deconvolution就是convolution
這裡以一維的卷積為例,假設輸入是5維,過濾器(filter)的大小是3
卷積的過程就是每三個相鄰的點通過過濾器生成一個新的點,如下圖左側所示
在你的想象中,去卷積的過程應該是每個點都生成三個點,不同的點對生成同一個點的貢獻值相加;但實際上,這個過程就相當于在周圍補0之後再次做卷積,如下圖右側所示,兩個過程是等價的
卷積和去卷積的過程中,不同點在于,去卷積需要補零且過濾器的weight與卷積是相反的:
1、在卷積過程中,依次是橙線、藍線、綠線
2、在去卷積過程中,依次是綠線、藍線、橙線
是以在實踐中,做去卷積的時候直接對模型加卷積層即可
4.5、 Auto-encoder
4.5.1、De-noising Auto-encoder
去噪自編碼器的基本思想是,把輸入的x加上一些噪聲(noise)變成x ′ ,再對x ′依次做編碼(encode)和解碼(decode),得到還原後的y
值得注意的是,一般的自編碼器都是讓輸入輸出盡可能接近,但在去噪自編碼器中,我們的目标是讓解碼後的y 與加噪聲之前的x越接近越好
這種方法可以增加系統的魯棒性,因為此時的編碼器Encoder不僅僅是在學習如何做編碼,它還學習到了如何過濾掉噪聲這件事情
4.5.2、Contractive Auto-encoder
收縮自動編碼器的基本思想是,在做encode編碼的時候,要加上一個限制,它可以使得:input的變化對編碼後得到的code的影響最小化
這個描述跟去噪自編碼器很像,隻不過去噪自編碼器的重點在于加了噪聲之後依舊可以還原回原先的輸入,而收縮自動編碼器的重點在于加了噪聲之後能夠保持編碼結果不變
4.5.3、Seq2Seq Auto-encoder
在之前介紹的自編碼器中,輸入都是一個固定長度的vector,但類似文章、語音等資訊實際上不應該單純被表示為vector,那會丢失很多前後聯系的資訊
Seq2Seq就是為了解決這個問題提出的,它的輸入和輸出都可以是不定長序列。
五、Generate
在用自編碼器的時候,通常是擷取Encoder之後的code作為降維結果,但實際上Decoder也是有作用的,我們可以拿它來生成新的東西
以MNIST為例,訓練好編碼器之後,取出其中的Decoder,輸入一個随機的code,就可以生成一張圖像
假設将28×28維的圖像通過一層2維的hidden layer投影到二維平面上,得到的結果如下所示,不同顔色的點代表不同的數字,然後在紅色方框中,等間隔的挑選二維向量丢進Decoder中,就會生成許多數字的圖像。
此外,我們還可以對code加L2 regularization,以限制code分布的範圍集中在0附近,此時就可以直接以0為中心去随機采取樣本點,再通過Decoder生成圖像
觀察生成的數字圖像,可以發現橫軸的次元表示是否含有圓圈,縱軸的次元表示是否傾斜
總結
自編碼器包括兩個部分:encoder(編碼器)将高維的資料降維編碼和decoder(解碼器)将之前降維後的資料進行解碼恢複原來的資料。那麼我們為什麼要對資料進行降維?一個是我們很難對高維的資料有直覺的認識,降維後的資料保持資料點之間的關系,我們可以進行肉眼觀察,還有一個原因是降維後的資料即儲存了資料的主要資訊,又删除了大量的備援資訊,可以用于簡化機器學習模型的訓練,将訓練效率大大提升。除了在文章檢索和圖像檢索上,比較常見的可能是用于圖像去噪,對于一些比較模糊的照片,其實就是噪聲比較多,自編碼器可以用于去噪,然後輸出比較清晰的圖像。