訂閱
糾錯(cuò)
加入自媒體

一文教你如何使用自動編碼器進(jìn)行圖像去噪

介紹讓我們從理解術(shù)語“圖像去噪”的含義來開始我們的討論,這也是我們的文章標(biāo)題——

圖像去噪是從圖像中去除噪聲的過程

圖像中存在的噪聲可能是由實(shí)際上難以處理的各種內(nèi)在或外在條件引起的。圖像去噪問題是圖像處理計(jì)算機(jī)視覺領(lǐng)域的一個(gè)非;镜奶魬(zhàn) 。因此,它在許多領(lǐng)域中發(fā)揮著重要作用,獲取原始圖像對于魯棒性能非常重要。

讓我們看看存在噪聲的圖像是什么樣子的:

帶有噪聲的圖像示例

因此,在本文中,我們將看到如何使用自動編碼器或編碼器-解碼器網(wǎng)絡(luò)從帶有噪聲的圖像中去除噪聲。

在本文中,我將使用深度人工神經(jīng)網(wǎng)絡(luò)實(shí)現(xiàn)自動編碼器。我的下一篇文章中,我還將針對相同的問題陳述使用深度卷積神經(jīng)網(wǎng)絡(luò)來描述自動編碼器。所以,試試這個(gè)項(xiàng)目,并在我的下一個(gè)教程中繼續(xù)關(guān)注我們。

現(xiàn)在,讓我們也看看去除噪聲后圖像的外觀:

對頑皮狗圖像進(jìn)行降噪之前和降噪之后

現(xiàn)在,讓我們通過了解一些關(guān)于自動編碼器的基本概念來開始我們的討論。

編碼器-解碼器網(wǎng)絡(luò)(自動編碼器)概述自編碼器是一種無監(jiān)督的人工神經(jīng)網(wǎng)絡(luò),經(jīng)過訓(xùn)練可以將其輸入復(fù)制到輸出。對于圖像數(shù)據(jù),自動編碼器將首先將圖像編碼為低維表示,然后將該表示解碼回圖像。編碼器-解碼器包含以下兩種結(jié)構(gòu):編碼器 - 該網(wǎng)絡(luò)將數(shù)據(jù)下采樣到較低的維度。解碼器 -該網(wǎng)絡(luò)從較低維度的表示中重建原始數(shù)據(jù)。較低維度(即編碼器網(wǎng)絡(luò)的輸出)表示通常稱為 潛在空間表示。關(guān)于自動編碼器,我們必須記住的一件事是,它們只能壓縮與它們接受過訓(xùn)練的數(shù)據(jù)相似的數(shù)據(jù)。它們本質(zhì)上也是有損的,這意味著相對于原始輸入,輸出將降級。

它們通過反向傳播進(jìn)行類似于人工神經(jīng)網(wǎng)絡(luò)的訓(xùn)練。

讓我們開始吧!!加載必要的庫

第一步是加載必要的 Python 庫。我們將導(dǎo)入諸如numpy 之類的庫,用于優(yōu)化矩陣乘法,matplotlib用于數(shù)據(jù)可視化,例如繪制圖像。來自 Keras 的序列模型為我們提供了一個(gè)空的架構(gòu),根據(jù)我們的架構(gòu),我們將在其中添加幾個(gè)全連接層,Dense在我們的網(wǎng)絡(luò)中創(chuàng)建全連接層,直接從Keras導(dǎo)入MNIST數(shù)據(jù)集。

import numpy
import matplotlib.pyplot as plt
from keras.models import Sequential
from keras.layers import Dense
from keras.datasets import mnist

現(xiàn)在,我們完成了導(dǎo)入必要庫的第一步,讓我們繼續(xù)以 numpy 的形式加載數(shù)據(jù)集。

以 Numpy 格式加載數(shù)據(jù)集

在本文中,我們將使用 MNIST 數(shù)據(jù)集,這是一個(gè)簡單的計(jì)算機(jī)視覺數(shù)據(jù)集。它由灰度形式的手寫數(shù)字圖像組成。它還包括每個(gè)圖像的標(biāo)簽,告訴我們它是哪個(gè)數(shù)字(即每個(gè)圖像的輸出)。這意味著我們手中有一個(gè)標(biāo)記數(shù)據(jù)可以使用。MNIST 數(shù)據(jù)集中的每個(gè)圖像都是 28 x 28 像素。

讓我們看看 MNIST 數(shù)據(jù)集中的一些圖像:

我們將把我們的 MNIST 數(shù)據(jù)分成兩部分:

訓(xùn)練數(shù)據(jù)集: 60,000 個(gè)數(shù)據(jù)點(diǎn)屬于訓(xùn)練數(shù)據(jù)集

測試數(shù)據(jù)集: 10,000 個(gè)數(shù)據(jù)點(diǎn)屬于測試數(shù)據(jù)集

(X_train, y_train), (X_test, y_test) = mnist.load_data()

輸出:

讓我們借助以下代碼行來看看我們的 NumPy 數(shù)組的形狀:

X_train.shape

輸出:

(60000, 28, 28)

