深度學習第51講:自編碼器(AutoEncoder)及其keras實現

2021-03-06 機器學習實驗室

     從本講開始,筆者將花一些時間和大家一起學習深度學習中的無監督模型。從現有情況來看,無監督學習很有可能是一把決定深度學習未來發展方向的鑰匙,在缺乏高質量打標數據的監督機器學習時代,若是能在無監督學習方向上有所突破對於未來深度學習的發展意義重大。從自編碼器到生成對抗網絡,筆者將和大家一起來探索深度學習中的無監督學習。

自編碼器

     所謂自編碼器(Autoencoder,AE),就是一種利用反向傳播算法使得輸出值等於輸入值的神經網絡,它現將輸入壓縮成潛在空間表徵,然後將這種表徵重構為輸出。所以,從本質上來講,自編碼器是一種數據壓縮算法,其壓縮和解壓縮算法都是通過神經網絡來實現的。自編碼器有如下三個特點:

數據相關性。就是指自編碼器只能壓縮與自己此前訓練數據類似的數據,比如說我們使用mnist訓練出來的自編碼器用來壓縮人臉圖片,效果肯定會很差。

數據有損性。自編碼器在解壓時得到的輸出與原始輸入相比會有信息損失,所以自編碼器是一種數據有損的壓縮算法。

自動學習性。自動編碼器是從數據樣本中自動學習的,這意味著很容易對指定類的輸入訓練出一種特定的編碼器,而不需要完成任何新工作。

     構建一個自編碼器需要兩部分:編碼器(Encoder)和解碼器(Decoder)。編碼器將輸入壓縮為潛在空間表徵,可以用函數f(x)來表示,解碼器將潛在空間表徵重構為輸出,可以用函數g(x)來表示,編碼函數f(x)和解碼函數g(x)都是神經網絡模型。

     所以,我們大致搞清楚了自編碼器是一種讓輸入等於輸出的算法。但僅僅如此嗎?當然不是,如果一個算法只是為了讓輸入等於輸出,那這個算法意義肯定不大,自編碼器的核心價值在於經編碼器壓縮後的潛在空間表徵。上面我們提到自編碼器是一種數據有損的壓縮算法,經過這種有損的數據壓縮,我們可以學習到輸入數據種最重要的特徵。

     雖然自編碼器對於我們是個新概念,但是其內容本身非常簡單。在後面的keras實現中大家可以看到如何用幾行代碼搭建和訓練一個自編碼器。那麼重要的問題來了,自編碼器這樣的自我學習模型到底有什麼用呢?這個問題的答案關乎無監督學習在深度學習領域的價值,所以還是非常有必要說一下的。自編碼器吸引了一大批研究和關注的主要原因之一是很長時間一段以來它被認為是解決無監督學習的可能方案,即大家覺得自編碼器可以在沒有標籤的時候學習到數據的有用表達。但就具體應用層面上而言,自編碼器通常有兩個方面的應用:一是數據去噪,二是為進行可視化而降維。自編碼器在適當的維度和係數約束下可以學習到比PCA等技術更有意義的數據映射。

自編碼器的keras實現

     原始的自編碼器實現起來非常容易,我們來看一下如何使用keras來實現一個簡易的自編碼器。使用全連接網絡作為編碼和解碼器:

from keras.layers import Input, Dense
from keras.models import Model
import warningswarnings.filterwarnings('ignore')
encoding_dim = 32  
input_img = Input(shape=(784,))
encoded = Dense(encoding_dim, activation='relu')(input_img)
decoded = Dense(784, activation='sigmoid')(encoded)
autoencoder = Model(input=input_img, output=decoded)

     模型概要如下:

     我們也可以把編碼器和解碼器當作單獨的模型來使用:

encoder = Model(input=input_img, output=encoded)
encoded_input = Input(shape=(encoding_dim,))decoder_layer = autoencoder.layers[-1]decoder = Model(input=encoded_input, output=decoder_layer(encoded_input))

對自編碼器模型進行編譯並使用mnist數據進行訓練:

