用自編碼器進行圖像去噪

在深度學習中,自編碼器是非常有用的一種無監督學習模型。自編碼器由encoder和decoder組成,前者將原始表示編碼成隱層表示,后者將隱層表示解碼成原始表示,訓練目標為最小化重構誤差,而且一般而言,隱層的特征維度低于原始特征維度。

自編碼器只是一種思想,在具體實現中,encoder和decoder可以由多種深度學習模型構成,例如全連接層、卷積層或LSTM等,以下使用Keras來實現用于圖像去噪的卷積自編碼器。

1 結果##

先看一下最后的結果,使用的是手寫數字MNIST數據集,上面一行是添加噪音的圖像,下面一行是去噪之后的結果。

去噪效果.png

2 代碼##

我使用Keras來實現自編碼器,encoder和decoder使用CNN來實現。

加載Keras和numpy。

from keras.datasets import mnist
import numpy as np

獲取數據集MNIST,將像素點值轉化到0-1區間,并且重塑為N×1×28×28的四維tensor。

(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))

添加噪聲,即疊加一個隨機的高斯白噪聲,并限制加噪之后的值仍處于0-1區間。

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.)

看一下加噪之后的結果。

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

畫出來是這個樣子的。

加噪后的數字.png

定義模型的輸入。

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

定義encoder部分,由兩個32×3×3的卷積層和兩個2×2的最大池化層組成。

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)

定義decoder部分,由兩個32×3×3的卷積層和兩個2×2的上采樣層組成。

# at this point the representation is (32, 7, 7)
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并compile。

autoencoder = Model(input_img, decoded)
autoencoder.compile(optimizer='adadelta', loss='binary_crossentropy')

使用x_train作為輸入和輸出來訓練我們的autoencoder,并使用x_test進行validation。

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

使用autoencoder對x_test預測,并將預測結果繪制出來,和原始加噪圖像進行對比。

decoded_imgs = autoencoder.predict(x_test_noisy)
 
import matplotlib.pyplot as plt
 
n = 10
plt.figure(figsize=(20, 4))
for i in range(n):
    # display original
    ax = plt.subplot(2, n, i + 1)
    plt.imshow(x_test_noisy[i].reshape(28, 28))
    plt.gray()
    ax.get_xaxis().set_visible(False)
    ax.get_yaxis().set_visible(False)
 
    # display reconstruction
    ax = plt.subplot(2, n, i + 1 + 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()

這樣便可以生成一開始看到的結果了,完整代碼在這里

3 其他內容##

除了以上用于去噪的卷積自編碼器,這里還有其他幾個代碼:

  • 1_simplest_possible_autoencoder:分別僅使用一層Dense作為encoder和decoder構成自編碼器,并對MNIST數據集訓練和重構,50 epoch之后loss為0.1068,val_loss為0.1051;
  • 2_deep_autoencoder:encoder和decoder從一層Dense增加到三層Dense,100 epoch之后loss為0.0974,val_loss為0.0966;
  • 3_convolutional_deep_autoencoder:encoder和decoder分別由CNN實現,100 epoch之后loss為0.0958,val_loss為0.0946;
  • 4_denoising_autoencoder:即以上詳細討論的去噪卷積自編碼器;
  • 5_variational_autoencoder(VAE):隱層添加額外的限制,即訓練目標為最小化重構誤差,以及隱層表示分布和原始表示分布的交叉熵(KL Divergence)。

其中最后一個代碼中的VAE將MNIST的原始圖像數據映射到了一個二維的隱層,下面是隱層表示中的聚類結果,可以看到在隱層的表示空間中,相同數字所對應的圖像匯聚到了一起。

隱層空間聚類.png

如果將隱層中的點解碼到原始的圖像表示空間,則各個聚類中心會出現對應的數字,而類和類之間的位置則會出現“新的數字”,即不同數字之間的過渡形態。

過渡態數字.png
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,983評論 6 537
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,772評論 3 422
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,947評論 0 381
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,201評論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,960評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,350評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,406評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,549評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,104評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,914評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,089評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,647評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,340評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,753評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,007評論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,834評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,106評論 2 375

推薦閱讀更多精彩內容