您當前的位置:首頁 > 書法

自動編碼(AE)器的簡單實現

作者:由 史努比 發表于 書法時間:2019-06-18

自動編碼(AE,DAE,CAE,SAE)器的方法介紹與簡單實現(附程式碼)

一。目錄

自動編碼(AE)器的簡單實現

一。目錄

二。自動編碼器的發展簡述

2。1 自動編碼器(Auto-Encoders,AE)

2。2 降噪自編碼(Denoising Auto-Encoders, DAE)(2008)

2。3 堆疊降燥自動編碼器 (Stacked Denoising Auto-Encoders, SAE)(2008)

2。4 卷積自動編碼器(Convolution Auto-Encoders, CAE)(2011)

2。5 變分自動編碼器(Variational Auto-Encoders, VAE)(Kingma, 2014)

2。5 幾種演算法的改進點表格

三。 實驗

3。1 傳統的自動編碼器實驗結果

模型結構與實現程式碼

訓練過程

編碼器輸出的視覺化結果

說明與討論

3。2 堆疊降噪自編碼器

模型結構與實現程式碼

訓練過程

編碼器輸出的視覺化結果

說明與討論

3。3 卷積自編碼器

模型結構與實現程式碼

訓練過程

編碼器輸出的視覺化結果

3。4 變分自編碼器

模型結構與實現程式碼

訓練過程

自編碼器輸出的視覺化結果

四。討論

參考文獻

二。自動編碼器的發展簡述

2。1 自動編碼器(Auto-Encoders,AE)

傳統的自動編碼器是一種資料的壓縮演算法,其演算法包括編碼階段和解碼階段,且擁有對稱的結構。

目前自編碼器的應用主要有兩個方面,第一是資料去噪,第二是為進行視覺化而降維。配合適當的維度和稀疏約束,自編碼器可以學習到比PCA等技術更有意思的資料投影。

傳統編碼器的編解碼過程描述如圖:

自動編碼(AE)器的簡單實現

自動編碼器的訓練過程使用傳統的基於梯度的方式進行訓練。

評價:

學界評價:傳統自編碼器的目的是使輸出與輸入儘量相同,這完全可以透過學習兩個恆等函式來完成,但是這樣的變換沒有任何意義,因為我們真正關心的是隱層表達,而不是實際輸出。因此,針對自編碼器的很多改進方法都是對隱層表達增加一定的約束,迫使隱層表達與輸入不同。

2。2 降噪自編碼(Denoising Auto-Encoders, DAE)(2008)

自編碼器真正關心的是隱藏層的特徵表達,一個好的表達能夠捕獲輸入訊號的穩定結構,以該目的為出發出現了降噪自動編碼器。降噪自動編碼器,首先對乾淨的輸入訊號加入噪聲產生一個受損的訊號。然後將受損訊號送入傳統的自動編碼器中,使其重建回原來的無損訊號。

降噪自編碼器的編解碼過程描述如圖:

自動編碼(AE)器的簡單實現

其中過程可以使用如下公式描述:

降噪自編碼器與傳統的自動編碼器的主要區別在於:

降噪自編碼器透過人為的增加噪聲使模型獲得魯棒性的特徵表達

避免使隱層單元學習一個傳統自編碼器中沒有意義的恆等函式

評價:

學界評價:降噪自編碼器透過對輸入訊號人為地進行損壞,主要是為了達到兩個目的,首先是為了避免使隱層單元學習一個傳統自編碼器中沒有實際意義的恆等函式,其次就是為了使隱層單元可以學習到一個更加具有魯棒性的特徵表達。

降噪自編碼器最大的優點在於,重建訊號對輸入中的噪聲具有一定的魯棒性,而最大的缺陷在於每次進行網路訓練之前,都需要對乾淨輸入訊號人為地新增噪聲,以獲得它的損壞訊號,這無形中就增加了該模型的處理時間。

2。3 堆疊降燥自動編碼器 (Stacked Denoising Auto-Encoders, SAE)(2008)

參考深度置信網路的方法,將降噪自編碼器進行堆疊可以構造成堆疊降噪自編碼器。與自編碼器和降噪自編碼器不同,堆疊降噪自編碼器的提出是為了解決。

降噪自編碼器的編解碼過程描述如圖:

自動編碼(AE)器的簡單實現

每個子問題的訓練過程與降噪自編碼器自編碼器相同。

整個堆疊降噪自編碼器的訓練過程如下:

為解碼的權重和偏置。

堆疊降噪自編碼器與降噪自編碼器的區別在於:

堆疊降噪自編碼器採用了降噪編碼器的編碼器作為基礎單元,並且使用其訓練方法進行預訓練

降噪自動編碼器是無監督學習(自監督)的一種方法,而降噪自編碼器是一種有監督方法。

評價:

學界評價:堆疊降噪自編碼器是降噪自編碼器的一個應用方法。

2。4 卷積自動編碼器(Convolution Auto-Encoders, CAE)(2011)

全卷積網路是一種面向特定應用(影象語義分割)的卷積神經網路,其結構圖如下圖所示:

自動編碼(AE)器的簡單實現

與經典的CNN在卷積層之後使用全連線層得到固定長度的特徵向量進行分類(全聯接層+softmax輸出)不同,FCN可以接受任意尺寸的輸入影象,採用反捲積層對最後一個卷積層的feature map進行上取樣, 使它恢復到輸入影象相同的尺寸,從而可以對每個畫素都產生了一個預測, 同時保留了原始輸入影象中的空間資訊, 最後在上取樣的特徵圖上進行逐畫素分類。

與全卷積網路類似的一種無監督方法稱為卷機自動編碼器。

由於卷積神經網路所取得的各種優異表現,直接推動了卷積自編碼器的產生。卷積自編碼器屬於傳統自編碼器的一個特例。它使用卷積層和池化層替代了原來的全連線層。卷積

自編碼器能很好的保留二維訊號的空間資訊。

學界評價:其主要差別在於卷積自編碼器採用卷積方式對輸入訊號進行線性變換,並且其權重是共享的,這點與卷積神經網路一樣。因此,重建過程就是基於隱藏編碼的基本影象塊的線性組合。

我實現後的感受:

2。5 變分自動編碼器(Variational Auto-Encoders, VAE)(Kingma, 2014)

變分自編碼器是一種主要用於資料生成的自編碼器的變體。當作為生成模型時,首先利用資料訓練變分自編碼器,然後只使用變分自編碼器的解碼部分,自動生成與訓練資料類似的輸出。

其結構圖如圖所示:

自動編碼(AE)器的簡單實現

整個結構可以分成三個部分,分別是編碼部分,解碼部分和生成部分。編碼部分和解碼部分同時進行訓練,目標函式是從KL散度的概念中推倒得到的。

該公式正好是變分自編碼器的目標函式。目標函式可以分成兩個部分,分別約束了中間的隱變數受到一個標準分佈的約束和輸出影象儘量與原圖相同。

2。5 幾種演算法的改進點表格

編碼器名稱提出時間改進點目的傳統自編碼器1986無無降噪自編碼器2008將帶有噪聲的損壞資訊作為輸入訊號使重建訊號魯棒性更強堆疊自編碼器2008將多層結構和棧式訓練引入自編碼器使自編碼器可以訓練更高層數卷積自編碼器2011將卷積層引入自編碼器更好的處理圖片資料,得到更好的效果變分自編碼器2014相當於在傳統自編碼器的隱層表達上增加一個對隱變數的約束,提出了一種將機率模型和神經網路結構的方法使編碼器產生的隱層表達滿足正態分佈,能夠更好的生成影象模型

三。 實驗

3。1 傳統的自動編碼器實驗結果

模型結構與實現程式碼

傳統的自動編碼器分為編碼器部分和解碼器部分,整體模型結構如圖所示:

自動編碼(AE)器的簡單實現

模型分為三個子模組,由上至下分別為輸入層,編碼器層和解碼器層,編碼器將輸入維度為784(28

28)的mnint灰度值轉化為一個維度為2的值。編碼器將維度為2的值解碼回維度為784(28

28)的mnint灰度值。

使用python-keras程式碼實現關鍵程式碼如下。

def __init__(self, ENCODING_DIM_INPUT=784, ENCODING_DIM_OUTPUT=2, Name = “ae”):

input_image = Input(shape=(ENCODING_DIM_INPUT, ))