上面的輸出表明我們有 60,000 張訓(xùn)練圖像,每張圖像由 28 x 28 像素組成。

X_test.shape

輸出:

(10000, 28, 28)

上面的輸出表明我們有 10,000 個(gè)測試圖像,每個(gè)圖像由 28 x 28 像素組成。將圖像繪制為灰度圖像現(xiàn)在,到上述部分,我們將加載完整的數(shù)據(jù)集,并將其分為訓(xùn)練集和測試集。因此,在本節(jié)中,我們將使用matplotlib庫繪制一些我們的數(shù)據(jù)集圖像,具體而言,我們使用的是matplotlib庫的 subplot 函數(shù)同時(shí)繪制多個(gè)圖像。

plt.subplot(221)
plt.imshow(X_train[0], cmap=plt.get_cmap('gray'))
plt.subplot(222)
plt.imshow(X_train[1], cmap=plt.get_cmap('gray'))
plt.subplot(223)
plt.imshow(X_train[2], cmap=plt.get_cmap('gray'))
plt.subplot(224)
plt.imshow(X_train[3], cmap=plt.get_cmap('gray'))
# show the plot
plt.show()

輸出:

格式化 Keras 數(shù)據(jù)我們可以將二維圖像數(shù)組展平為28×28=784 個(gè)數(shù)字的向量。只要我們在圖像之間保持一致,這與我們?nèi)绾握蛊疥嚵袩o關(guān)。從這個(gè)角度來看,MNIST 圖像只是784 維向量空間中的一堆點(diǎn) 。但數(shù)據(jù)應(yīng)始終采用“ (數(shù)據(jù)點(diǎn)數(shù),數(shù)據(jù)點(diǎn)維度)”格式。在這種情況下,訓(xùn)練數(shù)據(jù)的格式為60,000×784。

num_pixels = X_train.shape[1] * X_train.shape[2]
X_train = X_train.reshape(X_train.shape[0], num_pixels).a(chǎn)stype('float32')
X_test = X_test.reshape(X_test.shape[0], num_pixels).a(chǎn)stype('float32')
X_train = X_train / 255
X_test = X_test / 255

讓我們借助以下幾行代碼再次看看我們的 NumPy 數(shù)組的形狀:

X_train.shape

輸出:

(60000, 784)

X_test.shape

輸出:

(10000, 784)

給圖像添加噪點(diǎn)在解決問題陳述時(shí),我們必須記住我們的目標(biāo)是制作一個(gè)能夠?qū)D像執(zhí)行噪聲去除的模型。為了能夠做到這一點(diǎn),我們將使用現(xiàn)有圖像并給它們添加隨機(jī)噪聲。在這里,我們將原始圖像作為輸入,我們將噪聲圖像作為輸出,我們的模型(即自動編碼器)將學(xué)習(xí)干凈圖像和噪聲圖像之間的關(guān)系,并學(xué)習(xí)如何清理噪聲圖像。因此,讓我們創(chuàng)建 MNIST 數(shù)據(jù)集的噪聲版本,并將其作為解碼器網(wǎng)絡(luò)的輸入。我們首先定義一個(gè)噪聲因子,它是一個(gè)超參數(shù)。噪聲因子乘以均值為 0.0 且標(biāo)準(zhǔn)差為 1.0 的隨機(jī)矩陣。該矩陣將從正態(tài)(高斯)分布中抽取樣本。在添加噪聲時(shí),我們必須記住正態(tài)隨機(jī)數(shù)組的形狀與你將添加噪聲的數(shù)據(jù)的形狀類似。

noise_factor = 0.2
x_train_noisy = X_train + noise_factor * numpy.random.normal(loc=0.0, scale=1.0, size=X_train.shape)
x_test_noisy = X_test + noise_factor * numpy.random.normal(loc=0.0, scale=1.0, size=X_test.shape)
x_train_noisy = numpy.clip(x_train_noisy, 0., 1.)
x_test_noisy = numpy.clip(x_test_noisy, 0., 1.)

看到上面的代碼,你可能會想,這里為什么要用這個(gè)clip函數(shù)呢?為了確保我們最終的圖像數(shù)組項(xiàng)值在 0 到 1 的范圍內(nèi),我們可以使用**np.clip ** 方法。clip 是numpy的函數(shù),用于剪輯min - max范圍之外的值,并用指定的最小或最大值替換它們。

讓我們看看噪聲圖像是什么樣子的:

手寫數(shù)字的噪聲圖像定義編碼器-解碼器網(wǎng)絡(luò)它將有一個(gè) 784 個(gè)神經(jīng)元的輸入層,因?yàn)槲覀兊膱D像大小為 784,因?yàn)榇嬖?28 x 28 個(gè)像素(即我們有 784 個(gè)神經(jīng)元的輸入維度和輸出層)。

# create model
model = Sequential()
model.a(chǎn)dd(Dense(500, input_dim=num_pixels, activation='relu'))
model.a(chǎn)dd(Dense(300, activation='relu'))
model.a(chǎn)dd(Dense(100, activation='relu'))
model.a(chǎn)dd(Dense(300, activation='relu'))
model.a(chǎn)dd(Dense(500, activation='relu'))
model.a(chǎn)dd(Dense(784, activation='sigmoid'))

