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