一文教你如何使用自動編碼器進行圖像去噪
介紹讓我們從理解術語“圖像去噪”的含義來開始我們的討論,這也是我們的文章標題——
圖像去噪是從圖像中去除噪聲的過程
圖像中存在的噪聲可能是由實際上難以處理的各種內在或外在條件引起的。圖像去噪問題是圖像處理和計算機視覺領域的一個非;镜奶魬(zhàn) 。因此,它在許多領域中發(fā)揮著重要作用,獲取原始圖像對于魯棒性能非常重要。
讓我們看看存在噪聲的圖像是什么樣子的:
帶有噪聲的圖像示例
因此,在本文中,我們將看到如何使用自動編碼器或編碼器-解碼器網絡從帶有噪聲的圖像中去除噪聲。
在本文中,我將使用深度人工神經網絡實現自動編碼器。我的下一篇文章中,我還將針對相同的問題陳述使用深度卷積神經網絡來描述自動編碼器。所以,試試這個項目,并在我的下一個教程中繼續(xù)關注我們。
現在,讓我們也看看去除噪聲后圖像的外觀:
對頑皮狗圖像進行降噪之前和降噪之后
現在,讓我們通過了解一些關于自動編碼器的基本概念來開始我們的討論。
編碼器-解碼器網絡(自動編碼器)概述自編碼器是一種無監(jiān)督的人工神經網絡,經過訓練可以將其輸入復制到輸出。對于圖像數據,自動編碼器將首先將圖像編碼為低維表示,然后將該表示解碼回圖像。編碼器-解碼器包含以下兩種結構:編碼器 - 該網絡將數據下采樣到較低的維度。解碼器 -該網絡從較低維度的表示中重建原始數據。較低維度(即編碼器網絡的輸出)表示通常稱為 潛在空間表示。關于自動編碼器,我們必須記住的一件事是,它們只能壓縮與它們接受過訓練的數據相似的數據。它們本質上也是有損的,這意味著相對于原始輸入,輸出將降級。
它們通過反向傳播進行類似于人工神經網絡的訓練。
讓我們開始吧!!加載必要的庫
第一步是加載必要的 Python 庫。我們將導入諸如numpy 之類的庫,用于優(yōu)化矩陣乘法,matplotlib用于數據可視化,例如繪制圖像。來自 Keras 的序列模型為我們提供了一個空的架構,根據我們的架構,我們將在其中添加幾個全連接層,Dense在我們的網絡中創(chuàng)建全連接層,直接從Keras導入MNIST數據集。
import numpy
import matplotlib.pyplot as plt
from keras.models import Sequential
from keras.layers import Dense
from keras.datasets import mnist
現在,我們完成了導入必要庫的第一步,讓我們繼續(xù)以 numpy 的形式加載數據集。
以 Numpy 格式加載數據集
在本文中,我們將使用 MNIST 數據集,這是一個簡單的計算機視覺數據集。它由灰度形式的手寫數字圖像組成。它還包括每個圖像的標簽,告訴我們它是哪個數字(即每個圖像的輸出)。這意味著我們手中有一個標記數據可以使用。MNIST 數據集中的每個圖像都是 28 x 28 像素。
讓我們看看 MNIST 數據集中的一些圖像:
我們將把我們的 MNIST 數據分成兩部分:
訓練數據集: 60,000 個數據點屬于訓練數據集
測試數據集: 10,000 個數據點屬于測試數據集
(X_train, y_train), (X_test, y_test) = mnist.load_data()
輸出:
讓我們借助以下代碼行來看看我們的 NumPy 數組的形狀:
X_train.shape
輸出:
(60000, 28, 28)
上面的輸出表明我們有 60,000 張訓練圖像,每張圖像由 28 x 28 像素組成。
X_test.shape
輸出:
(10000, 28, 28)
上面的輸出表明我們有 10,000 個測試圖像,每個圖像由 28 x 28 像素組成。將圖像繪制為灰度圖像現在,到上述部分,我們將加載完整的數據集,并將其分為訓練集和測試集。因此,在本節(jié)中,我們將使用matplotlib庫繪制一些我們的數據集圖像,具體而言,我們使用的是matplotlib庫的 subplot 函數同時繪制多個圖像。
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 數據我們可以將二維圖像數組展平為28×28=784 個數字的向量。只要我們在圖像之間保持一致,這與我們如何展平陣列無關。從這個角度來看,MNIST 圖像只是784 維向量空間中的一堆點 。但數據應始終采用“ (數據點數,數據點維度)”格式。在這種情況下,訓練數據的格式為60,000×784。
num_pixels = X_train.shape[1] * X_train.shape[2]
X_train = X_train.reshape(X_train.shape[0], num_pixels).astype('float32')
X_test = X_test.reshape(X_test.shape[0], num_pixels).astype('float32')
X_train = X_train / 255
X_test = X_test / 255
讓我們借助以下幾行代碼再次看看我們的 NumPy 數組的形狀:
X_train.shape
輸出:
(60000, 784)
X_test.shape
輸出:
(10000, 784)
給圖像添加噪點在解決問題陳述時,我們必須記住我們的目標是制作一個能夠對圖像執(zhí)行噪聲去除的模型。為了能夠做到這一點,我們將使用現有圖像并給它們添加隨機噪聲。在這里,我們將原始圖像作為輸入,我們將噪聲圖像作為輸出,我們的模型(即自動編碼器)將學習干凈圖像和噪聲圖像之間的關系,并學習如何清理噪聲圖像。因此,讓我們創(chuàng)建 MNIST 數據集的噪聲版本,并將其作為解碼器網絡的輸入。我們首先定義一個噪聲因子,它是一個超參數。噪聲因子乘以均值為 0.0 且標準差為 1.0 的隨機矩陣。該矩陣將從正態(tài)(高斯)分布中抽取樣本。在添加噪聲時,我們必須記住正態(tài)隨機數組的形狀與你將添加噪聲的數據的形狀類似。
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.)
看到上面的代碼,你可能會想,這里為什么要用這個clip函數呢?為了確保我們最終的圖像數組項值在 0 到 1 的范圍內,我們可以使用**np.clip ** 方法。clip 是numpy的函數,用于剪輯min - max范圍之外的值,并用指定的最小或最大值替換它們。
讓我們看看噪聲圖像是什么樣子的:
手寫數字的噪聲圖像定義編碼器-解碼器網絡它將有一個 784 個神經元的輸入層,因為我們的圖像大小為 784,因為存在 28 x 28 個像素(即我們有 784 個神經元的輸入維度和輸出層)。
# create model
model = Sequential()
model.add(Dense(500, input_dim=num_pixels, activation='relu'))
model.add(Dense(300, activation='relu'))
model.add(Dense(100, activation='relu'))
model.add(Dense(300, activation='relu'))
model.add(Dense(500, activation='relu'))
model.add(Dense(784, activation='sigmoid'))
編譯模型一旦定義了模型,我們就必須編譯它。在編譯時,我們提供要使用的損失函數、優(yōu)化器和任何指標。對于我們的問題陳述,我們將為我們的模型使用Adam 優(yōu)化器和均方誤差。
# Compile the model
model.compile(loss='mean_squared_error', optimizer='adam')
訓練或擬合模型現在模型已準備好接受訓練。我們將向網絡提供訓練數據。此外,我們將指定驗證數據,僅在其上驗證模型。
# Training model
model.fit(x_train_noisy, X_train, validation_data=(x_test_noisy, X_test), epochs=2, batch_size=200)
輸出:
在這里,我們只運行我們的模型兩個時期,但你可以根據你的問題陳述更改此數字。你能想出當我們改變時期數量時會發(fā)生什么嗎?請考慮一下,將在文章的最后解釋這一點。
評估模型最后,我們將在測試數據集上評估我們的訓練模型,該數據集是我們在加載數據集的部分中創(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()
輸出:
在上面的輸出中,圖像:
第一行是原始測試圖像,
第二行是嘈雜的圖像,
第三行用于清理(重建)圖像。
查看清理后的圖像如何與原始圖像相似。
但是如果你仔細觀察重建的圖像,那么它可能會顯得有些模糊。那么你能不能想出一些可能的原因! 為什么這些圖像在解碼器網絡的輸出中變得模糊。重建圖像中出現這種模糊的可能原因之一是在訓練我們的模型時使用較少的 epoch。因此,現在你的任務是增加時期數的值,然后再次觀察這些圖像并與這些圖像進行比較。
如果我們想在一張圖中總結整個過程,下圖是最好的。
我們的實現到此結束!
在本教程中,你已經構建了一個自動編碼器模型,該模型可以成功清除之前從未見過的噪聲圖像(我們使用了測試數據集)。顯然,這些圖像中存在一些未恢復的失真。然而,如果你考慮噪聲圖像的變形程度,我們可以說我們的模型在恢復失真圖像方面非常成功。
你可以考慮擴展這個自動編碼器并將其嵌入到照片增強應用程序中,這可以增加照片的清晰度。

最新活動更多
-
10月23日火熱報名中>> 2025是德科技創(chuàng)新技術峰會
-
10月23日立即報名>> Works With 開發(fā)者大會深圳站
-
10月24日立即參評>> 【評選】維科杯·OFweek 2025(第十屆)物聯網行業(yè)年度評選
-
11月27日立即報名>> 【工程師系列】汽車電子技術在線大會
-
12月18日立即報名>> 【線下會議】OFweek 2025(第十屆)物聯網產業(yè)大會
-
精彩回顧立即查看>> 【限時福利】TE 2025國際物聯網展·深圳站