用自編碼器進(jìn)行圖像去噪

在深度學(xué)習(xí)中,自編碼器是非常有用的一種無監(jiān)督學(xué)習(xí)模型痊土。自編碼器由encoder和decoder組成肄扎,前者將原始表示編碼成隱層表示,后者將隱層表示解碼成原始表示赁酝,訓(xùn)練目標(biāo)為最小化重構(gòu)誤差犯祠,而且一般而言,隱層的特征維度低于原始特征維度酌呆。

自編碼器只是一種思想衡载,在具體實現(xiàn)中,encoder和decoder可以由多種深度學(xué)習(xí)模型構(gòu)成隙袁,例如全連接層痰娱、卷積層或LSTM等,以下使用Keras來實現(xiàn)用于圖像去噪的卷積自編碼器菩收。

1 結(jié)果##

先看一下最后的結(jié)果梨睁,使用的是手寫數(shù)字MNIST數(shù)據(jù)集,上面一行是添加噪音的圖像娜饵,下面一行是去噪之后的結(jié)果坡贺。

去噪效果.png

2 代碼##

我使用Keras來實現(xiàn)自編碼器,encoder和decoder使用CNN來實現(xiàn)箱舞。

加載Keras和numpy遍坟。

from keras.datasets import mnist
import numpy as np

獲取數(shù)據(jù)集MNIST,將像素點值轉(zhuǎn)化到0-1區(qū)間褐缠,并且重塑為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區(qū)間公般。

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

看一下加噪之后的結(jié)果万搔。

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

畫出來是這個樣子的。

加噪后的數(shù)字.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)

將輸入和輸出連接起來,構(gòu)成autoencoder并compile涌哲。

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

使用x_train作為輸入和輸出來訓(xùn)練我們的autoencoder胖缤,并使用x_test進(jìn)行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預(yù)測阀圾,并將預(yù)測結(jié)果繪制出來哪廓,和原始加噪圖像進(jìn)行對比。

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

這樣便可以生成一開始看到的結(jié)果了初烘,完整代碼在這里涡真。

3 其他內(nèi)容##

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

  • 1_simplest_possible_autoencoder:分別僅使用一層Dense作為encoder和decoder構(gòu)成自編碼器肾筐,并對MNIST數(shù)據(jù)集訓(xùn)練和重構(gòu)哆料,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實現(xiàn)讥此,100 epoch之后loss為0.0958,val_loss為0.0946谣妻;
  • 4_denoising_autoencoder:即以上詳細(xì)討論的去噪卷積自編碼器;
  • 5_variational_autoencoder(VAE):隱層添加額外的限制卒稳,即訓(xùn)練目標(biāo)為最小化重構(gòu)誤差蹋半,以及隱層表示分布和原始表示分布的交叉熵(KL Divergence)。

其中最后一個代碼中的VAE將MNIST的原始圖像數(shù)據(jù)映射到了一個二維的隱層充坑,下面是隱層表示中的聚類結(jié)果减江,可以看到在隱層的表示空間中,相同數(shù)字所對應(yīng)的圖像匯聚到了一起捻爷。

隱層空間聚類.png

如果將隱層中的點解碼到原始的圖像表示空間辈灼,則各個聚類中心會出現(xiàn)對應(yīng)的數(shù)字,而類和類之間的位置則會出現(xiàn)“新的數(shù)字”也榄,即不同數(shù)字之間的過渡形態(tài)巡莹。

過渡態(tài)數(shù)字.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末司志,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子降宅,更是在濱河造成了極大的恐慌骂远,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,248評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件腰根,死亡現(xiàn)場離奇詭異激才,居然都是意外死亡,警方通過查閱死者的電腦和手機额嘿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評論 2 381
  • 文/潘曉璐 我一進(jìn)店門瘸恼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人册养,你說我怎么就攤上這事东帅。” “怎么了捕儒?”我有些...
    開封第一講書人閱讀 153,443評論 0 344
  • 文/不壞的土叔 我叫張陵冰啃,是天一觀的道長。 經(jīng)常有香客問我刘莹,道長阎毅,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,475評論 1 279
  • 正文 為了忘掉前任点弯,我火速辦了婚禮扇调,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘抢肛。我一直安慰自己狼钮,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,458評論 5 374
  • 文/花漫 我一把揭開白布捡絮。 她就那樣靜靜地躺著熬芜,像睡著了一般。 火紅的嫁衣襯著肌膚如雪福稳。 梳的紋絲不亂的頭發(fā)上涎拉,一...
    開封第一講書人閱讀 49,185評論 1 284
  • 那天,我揣著相機與錄音的圆,去河邊找鬼鼓拧。 笑死,一個胖子當(dāng)著我的面吹牛越妈,可吹牛的內(nèi)容都是我干的季俩。 我是一名探鬼主播,決...
    沈念sama閱讀 38,451評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼梅掠,長吁一口氣:“原來是場噩夢啊……” “哼酌住!你這毒婦竟也來了店归?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,112評論 0 261
  • 序言:老撾萬榮一對情侶失蹤赂韵,失蹤者是張志新(化名)和其女友劉穎娱节,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體祭示,經(jīng)...
    沈念sama閱讀 43,609評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡肄满,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,083評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了质涛。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片稠歉。...
    茶點故事閱讀 38,163評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖汇陆,靈堂內(nèi)的尸體忽然破棺而出怒炸,到底是詐尸還是另有隱情,我是刑警寧澤毡代,帶...
    沈念sama閱讀 33,803評論 4 323
  • 正文 年R本政府宣布阅羹,位于F島的核電站,受9級特大地震影響教寂,放射性物質(zhì)發(fā)生泄漏捏鱼。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,357評論 3 307
  • 文/蒙蒙 一酪耕、第九天 我趴在偏房一處隱蔽的房頂上張望导梆。 院中可真熱鬧,春花似錦迂烁、人聲如沸看尼。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,357評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽藏斩。三九已至,卻和暖如春却盘,著一層夾襖步出監(jiān)牢的瞬間灾茁,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,590評論 1 261
  • 我被黑心中介騙來泰國打工谷炸, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人禀挫。 一個月前我還...
    沈念sama閱讀 45,636評論 2 355
  • 正文 我出身青樓旬陡,卻偏偏與公主長得像,于是被迫代替她去往敵國和親语婴。 傳聞我的和親對象是個殘疾皇子描孟,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,925評論 2 344

推薦閱讀更多精彩內(nèi)容