# encoding layer

hidden_layer = Dense(ENCODING_DIM_OUTPUT, activation=‘relu’)(input_image)

# decoding layer

decode_output = Dense(ENCODING_DIM_INPUT, activation=‘relu’)(hidden_layer)

# build autoencoder, encoder, decoder

autoencoder = Model(inputs=input_image, outputs=decode_output)

encoder = Model(inputs=input_image, outputs=hidden_layer)

# compile autoencoder

autoencoder。compile(optimizer=‘adam’, loss=‘mse’, metrics=[‘accuracy’])

self。autoencoder = autoencoder

self。encoder = encoder

訓練過程

本實驗討論使用relu和tanh兩種啟用函式的自監督訓練的情況。訓練的loss函式選擇為方均根誤差。

訓練過程的loss變化影象如下。

使用tanh作為啟用函式時,loss變化情況如下。

自動編碼(AE)器的簡單實現

可以觀察到,loss收斂到0。0685,效果較好。使用relu作為啟用函式同樣能夠有效收斂,不過誤差數值相對較大。由於篇幅原因不將圖片在此進行展示。誤差數值相對較大的原因將在下一節進行討論。

編碼器輸出的視覺化結果

本節將從重建影象和編碼器輸出層的二維視覺化影象兩部分進行展示,分別展示使用tanh和relu兩種損失函式的訓練結果。

訓練好的自動編碼器重建影象(使用relu啟用函式)如下圖:

自動編碼(AE)器的簡單實現

訓練好的自動編碼器重建影象(使用tanh啟用函式)如下圖:

自動編碼(AE)器的簡單實現

兩者對比可以發現relu函式訓練出的模型存在一些畫素顆粒,這也驗證了上一節loss函式較大的實驗結果。為了解釋該問題,展示編碼器輸出層的二維視覺化圖片。

訓練好的編碼器輸出影象(使用relu啟用函式)如下圖:

自動編碼(AE)器的簡單實現

訓練好的編碼器輸出影象(使用tanh啟用函式)如下圖:

自動編碼(AE)器的簡單實現

以上兩張圖片是 編碼器-解碼器 結構中編碼器部分的輸出繪製成的二維視覺化圖片,不同的顏色代表了不同的數字,對應的數字在右邊的圖例中進行了顯示。從以上兩張圖片中可以得到:

由於relu函式對負數的截斷性質,使用relu啟用函式訓練的模型中有一部分點被限制在x=0,y=0兩條邊緣線上,這也是上文中提到的訓練誤差較大和出現畫素顆粒的原因。

自動編碼器雖然能夠對mnist資料集進行編碼和解碼,但是效果並沒有其改進的其他方法理想,這一觀點可以從解碼圖片較為模糊和編碼器視覺化後各個類別的分類相重合得到驗證。

說明與討論

傳統自編碼器有很大的改進空間,改進空間的可以從幾個方面闡述:

解碼器輸出較為模糊

編碼器視覺化的類別間的界限不明顯

3。2 堆疊降噪自編碼器

模型結構與實現程式碼

傳統的自動編碼器分為編碼器部分和解碼器部分,整體模型結構如圖所示:

自動編碼(AE)器的簡單實現

模型分為三個子模組,由上至下分別為輸入層,多層編碼器層和多層解碼器層,編碼器將輸入維度為784(28

28)的mnint灰度值轉化為一個維度為2的值。編碼器將維度為2的值解碼回維度為784(28

28)的mnint灰度值

使用python-keras程式碼實現關鍵程式碼如下。

class DAE(ae。AE):

def __init__(

self, ENCODING_DIM_INPUT=784, ENCODING_DIM_LAYER1=128,

ENCODING_DIM_LAYER2=64, ENCODING_DIM_LAYER3=10,

ENCODING_DIM_OUTPUT=2,Name=“dae” ):

# input placeholder

input_image = Input(shape=(ENCODING_DIM_INPUT, ))

# encoding layer

encode_layer1 = Dense(ENCODING_DIM_LAYER1,

activation=‘relu’)(input_image)

encode_layer2 = Dense(ENCODING_DIM_LAYER2,

activation=‘relu’)(encode_layer1)

encode_layer3 = Dense(ENCODING_DIM_LAYER3,

activation=‘relu’)(encode_layer2)

