當前位置:
首頁 > 新聞 > 「實戰」利用卷積自編碼器實現圖片降噪(代碼開源)

「實戰」利用卷積自編碼器實現圖片降噪(代碼開源)

「實戰」利用卷積自編碼器實現圖片降噪(代碼開源)

1新智元推薦

「實戰」利用卷積自編碼器實現圖片降噪(代碼開源)

前言

這周工作太忙,本來想更把Attention tranlsation寫出來,但一直抽不出時間,等後面有時間再來寫。我們這周來看一個簡單的自編碼器實戰代碼,關於自編碼器的理論介紹我就不詳細介紹了,網上一搜一大把。最簡單的自編碼器就是通過一個encoder和decoder來對輸入進行復現,例如我們將一個圖片輸入到一個網路中,自編碼器的encoder對圖片進行壓縮,得到壓縮後的信息,進而decoder再將這個信息進行解碼從而復現原圖。

「實戰」利用卷積自編碼器實現圖片降噪(代碼開源)

作圖工具:OmniGraffle

自編碼器實際上是通過去最小化target和input的差別來進行優化,即讓輸出層儘可能地去復現原來的信息。由於自編碼器的基礎形式比較簡單,對於它的一些變體也非常之多,包括DAE,SDAE,VAE等等,如果感興趣的小夥伴可以去網上搜一下其他相關信息。

本篇文章將實現兩個Demo,第一部分即實現一個簡單的input-hidden-output結的自編碼器,第二部分將在第一部分的基礎上實現卷積自編碼器來對圖片進行降噪。

工具說明

  • TensorFlow1.0

  • jupyter notebook

  • 數據:MNIST手寫數據集

  • 完整代碼地址:NELSONZHAO/zhihu

第一部分

首先我們將實現一個如上圖結構的最簡單的AutoEncoder。

載入數據

在這裡,我們使用MNIST手寫數據集來進行實驗。首先我們需要導入數據,TensorFlow已經封裝了這個實驗數據集,所以我們使用起來也非常簡單。

「實戰」利用卷積自編碼器實現圖片降噪(代碼開源)


如果想讓數據顯示灰度圖像,使用代碼plt.imshow(img.reshape((28,28)), cmap="Greys_r")即可。

通過input_data就可以載入我們的數據集。如果小夥伴本地已經有了MNIST數據集(四個壓縮包),可以把這四個壓縮包放在目錄MNIST_data下,這樣TensorFlow就會直接Extract數據,而不用再重新下載。我們可以通過imshow來隨便查看一個圖像。由於我們載入進來的數據已經被處理成一個784維度的向量,因此重新顯示的時候需要reshape一下。

構建模型

我們把數據載入進來以後就可以進行最簡單的建模。在這之前,我們首先來獲取一下input數據的大小,我們載入進來的圖片是28x28的像素塊,TensorFlow已經幫我們處理成了784維度的向量。同時我們還需要指定一下hidden layer的大小。

「實戰」利用卷積自編碼器實現圖片降噪(代碼開源)

在這裡我指定了64,hidden_units越小,意味著信息損失的越多,小夥伴們也可以嘗試一下其他的大小來看看結果。

AutoEncoder 中包含了 input,hidden 和 output 三層:

「實戰」利用卷積自編碼器實現圖片降噪(代碼開源)


在隱層,我們採用了ReLU作為激活函數。

至此,一個簡單的AutoEncoder就構造完成,接下來我們可以啟動TensorFlow的graph來進行訓練。

「實戰」利用卷積自編碼器實現圖片降噪(代碼開源)

訓練結果可視化

經過上面的步驟,我們構造了一個簡單的AutoEncoder,下面我們將對結果進行可視化看一下它的表現。

「實戰」利用卷積自編碼器實現圖片降噪(代碼開源)

這裡,我挑選了測試數據集中的5個樣本來進行可視化,同樣的,如果想觀察灰度圖像,指定cmap參數為"Greys_r"即可。上面一行為test數據集中原始圖片,第二行是經過AutoEncoder復現以後的圖片,可以很明顯的看到像素信息的損失。

同樣,我們也可以把隱層壓縮的數據拿出來可視化,結果如下:

「實戰」利用卷積自編碼器實現圖片降噪(代碼開源)

這五張圖分別對應了test中五張圖片的隱層壓縮後的圖像。

