自编码器(Auto Encoder)原理及其python实现
目錄
- 一.原理
- 二.為什么要使用自編碼器
- 三.代碼實現
- 1.原始自編碼器
- 2.多層(堆疊)自編碼器
- 3.卷積自編碼器
- 4.正則自編碼器
- 4.1稀疏自編碼器
- 四.降噪自編碼器
- 五. 逐層貪婪訓練堆疊自編碼器
- 參考
一.原理
自編碼器由兩部分組成:
編碼器(encoder):這部分能將輸入壓縮成潛在空間表征,可以用編碼函數h=f(x)表示。
解碼器(decoder):這部分重構來自潛在空間表征的輸入,可以用解碼函數r=g(h)表示。
因此,整個自編碼器可以用函數g(f(x)) = r 來描述,其中輸出r與原始輸入x相近。
自編碼器(Auto Encoder)可以認為是只有一層隱含層的神經網絡,通過壓縮和還原實現對特征的重構。輸入數據是特征,輸入層到隱含層是編碼器,能將輸入壓縮成潛在空間表征;隱含層到輸出層是解碼器,重構來自潛在空間表征的輸入。其中自編碼器的輸入輸出神經元個數都等于特征維度。訓練這個自編碼器,使得輸出的特征和輸入的特征盡可能一致。自編碼器試圖復現其原始輸入,因此,在訓練中,網絡中的輸出應與輸入相同,即y=x,因此,一個自編碼器的輸入、輸出應有相同的結構。我們利用訓練數據訓練這個網絡,等訓練結束后,這個網絡即學習出了x→h→x的能力。對我們來說,此時的h是至關重要的,因為它是在盡量不損失信息量的情況下,對原始數據的另一種表達。
其結構如下:
二.為什么要使用自編碼器
我們希望通過訓練輸出值等于輸入值的自編碼器,讓潛在表征h將具有價值屬性。從自編碼器獲得有用特征的一種方法是,限制h的維度使其小于輸入x, 這種情況下稱作有損自編碼器。通過訓練有損表征,使得自編碼器能學習到數據中最重要的特征。
三.代碼實現
以手寫數字識別為例
1.原始自編碼器
input_size = 784 hidden_size = 64 output_size = 784x = Input(shape=(input_size,))# Encoder h = Dense(hidden_size, activation='relu')(x)# Decoder r = Dense(output_size, activation='sigmoid')(h)autoencoder = Model(input=x, output=r) autoencoder.compile(optimizer='adam', loss='mse')2.多層(堆疊)自編碼器
input_size = 784 hidden_size = 128 code_size = 64x = Input(shape=(input_size,))# Encoder hidden_1 = Dense(hidden_size, activation='relu')(x) h = Dense(code_size, activation='relu')(hidden_1)# Decoder hidden_2 = Dense(hidden_size, activation='relu')(h) r = Dense(input_size, activation='sigmoid')(hidden_2)autoencoder = Model(input=x, output=r) autoencoder.compile(optimizer='adam', loss='mse')3.卷積自編碼器
除了全連接層,自編碼器也可以應用到卷積層,原理是一樣的,但是要使用3D矢量(如圖像)而不是展平后的一維矢量。對輸入圖像進行下采樣,以提供較小維度的潛在表征,來迫使自編碼器從壓縮后的數據進行學習。
x = Input(shape=(28, 28,1)) # Encoder conv1_1 = Conv2D(16, (3, 3), activation='relu', padding='same')(x) pool1 = MaxPooling2D((2, 2), padding='same')(conv1_1) conv1_2 = Conv2D(8, (3, 3), activation='relu', padding='same')(pool1) pool2 = MaxPooling2D((2, 2), padding='same')(conv1_2) conv1_3 = Conv2D(8, (3, 3), activation='relu', padding='same')(pool2) h = MaxPooling2D((2, 2), padding='same')(conv1_3)# Decoder conv2_1 = Conv2D(8, (3, 3), activation='relu', padding='same')(h) up1 = UpSampling2D((2, 2))(conv2_1) conv2_2 = Conv2D(8, (3, 3), activation='relu', padding='same')(up1) up2 = UpSampling2D((2, 2))(conv2_2) conv2_3 = Conv2D(16, (3, 3), activation='relu')(up2) up3 = UpSampling2D((2, 2))(conv2_3) r = Conv2D(1, (3, 3), activation='sigmoid', padding='same')(up3)autoencoder = Model(input=x, output=r) autoencoder.compile(optimizer='adam', loss='mse')4.正則自編碼器
除了施加一個比輸入維度小的隱含層,一些其他方法也可用來約束自編碼器重構,如正則自編碼器。
正則自編碼器不需要使用淺層的編碼器和解碼器以及小的編碼維數來限制模型容量,而是使用損失函數來鼓勵模型學習其他特性(除了將輸入復制到輸出)。這些特性包括稀疏表征、小導數表征、以及對噪聲或輸入缺失的魯棒性。
即使模型容量大到足以學習一個無意義的恒等函數,非線性且過完備的正則自編碼器仍然能夠從數據中學到一些關于數據分布的有用信息。
在實際應用中,常用到兩種正則自編碼器,分別是稀疏自編碼器和降噪自編碼器。
4.1稀疏自編碼器
一種用來約束自動編碼器重構的方法,是對其損失函數施加約束。比如,可對損失函數添加一個正則化約束,這樣能使自編碼器學習到數據的稀疏表征。
要注意,在隱含層中,我們還加入了L1正則化,作為優化階段中損失函數的懲罰項。與香草自編碼器相比,這樣操作后的數據表征更為稀疏。
input_size = 784 hidden_size = 64 output_size = 784x = Input(shape=(input_size,))# Encoder h = Dense(hidden_size, activation='relu', activity_regularizer=regularizers.l1(10e-5))(x)#施加在輸出上的L1正則項# Decoder r = Dense(output_size, activation='sigmoid')(h)autoencoder = Model(input=x, output=r) autoencoder.compile(optimizer='adam', loss='mse')四.降噪自編碼器
降噪自動編碼器就是在自動編碼器的基礎之上,為了防止過擬合問題而對輸入層的輸入數據加入噪音,以一定概率分布(通常使用二項分布)去擦除原始input矩陣,即每個值都隨機置0,這樣看起來部分數據的部分特征是丟失了。向訓練數據加入噪聲,并使自編碼器學會去除這種噪聲來獲得沒有被噪聲污染過的真實輸入。因此,這就迫使編碼器學習提取最重要的特征并學習輸入數據中更加魯棒的表征,這也是它的泛化能力比一般編碼器強的原因。
這里不是通過對損失函數施加懲罰項,而是通過改變損失函數的重構誤差項來學習一些有用信息。
向訓練數據加入噪聲(高斯噪聲或者隨機置0),并使自編碼器學會去除這種噪聲來獲得沒有被噪聲污染過的真實輸入。因此,這就迫使編碼器學習提取最重要的特征并學習輸入數據中更加魯棒的表征,這也是它的泛化能力比一般編碼器強的原因。
五. 逐層貪婪訓練堆疊自編碼器
這種方法一定程度上能解決梯度消失梯度爆炸的問題,但現在很少用了。
每次訓練都只訓練一個自編碼器,訓練完該自編碼器后,拋棄輸入層跟輸出層,將隱含層作為下一個自編碼器的輸入層,然后訓練下一個自編碼器。當訓練完多個自編碼器后,比如4個,訓練了4個隱含層結構,將這4個隱含層結構和參數提取出來作為神經網絡的隱含層結構和初始化參數。最后,在神經網絡添加輸出層預測平均接受信號功率,微調這個網絡。
逐層貪婪算法的主要思路是每次只訓練網絡中的一層,即我們首先訓練一個只含一個隱藏層的網絡,僅當這層網絡訓練結束之后才開始訓練一個有兩個隱藏層的網絡,以此類推。在每一步中,我們把已經訓練好的前k-1層固定,然后增加第k層(也就是將我們已經訓練好的前k-1的輸出作為輸入)。每一層的訓練可以是有監督的(例如,將每一步的分類誤差作為目標函數),但更通常使用無監督方法(例如自動編碼器,我們會在后邊的章節中給出細節)。這些各層單獨訓練所得到的權重被用來初始化最終(或者說全部)的深度網絡的權重,然后對整個網絡進行“微調”(即把所有層放在一起來優化有標簽訓練集上的訓練誤差)。
參考
自編碼器(AutoEncoder)入門及TensorFlow實現
自編碼器(Autoencoders)
keras實現各種自編碼器
tensorflow 1.0+版本的代碼實現
總結
以上是生活随笔為你收集整理的自编码器(Auto Encoder)原理及其python实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MySQL的高级应用:视图,事务,索引,
- 下一篇: Keras保存和载入训练好的模型和参数