encode_output = Dense(ENCODING_DIM_OUTPUT)(encode_layer3)

# decoding layer

decode_layer1 = Dense(ENCODING_DIM_LAYER3,

activation=‘relu’)(encode_output)

decode_layer2 = Dense(ENCODING_DIM_LAYER2,

activation=‘relu’)(decode_layer1)

decode_layer3 = Dense(ENCODING_DIM_LAYER1,

activation=‘relu’)(decode_layer2)

decode_output = Dense(ENCODING_DIM_INPUT,

activation=‘tanh’)(decode_layer3)

# build surprised learning model

SL_output = Dense(10, activation=‘softmax’)(encode_output)

# build autoencoder, encoder

autoencoder = Model(inputs=input_image, outputs=decode_output)

encoder = Model(inputs=input_image, outputs=encode_output)

SL_model = Model(inputs=input_image, outputs=SL_output)

# compile autoencoder

autoencoder。compile(optimizer=‘adam’, loss=‘mse’, metrics=[‘accuracy’])

SL_model。compile(optimizer=‘adam’, loss=‘mse’, metrics=[‘accuracy’])

程式碼定義了三個模型,分別是用於自監督訓練的 autoencoder, 用於二維化的編碼器 encoder 和用於進行有監督訓練的 SL_model。

訓練過程

堆疊降噪自動編碼器分為無監督的預訓練過程和有監督的訓練過程兩部分。

本部分分別進行說明。

自監督的預訓練過程loss變化情況如下。

自動編碼(AE)器的簡單實現

無監督的訓練過程正確率acc變化情況如下。

自動編碼(AE)器的簡單實現

可以看到,在兩個訓練階段,方法可以有效的達到收斂。

以下幾點需要指出:

多層編碼器的訓練沒有使用棧式編碼器的訓練方式。

預訓練次數20epoch,並不足夠模型充分收斂,但是作為預訓練部分,已經充分。

預訓練部分的誤差與傳統自編碼器相比較大,是因為在初始層加入了噪聲的原因。

訓練時間與傳統編碼器相比更長,是其3倍左右。

在有監督學習的開始階段,分類的正確率並不高,這也印證了上一部分二位視覺化的結果,很多點的界限不清晰。

編碼器輸出的視覺化結果

本節將從重建影象和編碼器輸出層的二維視覺化影象兩部分進行展示

預訓練部分

重建影象

下圖展示了新增噪聲的效果(第一行原圖,第二行增加噪聲的圖)。

自動編碼(AE)器的簡單實現

下圖展示了,對新增噪聲的圖片進行重構的結果(第一行增加噪聲的圖,第二行重構圖)

自動編碼(AE)器的簡單實現

編碼器輸出層的二維視覺化影象

下圖展示了新增噪聲的效果(第一行原圖,第二行增加噪聲的圖)。

自動編碼(AE)器的簡單實現

以下幾點需要指出:

本方法可以有效的對隨機噪聲進行去除

恢復圖與原圖相比雖然能夠識別但是效果更模糊

與傳統自動編碼器相比,本方法得到的二維圖的界限更加清晰

有監督訓練部分

經過有監督的訓練

重建影象(因為不是目標,所以必然走樣)

下圖展示了,對新增噪聲的圖片進行重構的結果(第一行增加噪聲的圖,第二行重構圖)

自動編碼(AE)器的簡單實現

編碼器輸出層的二維視覺化影象

自動編碼(AE)器的簡單實現

經過有監督學習,二維視覺化圖中各個組的界限更加清晰。

說明與討論

堆疊降噪自編碼器的改進有以下啟發:

使用自監督預訓練與有監督訓練方式相結合的形式獲得更加優秀的效果

使用增加噪聲的形式迫使模型學習更加有效的特徵

將深度玻爾茲曼姬的思想遷移到自動編碼器中

3。3 卷積自編碼器

模型結構與實現程式碼

卷積自編碼器自動編碼器分為編碼器部分和解碼器部分,整體模型結構如圖所示:

自動編碼(AE)器的簡單實現

使用python-keras程式碼實現關鍵程式碼如下。

def __init__(self,CHANNEL_1 = 16,CHANNEL_2 = 8,CHANNEL_OUTPUT = 1, Name=“cae”):