通過上面一個簡單的例子,我們了解了AutoEncoder的基本工作原理,下面我們將更進一步改進我們的模型,將隱層轉換為卷積層來進行圖像降噪。


上面過程中省略了一部分代碼,完整代碼請去作者的GitHub上查看。

第二部分

在了解了上面AutoEncoder工作原理的基礎上,我們在這一部分將對AutoEncoder加入多個卷積層來進行圖片的降噪處理。


如果有小夥伴對卷積神經網路不清楚的話,可以去知乎看看大神們的文章來學習一下。

同樣的我們還是使用MNIST數據集來進行實驗,關於數據導入的步驟不再贅述,請下載代碼查看。在開始之前,我們先通過一張圖片來看一下我們的整個模型結構:

「實戰」利用卷積自編碼器實現圖片降噪(代碼開源)

作圖工具:OmniGraffle

我們通過向模型輸入一個帶有雜訊的圖片,在輸出端給模型沒有雜訊的圖片,讓模型通過卷積自編碼器去學習降噪的過程。

輸入層

「實戰」利用卷積自編碼器實現圖片降噪(代碼開源)

這裡的輸入層和我們上一部分的輸入層已經不同,因為這裡我們要使用卷積操作,因此,輸入層應該是一個height x width x depth的一個圖像,一般的圖像depth是RGB格式三層,這裡我們的MNIST數據集的depth只有1。

Encoder卷積層

Encoder卷積層設置了三層卷積加池化層,對圖像進行處理。

「實戰」利用卷積自編碼器實現圖片降噪(代碼開源)

第一層卷積中,我們使用了64個大小為3 x 3 的濾波器(filter),strides默認為1,padding設置為same後我們的height和width不會被改變,因此經過第一層卷積以後,我們得到的數據從最初的28 x 28 x 1 變為 28 x 28 x 64。

緊接著對卷積結果進行最大池化操作(max pooling),這裡我設置了size和stride都是2 x 2,池化操作不改變卷積結果的深度,因此池化以後的大小為 14 x 14 x 64。

對於其他卷積層不再贅述。所有卷積層的激活函數都是用了ReLU。

經過三層的卷積和池化操作以後,我們得到的conv3實際上就相當於上一部分中AutoEncoder的隱層,這一層的數據已經被壓縮為4 x 4 x 32的大小。

至此,我們就完成了Encoder端的卷積操作,數據維度從開始的28 x 28 x 1變成了4 x 4 x 32。

Decoder卷積層

接下來我們就要開始進行Decoder端的卷積。在這之前,可能有小夥伴要問了,既然Encoder中都已經把圖片捲成了4 x 4 x 32,我們如果繼續在Decoder進行卷積的話,那豈不是得到的數據size越來越小?所以,在Decoder端,我們並不是單純進行卷積操作,而是使用了Upsample(中文翻譯可以為上採樣)+ 卷積的組合。

我們知道卷積操作是通過一個濾波器對圖片中的每個patch進行掃描,進而對patch中的像素塊加權求和後再進行非線性處理。舉個例子,原圖中我們的patch的大小假如是3 x 3(說的通俗點就是一張圖片中我們取其中一個3 x 3大小的像素塊出來),接著我們使用3 x 3的濾波器對這個patch進行處理,那麼這個patch經過卷積以後就變成了1個像素塊。在Deconvolution中(或者叫transposed convolution)這一過程是反過來的,1個像素塊會被擴展成3 x 3的像素塊。

但是Deconvolution有一些弊端,它會導致圖片中出現checkerboard patterns,這是因為在Deconvolution的過程中,濾波器中會出現很多重疊。為了解決這個問題,有人提出了使用Upsample加卷積層來進行解決。


關於Upsample有兩種常見的方式,一種是nearest neighbor interpolation,另一種是bilinear interpolation。

本文也會使用Upsample加卷積的方式來進行Decoder端的處理。

「實戰」利用卷積自編碼器實現圖片降噪(代碼開源)

在TensorFlow中也封裝了對Upsample的操作,我們使用resize_nearest_neighbor對Encoder卷積的結果resize,進而再進行卷積處理。經過三次Upsample的操作,我們得到了28 x 28 x 64的數據大小。最後,我們要將這個結果再進行一次卷積,處理成我們原始圖像的大小。

「實戰」利用卷積自編碼器實現圖片降噪(代碼開源)

最後一步定義loss和optimizer。

「實戰」利用卷積自編碼器實現圖片降噪(代碼開源)