編譯模型一旦定義了模型,我們就必須編譯它。在編譯時(shí),我們提供要使用的損失函數(shù)、優(yōu)化器和任何指標(biāo)。對于我們的問題陳述,我們將為我們的模型使用Adam 優(yōu)化器均方誤差

# Compile the model
model.compile(loss='mean_squared_error', optimizer='adam')

訓(xùn)練或擬合模型現(xiàn)在模型已準(zhǔn)備好接受訓(xùn)練。我們將向網(wǎng)絡(luò)提供訓(xùn)練數(shù)據(jù)。此外,我們將指定驗(yàn)證數(shù)據(jù),僅在其上驗(yàn)證模型。

# Training model
model.fit(x_train_noisy, X_train, validation_data=(x_test_noisy, X_test), epochs=2, batch_size=200)

輸出:

在這里,我們只運(yùn)行我們的模型兩個(gè)時(shí)期,但你可以根據(jù)你的問題陳述更改此數(shù)字。你能想出當(dāng)我們改變時(shí)期數(shù)量時(shí)會發(fā)生什么嗎?請考慮一下,將在文章的最后解釋這一點(diǎn)。

評估模型最后,我們將在測試數(shù)據(jù)集上評估我們的訓(xùn)練模型,該數(shù)據(jù)集是我們在加載數(shù)據(jù)集的部分中創(chuàng)建的。

# Final evaluation of the model
pred = model.predict(x_test_noisy)
pred.shape

輸出:

(10000, 784)

X_test.shape

輸出:

(10000, 784)

X_test = numpy.reshape(X_test, (10000,28,28)) *255
pred = numpy.reshape(pred, (10000,28,28)) *255
x_test_noisy = numpy.reshape(x_test_noisy, (-1,28,28)) *255
plt.figure(figsize=(20, 4))
print("Test Images")
for i in range(10,20,1):
   plt.subplot(2, 10, i+1)
   plt.imshow(X_test[i,:,:], cmap='gray')
   curr_lbl = y_test[i]
   plt.title("(Label: " + str(curr_lbl) + ")")
plt.show()    
plt.figure(figsize=(20, 4))
print("Test Images with Noise")
for i in range(10,20,1):
   plt.subplot(2, 10, i+1)
   plt.imshow(x_test_noisy[i,:,:], cmap='gray')
plt.show()    
plt.figure(figsize=(20, 4))
print("Reconstruction of Noisy Test Images")
for i in range(10,20,1):
   plt.subplot(2, 10, i+1)
   plt.imshow(pred[i,:,:], cmap='gray')  
plt.show()

輸出:

在上面的輸出中,圖像:

第一行是原始測試圖像,

第二行是嘈雜的圖像,

第三行用于清理(重建)圖像。

查看清理后的圖像如何與原始圖像相似。

但是如果你仔細(xì)觀察重建的圖像,那么它可能會顯得有些模糊。那么你能不能想出一些可能的原因! 為什么這些圖像在解碼器網(wǎng)絡(luò)的輸出中變得模糊。重建圖像中出現(xiàn)這種模糊的可能原因之一是在訓(xùn)練我們的模型時(shí)使用較少的 epoch。因此,現(xiàn)在你的任務(wù)是增加時(shí)期數(shù)的值,然后再次觀察這些圖像并與這些圖像進(jìn)行比較。

如果我們想在一張圖中總結(jié)整個(gè)過程,下圖是最好的。

我們的實(shí)現(xiàn)到此結(jié)束!

在本教程中,你已經(jīng)構(gòu)建了一個(gè)自動編碼器模型,該模型可以成功清除之前從未見過的噪聲圖像(我們使用了測試數(shù)據(jù)集)。顯然,這些圖像中存在一些未恢復(fù)的失真。然而,如果你考慮噪聲圖像的變形程度,我們可以說我們的模型在恢復(fù)失真圖像方面非常成功。

你可以考慮擴(kuò)展這個(gè)自動編碼器并將其嵌入到照片增強(qiáng)應(yīng)用程序中,這可以增加照片的清晰度。

聲明: 本文由入駐維科號的作者撰寫,觀點(diǎn)僅代表作者本人,不代表OFweek立場。如有侵權(quán)或其他問題,請聯(lián)系舉報(bào)。

發(fā)表評論

0條評論,0人參與

請輸入評論內(nèi)容...

請輸入評論/評論長度6~500個(gè)字

您提交的評論過于頻繁,請輸入驗(yàn)證碼繼續(xù)

  • 看不清,點(diǎn)擊換一張  刷新

暫無評論

暫無評論

人工智能 獵頭職位 更多
掃碼關(guān)注公眾號
OFweek人工智能網(wǎng)
獲取更多精彩內(nèi)容
文章糾錯(cuò)
x
*文字標(biāo)題:
*糾錯(cuò)內(nèi)容:
聯(lián)系郵箱:
*驗(yàn) 證 碼:

粵公網(wǎng)安備 44030502002758號