# input placeholder

input_image = Input(shape=(28, 28, 1))

# encoding layer

x = Conv2D(CHANNEL_1, (3, 3), activation=‘relu’, padding=“same”)(input_image)

x = MaxPool2D((2, 2), padding=‘same’)(x)

x = Conv2D(CHANNEL_2, (3, 3), activation=‘relu’, padding=‘same’)(x)

encode_output = MaxPool2D((2, 2), padding=‘same’)(x)

# decoding layer

x = Conv2D(CHANNEL_2, (3, 3), activation=‘relu’, padding=‘same’)(encode_output)

x = UpSampling2D((2, 2))(x)

x = Conv2D(CHANNEL_1, (3, 3),activation=‘relu’, padding=‘same’)(x)

x = UpSampling2D((2, 2))(x)

decode_output = Conv2D(CHANNEL_OUTPUT, (3, 3), activation=‘sigmoid’, padding=‘same’)(x)

# build surprised learning model

encode_output_flatten = Flatten()(decode_output)

SL_output = Dense(10, activation=‘softmax’)(encode_output_flatten)

# build autoencoder, encoder

autoencoder = Model(inputs=input_image, outputs=decode_output)

encoder = Model(inputs=input_image, outputs=encode_output)

SL_model = Model(inputs=input_image, outputs=SL_output)

# compile autoencoder

autoencoder。compile(optimizer=‘adam’, loss=‘binary_crossentropy’, metrics=[‘accuracy’])

SL_model。compile(optimizer=‘adam’, loss=‘mse’, metrics=[‘accuracy’])

訓練過程

堆疊降噪自動編碼器分為無監督的預訓練過程和有監督的訓練過程兩部分。

本部分分別進行說明。

在自監督的預訓練過程loss變化情況如下。

自動編碼(AE)器的簡單實現

影象顯示,自監督的訓練loss收斂於0。07左右,該誤差比降噪自編碼器的0。09要小。與傳統自編碼器的訓練誤差相差不多。但是從下文可知其訓練效果明顯優於傳統自動編碼器。

在有監督的訓練過程正確率acc變化情況如下。

自動編碼(AE)器的簡單實現

影象顯示,有監督訓練過程的正確率上升到0。99,比降噪自動編碼器的正確(0。95)率更高。

因此在mnist資料集中的重建任務和分類任務中,卷積自動編碼器有一定優勢。

不過以下幾點需要指出:

與sDAE相比,CAE有更高的準確率和更低的損失

更好的效果除了卷積單元能夠更好的處理影象資料外,可能與CAE方法的複雜度更高和其瓶頸處通道更寬有關

編碼器輸出的視覺化結果

可以看到和stacked AE的主要區別在於區域性卷積連線,而不所有層都是全連線。對影象和某些其他資料影響在空間區域性的問題,比全連線更合適。因此效果更加優秀。

於降噪自動編碼器相同,首先對圖片增加噪聲:

自動編碼(AE)器的簡單實現

然後對增加噪聲的圖片進行去噪:

自動編碼(AE)器的簡單實現

去噪結果比較優秀,與上文中所有的結果相比是最優秀的。

3。4 變分自編碼器

模型結構與實現程式碼

變分自動編碼器的結構最為複雜,並且在模型中引入了隱變數,和KL散度等機率論概念。對模型的實現造成了一定的影響。

自動編碼器分為編碼器部分和解碼器部分,整體模型結構如圖所示:

自動編碼(AE)器的簡單實現

上圖中並沒有展開編碼器和解碼器的結構,編碼器(encoder) 與 解碼器(decoder)的形式分別如下:

encoder:

自動編碼(AE)器的簡單實現

decoder:

自動編碼(AE)器的簡單實現

使用python-keras程式碼實現關鍵程式碼如下。

class VAE(ae。AE):

def __init__(

self,

ENCODING_DIM_INPUT = 784,

intermediate_dim = 512,

batch_size = 128,

latent_dim = 2,

mse_loss = True,

Name=“vae”

):

self。name = Name

# input placeholder

input_image = Input(shape=(ENCODING_DIM_INPUT,), name=‘encoder_input’)

# VAE model = encoder + decoder