loss函數我們使用了交叉熵進行計算,優化函數學習率為0.001。

構造雜訊數據

通過上面的步驟我們就構造完了整個卷積自編碼器模型。由於我們想通過這個模型對圖片進行降噪,因此在訓練之前我們還需要在原始數據的基礎上構造一下我們的雜訊數據。

「實戰」利用卷積自編碼器實現圖片降噪(代碼開源)

我們通過上面一個簡單的例子來看一下如何加入雜訊,我們獲取一張圖片的數據img(大小為784),在它的基礎上加入雜訊因子乘以隨機數的結果,就會改變圖片上的像素。接著,由於MNIST數據的每個像素數據都被處理成了0-1之間的數,所以我們通過numpy.clip對加入雜訊的圖片進行clip操作,保證每個像素數據還是在0-1之間。


np.random.randn(*img.shape)的操作等於np.random.randn(img.shape[0], img.shape[1])

我們下來來看一下加入雜訊前後的圖像對比。

「實戰」利用卷積自編碼器實現圖片降噪(代碼開源)

訓練模型

介紹完模型構建和雜訊處理,我們接下來就可以訓練我們的模型了。

「實戰」利用卷積自編碼器實現圖片降噪(代碼開源)

在訓練模型時,我們的輸入已經變成了加入雜訊後的數據,而輸出是我們的原始沒有雜訊的數據,主要要對原始數據進行reshape操作,變成與inputs_相同的格式。由於卷積操作的深度,所以模型訓練時候有些慢,建議使用GPU跑。


記得最後關閉sess。

結果可視化

經過上面漫長的訓練,我們的模型終於訓練好了,接下來我們就通過可視化來看一看模型的效果如何。

「實戰」利用卷積自編碼器實現圖片降噪(代碼開源)

可以看到通過卷積自編碼器,我們的降噪效果還是非常好的,最終生成的圖片看起來非常順滑,雜訊也幾乎看不到了。

有些小夥伴可能就會想,我們也可以用基礎版的input-hidden-output結構的AutoEncoder來實現降噪。因此我也實現了一版用最簡單的input-hidden-output結構進行降噪訓練的模型(代碼在我的GitHub)。我們來看看它的結果:

「實戰」利用卷積自編碼器實現圖片降噪(代碼開源)

可以看出,跟卷積自編碼器相比,它的降噪效果更差一些,在重塑的圖像中還可以看到一些雜訊的影子。

結尾

至此,我們完成了基礎版本的AutoEncoder模型,還在此基礎上加入卷積層來進行圖片降噪。相信小夥伴對AntoEncoder也有了一個初步的認識。

完整的代碼已經放在我的GitHub(NELSONZHAO/zhihu)上,其中包含了六個文件:

  • BasicAE,基礎版本的AutoEncoder(包含jupyter notebook和html兩個文件)

  • EasyDAE,基礎版本的降噪AutoEncoder(包含jupyter notebook和html兩個文件)

  • ConvDAE,卷積降噪AutoEncoder(包含jupyter notebook和html兩個文件)

如果覺得不錯,可以給我的GitHub點個star就更好啦!

本文作者天雨粟,經作者授權轉載自知乎專欄,特此感謝!

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 新智元 的精彩文章:

楊靜:人工智慧鴻溝或將割裂世界

TAG:新智元 |

您可能感興趣

實戰:圖片上傳組件開發
裝修效果圖:30張電視背景牆圖片,顏值實用性一手抓!
實戰篇@FastDFS搭建圖片伺服器單實例
實用性圖片:衛生間裝飾,窗檯圖片素材
木工鏤銑刀具應用圖片
「好奇號」火星探測器發回無價精美圖片
瀏覽器批量保存圖片
工作室發布王源睡覺的圖片,而粉絲關注的是圖片上的武器
用堅實證據支撐正義的審判:戰後搜集南京大屠殺證據真實圖片
利用畫圖工具完成幾張圖片的拼圖效果
動物圖片:蜘蛛圖片
PS教程將圖片轉為水彩筆繪製效果
掃描圖片完美無縫拼接-實測好用
精品槍械漂亮的圖片
圖片點評 構圖規矩
電木銑常用刀頭及加工效果圖片
手機上的專業圖片處理及視頻編輯器
工作流:圖片轉文字
PS之巧用仿製圖章工具去除圖片水印
我自控力特別差!斗圖表情包搞笑圖片