autoencoder.compile(optimizer='adadelta', loss='binary_crossentropy')
from keras.datasets import mnist
import numpy as np(x_train, _), (x_test, _) = mnist.load_data()x_train = x_train.astype('float32') / 255.
x_test = x_test.astype('float32') / 255.
x_train = x_train.reshape((len(x_train), np.prod(x_train.shape[1:])))x_test = x_test.reshape((len(x_test), np.prod(x_test.shape[1:])))
autoencoder.fit(x_train, x_train,                nb_epoch=50,                batch_size=256,                shuffle=True,                validation_data=(x_test, x_test))

     50輪訓練之後的損失降低到0.1:

     對原始輸入圖像和自編碼器訓練後的圖像進行可視化的直觀展示,看看自編碼器學習效果如何:

import matplotlib.pyplot as pltencoded_imgs = encoder.predict(x_test)decoded_imgs = decoder.predict(encoded_imgs)n = 10  
plt.figure(figsize=(20, 4))
for i in range(1, n):    
   ax = plt.subplot(2, n, i)    plt.imshow(x_test[i].reshape(28, 28))    plt.gray()    ax.get_xaxis().set_visible(False)    ax.get_yaxis().set_visible(False)    
       ax = plt.subplot(2, n, i + n)    plt.imshow(decoded_imgs[i].reshape(28, 28))    plt.gray()    ax.get_xaxis().set_visible(False)    ax.get_yaxis().set_visible(False)plt.show()

     效果如下,可見基於全連接網絡的自編碼器在mnist數據集上表現還不錯。

自編碼器的降噪作用

     前面我們講到自編碼器的一個重要作用就是給數據進行降噪處理。同樣是mnist數據集,我們給原始數據添加一些噪聲看看:

from keras.datasets import mnist
import numpy as np(x_train, _), (x_test, _) = mnist.load_data()x_train = x_train.astype('float32') / 255.
x_test = x_test.astype('float32') / 255.
x_train = np.reshape(x_train, (len(x_train), 1, 28, 28))x_test = np.reshape(x_test, (len(x_test), 1, 28, 28))
noise_factor = 0.5
x_train_noisy = x_train + noise_factor * np.random.normal(loc=0.0, scale=1.0, size=x_train.shape) x_test_noisy = x_test + noise_factor * np.random.normal(loc=0.0, scale=1.0, size=x_test.shape) x_train_noisy = np.clip(x_train_noisy, 0., 1.)x_test_noisy = np.clip(x_test_noisy, 0., 1.)

     展示添加了噪聲後的mnist數據示例:

n = 10  
plt.figure(figsize=(20, 4))
for i in range(1, n):    ax = plt.subplot(2, n, i)    plt.imshow(x_train_noisy[i].reshape(28, 28))    plt.gray()    ax.get_xaxis().set_visible(False)    ax.get_yaxis().set_visible(False)plt.show()

     下面我們想要自編碼器模型對上述經過噪聲處理後的數據進行降噪和還原,我們使用卷積神經網絡作為編碼和解碼模型:

from keras.layers import Input, Dense, UpSampling2D
from keras.layers import Convolution2D, MaxPooling2D
from keras.models import Model
input_img = Input(shape=(1, 28, 28))
x = Convolution2D(32, 3, 3, activation='relu', border_mode='same')(input_img)x = MaxPooling2D((2, 2), border_mode='same')(x)x = Convolution2D(32, 3, 3, activation='relu', border_mode='same')(x)encoded = MaxPooling2D((2, 2), border_mode='same')(x)
x = Convolution2D(32, 3, 3, activation='relu', border_mode='same')(encoded)x = UpSampling2D((2, 2))(x)x = Convolution2D(32, 3, 3, activation='relu', border_mode='same')(x)x = UpSampling2D((2, 2))(x)decoded = Convolution2D(1, 3, 3, activation='sigmoid', border_mode='same')(x)
autoencoder = Model(input_img, decoded)autoencoder.compile(optimizer='adadelta', loss='binary_crossentropy')

對噪聲數據進行自編碼器的訓練:

autoencoder.fit(x_train_noisy, x_train,                nb_epoch=100,                batch_size=128,                shuffle=True,                validation_data=(x_test_noisy, x_test))

     經過卷積自編碼器訓練之後的噪聲圖像還原效果如下:

     添加的噪聲基本被消除了,可見自編碼器確實是一種較好的數據降噪算法。本講的筆記就到這裡,後面筆者將繼續深入分享關於變分自編碼器(VAE)的相關內容。

參考資料:

https://blog.keras.io/building-autoencoders-in-keras.html

深度學習  Ian GoodFellow

https://zhuanlan.zhihu.com/p/34238979

往期精彩:

深度學習第50講:語音識別綜述——從概念到技術(下)

深度學習第49講:語音識別綜述——從概念到技術(上)

深度學習第48講:自然語言處理之情感分析

深度學習第47講:注意力機制Attention Model與機器翻譯

深度學習第46講:seq2seq模型

深度學習第45講:GloVe詞向量與相關應用

深度學習第44講:訓練一個word2vec詞向量

一個數據科學從業者的學習歷程

長按二維碼.關注機器學習實驗室

相關焦點

  • 深度學習筆記 | 第17講:深度生成模型之自編碼器(AutoEncoder)
    自動編碼器是從數據樣本中自動學習的,這意味著很容易對指定類的輸入訓練出一種特定的編碼器,而不需要完成任何新工作。構建一個自編碼器需要兩部分:編碼器(Encoder)和解碼器(Decoder)。編碼器將輸入壓縮為潛在空間表徵,可以用函數f(x)來表示,解碼器將潛在空間表徵重構為輸出,可以用函數g(x)來表示,編碼函數f(x)和解碼函數g(x)都是神經網絡模型。
  • 【周末AI課堂】簡單的自編碼器(代碼篇)| 機器學習你會遇到的「坑」
    為了將AI知識體系以最簡單的方式呈現給你,從這個星期開始,芯君邀請AI專業人士開設「周末學習課堂」——每周就AI學習中的一個重點問題進行深度分析,課程會分為理論篇和代碼篇,理論與實操,一個都不能少!來,退出讓你廢寢忘食的遊戲頁面,取消只有胡吃海塞的周末聚會吧。未來你與同齡人的差異,也許就從每周末的這堂AI課開啟了!
  • 壓縮去噪利器---自編碼器(AutoEncoder)
    input_size = 784hidden_size = 128code_size = 64x = Input(shape=(input_size,))h = Dense(hidden_size, activation='relu')(x)r = Dense(output_size, activation='sigmoid')(h)autoencoder
  • 跟著李宏毅老師學習 Autoencoder 的各類變體及應用
    Hinton 提出的論文,左上角的圖示想要搜索的圖,而其他的皆為被 autoencoder 認為很像的圖,的確 autoencoder 似乎能夠看到 input data 的精髓,但也有些抓出來的圖片怪怪的 XDD
  • 極端時序預測LSTM+AutoEncoder
    這篇文章最重要的收穫可以概括為:開發一種穩定的方法來評估和比較keras模型(同時避免權重種子生成器的問題);實現了一個簡單而智能的LSTM自編碼器,用於新特徵的創建;通過簡單的技巧提高時間序列的預測性能(參見上面的內容);處理嵌套數據集,即觀察到的屬於不同實體的問題(例如,不同商店/引擎/人員的時間序列等)。從這個意義上說,意在所有人開發一個高性能的時序預測模型。
  • 深度學習算法(第30期)----降噪自編碼器和稀疏自編碼器及其實現
    上期我們一起學習了深度學習中的可視化自編碼器和無監督預訓練的相關知識,深度學習算法
  • 從零開始深度學習第17講:keras入門及快速上手指南
    深度學習到這個進度,筆者覺得有必要開始對一些優秀的深度學習框架進行介紹了。在前面幾講中,我們著重對 Tensorflow 進行了介紹,並用其實現了一些數據例子。Tensorflow 雖然很強大,但語法和使用便利性上對於新手來說並不是那麼的友好,所以到這裡筆者需要給大家介紹 keras 了。
  • 深度學習第19講:CNN經典論文研讀之殘差網絡ResNet及其keras實現
    作者:魯偉一個數據科學踐行者的學習日記。
  • 深度學習第17講:keras入門和快速上手指南
    作者:魯偉一個數據科學踐行者的學習日記。
  • 深度學習第56講:強化學習簡介與Q-Learning實例
    從整個機器學習的任務劃分上來看,機器學習可以分為有監督學習、有監督和半監督學習以及強化學習,而我們之前一直談論的圖像、文本等深度學習的應用都屬於監督學習範疇。自編碼器和生成式對抗網絡可以算在無監督深度學習範疇內。最後就只剩下強化學習了。但是我們這是深度學習的筆記,為什麼要把強化學習單獨拎出來講一下呢?
  • TensorFlow教程:快速入門深度學習五步法(附Keras實例)
    作為一個程式設計師,我們可以像學習編程一樣學習深度學習模型開發。過程化方法構造網絡模型我們先學習最容易理解的,過程化方法構造網絡模型的過程。 Keras中提供了Sequential容器來實現過程式構造。只要用Sequential的add方法把層結構加進來就可以了。10種基本層結構我們會在後面詳細講。
  • 入門 | 十分鐘搞定Keras序列到序列學習(附代碼實現)
    RNN 序列到序列學習?GitHub:https://github.com/fchollet/keras/blob/master/examples/lstm_seq2seq.py什麼是序列到序列學習?序列到序列學習(Seq2Seq)是指訓練模型從而把一個域的序列(比如英語語句)轉化為另一個域的序列(比如法語中的對應語句)。
  • 春節充電系列:李宏毅2017機器學習課程學習筆記16之無監督學習:自編碼器(autoencoder)
    本文內容涉及機器學習中半監督學習auto-encoder的若干主要問題:Auto-encoder原理,deep auto-encoder,text retrieval,similar image search,auto-encoder for CNN以及Pre-train DNN。
  • 如何Keras自動編碼器給極端罕見事件分類
    近來,深度學習被廣泛應用於分類中。然而正樣本數太少不利於深度學習的應用。不論數據總量多大,深度學習的使用都會受制於陽性數據的數量。2. 為什麼要使用深度學習?這個問題很合理。為什麼不考慮使用其他機器學習方法呢?答案很主觀。我們總是可以採用某種機器學習方法來達到目的。
  • CICC科普欄目|十分鐘搞定Keras序列到序列學習(附代碼實現)
    RNN 序列到序列學習?GitHub:https://github.com/fchollet/keras/blob/master/examples/lstm_seq2seq.py什麼是序列到序列學習?序列到序列學習(Seq2Seq)是指訓練模型從而把一個域的序列(比如英語語句)轉化為另一個域的序列(比如法語中的對應語句)。
  • 十分鐘掌握Keras實現RNN的seq2seq學習
    很多人問這個問題:如何在Keras中實現RNN序列到序列(seq2seq)學習?本文將對此做一個簡單的介紹。序列到序列學習(seq2seq)是一種把序列從一個域(例如英語中的句子)轉換為另一個域中的序列(例如把相同的句子翻譯成法語)的模型訓練方法。
  • 深度學習 | Keras 簡介
    說到深度學習,不可避免得會提及業界有哪些優秀的框架,Keras神經網絡框架便是其中之一,它是一個高級神經網絡APl,用Python編寫,能夠在TensorFlow,CNTK或Theano之上運行。它的開發重點是實現快速實驗。能夠以最小的延遲從理念到結果是進行良好研究的關鍵。
  • 深度學習第25講:目標檢測算法經典論文研讀之R-CNN
    論文地址:https://arxiv.org/abs/1311.2524R-CNN 參考實現代碼:Tensorflow: https://github.com/yangxue0827/RCNNkeras: https://github.com/broadinstitute/keras-rcnn參考資料:
  • 基於Keras/Python的深度學習模型Dropout正則項
    dropout技術是神經網絡和深度學習模型的一種簡單而有效的正則化方式。
  • Python小白深度學習教程:Keras 精講(上)
    Python小白數據可視化教程:Seaborn 精講Python小白數據可視化教程:PyEcharts 精講Python小白機器學習教程:Sklearn精講Python小白機器可視化學習教程:Scikit-Plot精講Keras 是一個高級的 (high-level) 深度學習框架,作者是 François Chollet。