# encoding layer

x = Dense(intermediate_dim, activation=‘relu’)(input_image)

z_mean = Dense(latent_dim, name=‘z_mean’)(x)

z_log_var = Dense(latent_dim, name=‘z_log_var’)(x)

z = Lambda(sampling, output_shape=(latent_dim,), name=‘z’)([z_mean, z_log_var])

# build decoder model

latent_inputs = Input(shape=(latent_dim,), name=‘z_sampling’)

x = Dense(intermediate_dim, activation=‘relu’)(latent_inputs)

outputs = Dense(ENCODING_DIM_INPUT, activation=‘sigmoid’)(x)

# # build surprised learning model

# SL_output = Dense(10, activation=‘softmax’)()

# build autoencoder, encoder

encoder = Model(input_image, [z_mean, z_log_var, z], name=‘encoder’)

decoder = Model(latent_inputs, outputs, name=‘decoder’)

# SL_model = Model(inputs=input_image, outputs=SL_output)

outputs = decoder(encoder(input_image)[2])

autoencoder = Model(input_image, outputs, name=‘vae_mlp’)

# compile autoencoder

# VAE loss = mse_loss or xent_loss + kl_loss

if mse_loss:

reconstruction_loss = mse(input_image, outputs)

else:

reconstruction_loss = binary_crossentropy(input_image,outputs)

reconstruction_loss *= ENCODING_DIM_INPUT

kl_loss = 1 + z_log_var - K。square(z_mean) - K。exp(z_log_var)

kl_loss = K。sum(kl_loss, axis=-1)

kl_loss *= -0。5

vae_loss = K。mean(reconstruction_loss + kl_loss)

autoencoder。add_loss(vae_loss)

autoencoder。compile(optimizer=‘adam’)

autoencoder。summary()

# SL_model。compile(optimizer=‘adam’, loss=‘mse’, metrics=[‘accuracy’])

self。autoencoder = autoencoder

self。encoder = encoder

self。decoder = decoder

訓練過程

由於,變分自動編碼器主要應用於影象生成,而並非是提取與分類,因此變分降噪自動編碼器只有自監督的訓練過程。。

在自監督的訓練過程,使用 KL散度+交叉熵 作為loss函式,loss變化情況如下。

自動編碼(AE)器的簡單實現

可以看散度可以收斂到145的情況,能夠有效進行收斂。

在自監督的訓練過程,使用 KL散度+方均根 作為loss函式,loss變化情況如下。

自動編碼(AE)器的簡單實現

對於兩種損失函式效果的討論在下文中進行。

自編碼器輸出的視覺化結果

使用 KL散度+交叉熵 作為損失函式

基於kl散度的loss訓練結果二維視覺化如下

自動編碼(AE)器的簡單實現

使用生成器對影象進行生成可以得到如下結果。

自動編碼(AE)器的簡單實現

使用 KL散度+方均根 作為損失函式

基於kl散度的loss訓練結果二維視覺化如下

自動編碼(AE)器的簡單實現

使用生成器對影象進行生成可以得到如下結果。

自動編碼(AE)器的簡單實現

由於方均根與交叉熵的區別在於 解碼器重現誤差上面的區別,在編碼器部分同樣使用kl散度作為loss,因此兩者的視覺化結果類似。

以下幾點需要指出:

二維視覺化的結果中各個類別的界限較為明顯,且其分佈十分集中方便生成模型的影象生成。

KL散度作為一種新的損失函式無法與其他方法的誤差進行對比。

四。討論

自動編碼器可能的應用有特徵提取,影象分類,影象去燥,影象生成等

在特徵提取領域和影象分類領域使用sae有較優秀的效果

在影象去噪領域可以使用cae方法,cae方法對二維圖片的去燥效果十分優秀,但是由於中間部分是比較複雜的卷機核結構,無法進行有效的視覺化

vae方法在影象生成領域有出色的表現,將中間的隱變數約束為正太分佈的形式,十分方便的透過生成器完成影象生成。

在研究角度,vae方法將機率方法引入神經網路的計算體系中,透過網路完成對機率分佈的對映,使用散度的概念構造損失函式,對其他研究有些啟發。

原文連結

標簽: 編碼器  loss  訓練  降噪  卷積