<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          視覺進階 | 用于圖像降噪的卷積自編碼器

          共 10457字,需瀏覽 21分鐘

           ·

          2021-05-30 01:47

          點擊上方小白學視覺”,選擇加"星標"或“置頂

          重磅干貨,第一時間送達

          本文轉(zhuǎn)自:磐創(chuàng)AI

          作者|Dataman

          編譯|Arno

          來源|Analytics Vidhya

          這篇文章的目的是介紹關(guān)于利用自動編碼器實現(xiàn)圖像降噪的內(nèi)容。

          在神經(jīng)網(wǎng)絡(luò)世界中,對圖像數(shù)據(jù)進行建模需要特殊的方法。其中最著名的是卷積神經(jīng)網(wǎng)絡(luò)(CNN或ConvNet)或稱為卷積自編碼器。并非所有的讀者都了解圖像數(shù)據(jù),那么我先簡要介紹圖像數(shù)據(jù)(如果你對這方面已經(jīng)很清楚了,可以跳過)。然后,我會介紹標準神經(jīng)網(wǎng)絡(luò)。這個標準神經(jīng)網(wǎng)絡(luò)用于圖像數(shù)據(jù),比較簡單。這解釋了處理圖像數(shù)據(jù)時為什么首選的是卷積自編碼器。最重要的是,我將演示卷積自編碼器如何減少圖像噪聲。這篇文章將用上Keras模塊和MNIST數(shù)據(jù)。Keras用Python編寫,并且能夠在TensorFlow上運行,是高級的神經(jīng)網(wǎng)絡(luò)API。

          了解圖像數(shù)據(jù)


          如圖(A)所示,圖像由“像素”組成。在黑白圖像中,每個像素由0到255之間的數(shù)字表示。如今大多數(shù)圖像使用24位彩色或更高的顏色。一幅RGB彩色圖像表示一個像素的顏色由紅色、綠色和藍色組成,這三種顏色各自的像素值從0到255。RGB色彩生成器(如下所示)表明,RGB色彩系統(tǒng)利用紅綠藍,組合成各種顏色。因此,一個像素由含三個值的RGB(102、255、102)構(gòu)成,其色號為#66ff66。
          圖 (A)
          寬800像素,高600像素的圖像具有800 x 600 = 480,000像素,即0.48兆像素(“兆像素”等于100萬像素)。分辨率為1024×768的圖像是一個由1,024列和768行構(gòu)成的網(wǎng)格,共有1,024×768 = 0.78兆像素。
          MNIST


          MNIST數(shù)據(jù)庫是一個大型的手寫數(shù)字數(shù)據(jù)庫,通常用于訓練各種圖像處理系統(tǒng)。Keras的訓練數(shù)據(jù)集具備60,000條記錄,而測試數(shù)據(jù)集則包含了10,000條記錄。每條記錄共有28 x 28個像素。
          from keras.layers import Input, Dense
          from keras.models import Model
          from keras.datasets import mnist
          import numpy as np
          (x_train, _), (x_test, _) = mnist.load_data()

          它們看起來怎么樣?我們用繪圖庫及其圖像功能imshow()展示前十條記錄。

          import matplotlib.pyplot as plt

          n = 10  # 顯示的記錄數(shù)
          plt.figure(figsize=(204))
          for i in range(n):
              # 顯示原始圖片
              ax = plt.subplot(2, n, i + 1)
              plt.imshow(x_test[i].reshape(2828))
              plt.gray()
              ax.get_xaxis().set_visible(False)
              ax.get_yaxis().set_visible(False)

          plt.show()

          圖像數(shù)據(jù)的堆疊,用于訓練

          如果要讓神經(jīng)網(wǎng)絡(luò)框架適用于模型訓練,我們可以在一列中堆疊所有28 x 28 = 784個值。第一條記錄的堆疊列如下所示(使用x_train[1].reshape(1,784)):
          然后,我們可以使用標準的神經(jīng)網(wǎng)絡(luò)訓練模型,如圖(B)所示。數(shù)值為784的每個值都是輸入層中的一個節(jié)點。且慢!堆疊數(shù)據(jù)會丟失很多信息嗎?答案是肯定的。圖像中的空間關(guān)系被忽略了。這使得大量的信息丟失。那么,我們接著看卷積自編碼器如何保留空間信息。
          圖(B)
          為什么圖像數(shù)據(jù)首選卷積自編碼器?


          可以看到,數(shù)據(jù)切片和數(shù)據(jù)堆疊會導致信息大量丟失。卷積自編碼器放棄堆疊數(shù)據(jù),使圖像數(shù)據(jù)輸入時保持其空間信息不變,并在卷積層中以溫和的方式提取信息。圖(D)演示了將平面2D圖像先提取到一個厚的正方體(Conv1),再提取到一個長方體(Conv2)和另一個長度更長的長方體(Conv3)。此過程旨在保留數(shù)據(jù)中的空間關(guān)系。這是自動編碼器的編碼過程。中間部分是一個完全連接的自動編碼器,其隱藏層僅由10個神經(jīng)元組成。然后就是解碼過程。三個立方體將會展平,最后變成2D平面圖像。圖(D)的編碼器和解碼器是對稱的。實際上,編碼器和解碼器不要求對稱。
          圖(D)
          卷積自編碼器如何工作?


          上面的數(shù)據(jù)析取似乎很神奇。數(shù)據(jù)析取究竟是如何進行的?這包括以下三層:卷積層,線性整流層和池化層。
          圖 (E): 特征圖

          1.    卷積層

          卷積步驟會生成很多小塊,稱為特征圖或特征,如圖(E)的綠色、紅色或深藍色的正方形。這些正方形保留了輸入圖像中像素之間的關(guān)系。如圖(F)所示,每個特征掃描原始圖像。這一產(chǎn)生分值的過程稱為卷積。
          圖 (F): 過濾過程
          掃描完原始圖像后,每個特征都會生成高分值和低分值的濾波圖像,如圖(G)所示。如果匹配完美,那塊正方形的得分就高。如果匹配度低或不匹配,則得分低或為零。例如,原始圖像有四個區(qū)域與紅色方塊完全匹配,那么這四個區(qū)域的得分都很高。
          圖 (G)
          過濾器越多,模型可以提取的特征就越多。但是,特征越多,訓練時間也就越長。因此,最好還是選擇最少的過濾器提取特征。

          1.1填充

          特征如何確定匹配項?一種超參數(shù)是填充,有兩種選擇:(i)用零填充原始圖像以符合該特征,或(ii)刪除原始圖像中不符的部分并保留有效部分。

          1.2步長

          卷積層的另一個參數(shù):步長。步長是輸入矩陣上移動的像素個數(shù)。當步長為1時,過濾器一次移動1個像素。在Keras代碼中,我們將其視為超參數(shù)。

          2.線性整流步驟

          線性整流單位(ReLU)的步驟與典型的神經(jīng)網(wǎng)絡(luò)相同。它將所有的負值校正為零,確保數(shù)學運算正確。

          3.最大池化層

          池化會縮小圖像尺寸。在圖(H)中,一個2 x 2的窗口(稱為池的大小)掃描每個濾波圖像,并將該2 x 2窗口的最大值劃分給新圖像中大小為1 x 1的正方形。如圖(H)所示,第一個2 x 2窗口的最大值分數(shù)高(用紅色表示),因此高分劃分給1 x 1正方形。
          圖 (H): 最大池化
          除了采用最大值之外,其他不常用的池化方法還包括“平均池化”(取平均值)或“總和池化”(總和)。
          圖 (J)
          池化后,會生成新的更小的濾波圖像。現(xiàn)在我們拆分這個濾波圖像,然后堆疊為一列,如圖(J)所示。
          Keras模型


          以上三層是卷積神經(jīng)網(wǎng)絡(luò)的構(gòu)建塊。Keras具有以下兩個功能:
          ?    Conv2D(filters, kernel_size, activation = 'reLu', strides=1):核尺寸(kernel_size)是2D卷積窗口的高度和寬度。圖(E)使用的是2×2正方形,所以例子中核尺寸將為(2,2)。步長是輸入矩陣上移動的像素個數(shù)。我們一次將濾鏡移動了1個像素,所以步長為1。
          ?    MaxPooling2D(pool_size=(2,2)):在圖(H)中,我們使用2×2窗口作為池的大小。因此,我們將在以下代碼中使用(2,2)。
          你可以在卷積自編碼器中構(gòu)建許多卷積層。在圖(E)中,在編碼部分有三層,分別標記為Conv1,Conv2和Conv3。因此,我們要進行相應(yīng)的構(gòu)建。
          ?    下面的代碼input_img = Input(shape=(28,28,1)表明輸入的2D圖像為28 x 28。
          ?    然后,它構(gòu)建了Conv1,Conv2和Conv3。
          ?    請注意,Conv1在Conv2內(nèi)部,而Conv2在Conv3內(nèi)部。
          ?    要是過濾器無法適應(yīng)輸入圖像,填充將指定下一步該做什么。padding='valid'表示過濾器不符合,圖像的一部分將被丟棄;padding='same'用零填充圖片以適應(yīng)圖片。
          from keras.layers import Input, Dense, Conv2D, MaxPooling2D, UpSampling2D
          from keras.models import Model

          # 編碼過程
          input_img = Input(shape=(28281))  

          ############
          # 編碼 #
          ############

          # Conv1 #
          x = Conv2D(filters = 16, kernel_size = (33), activation='relu', padding='same')(input_img)
          x = MaxPooling2D(pool_size = (22), padding='same')(x)

          # Conv2 #
          x = Conv2D(filters = 8, kernel_size = (33), activation='relu', padding='same')(x)
          x = MaxPooling2D(pool_size = (22), padding='same')(x) 

          # Conv 3 #
          x = Conv2D(filters = 8, (33), activation='relu', padding='same')(x)
          encoded = MaxPooling2D(pool_size = (22), padding='same')(x)

          # 注意:
          # padding 是一個超參數(shù),值'valid' or 'same'. 
          # "valid" 意味不需要填充 
          # "same" 填充輸入,使輸出具有與原始輸入相同的長度。 

          然后,解碼過程繼續(xù)。因此,下面解碼部分已全部完成編碼和解碼過程。

          ############
          # 解碼 #
          ############

          # DeConv1
          x = Conv2D(8, (33), activation='relu', padding='same')(encoded)
          x = UpSampling2D((22))(x)

          # DeConv2
          x = Conv2D(8, (33), activation='relu', padding='same')(x)
          x = UpSampling2D((22))(x)

          # Deconv3
          x = Conv2D(16, (33), activation='relu')(x)
          x = UpSampling2D((22))(x)
          decoded = Conv2D(1, (33), activation='sigmoid', padding='same')(x)

          該Keras API需要模型和優(yōu)化方法的聲明:

          ?  Model (inputs= input_img,outputs= decoded):
          在解碼給定輸入數(shù)據(jù)input_img的情況下,模型包括計算輸出所需的所有層。compile(optimizer='adadelta',loss='binary_crossentropy'):優(yōu)化程序會像漸變梯度一樣執(zhí)行優(yōu)化操作。最常見的是隨機梯度下降(SGD),自適應(yīng)梯度(Adagrad)和Adadelta(Adadelta是Adagrad的擴展)。有關(guān)詳細信息,請參見Keras優(yōu)化器文檔。損失函數(shù)可以查找Keras損失文檔。
          # 聲明模型
          autoencoder = Model(input_img, decoded)
          autoencoder.compile(optimizer='adadelta', loss='binary_crossentropy')
          下面,我使用x_train作為輸入和輸出來訓練模型。batch_size是樣本量和epochs是迭代的次數(shù)。我指定shuffle=True打亂訓練數(shù)據(jù)。
          # 訓練模型
          autoencoder.fit(x_train, x_train,
                          epochs=100,
                          batch_size=128,
                          shuffle=True,
                          validation_data=(x_test, x_test)
                         )
          我們可以打印出前十張原始圖像和相同十張圖像的預測。
          decoded_imgs = autoencoder.predict(x_test)

          n = 10

          plt.figure(figsize=(204))
          for i in range(n):
              # 顯示原始圖像
              ax = plt.subplot(2, n, i + 1)
              plt.imshow(x_test[i].reshape(2828))
              plt.gray()
              ax.get_xaxis().set_visible(False)
              ax.get_yaxis().set_visible(False)

              # 顯示重構(gòu)后的圖像
              ax = plt.subplot(2, n, i+1+n)
              plt.imshow(decoded_imgs[i].reshape(2828))
              plt.gray()
              ax.get_xaxis().set_visible(False)
              ax.get_yaxis().set_visible(False)
          plt.show()
          如何構(gòu)建圖像降噪卷積自編碼器?


          圖像降噪的想法是訓練一個模型,輸入噪聲數(shù)據(jù),并輸出它們各自清晰的數(shù)據(jù)。這是與上述模型的唯一區(qū)別。首先讓我們向數(shù)據(jù)添加噪音。
          noise_factor = 0.4
          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.)

          前十張噪聲圖像如下所示:

          n = 10
          plt.figure(figsize=(202))
          for i in range(n):
              ax = plt.subplot(1, n, i+1)
              plt.imshow(x_test_noisy[i].reshape(2828))
              plt.gray()
              ax.get_xaxis().set_visible(False)
              ax.get_yaxis().set_visible(False)
          plt.show()

          然后,我們訓練模型時將輸入噪聲數(shù)據(jù),輸出干凈的數(shù)據(jù)。

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

          最后,我們打印出前十個噪點圖像以及相應(yīng)的降噪圖像。

          decoded_imgs = autoencoder.predict(x_test)

          n = 10

          plt.figure(figsize=(204))
          for i in range(n):
              # 顯示原始圖像
              ax = plt.subplot(2, n, i + 1)
              plt.imshow(x_test_noisy[i].reshape(2828))
              plt.gray()
              ax.get_xaxis().set_visible(False)
              ax.get_yaxis().set_visible(False)

              # 顯示重構(gòu)后的圖像
              ax = plt.subplot(2, n, i+1+n)
              plt.imshow(decoded_imgs[i].reshape(2828))
              plt.gray()
              ax.get_xaxis().set_visible(False)
              ax.get_yaxis().set_visible(False)
          plt.show()
          是否可以使用任何經(jīng)過訓練的CNN代碼嗎?


          可以的。如果你有興趣學習代碼,Keras提供了幾個經(jīng)過預訓練的CNN,包括Xception,VGG16,VGG19,ResNet50,InceptionV3,InceptionResNetV2,MobileNet,DenseNet,NASNet和MobileNetV2。值得一提的是,你可以出于研究目的付錢或下載此大型圖像數(shù)據(jù)庫ImageNet。


          下載1:OpenCV-Contrib擴展模塊中文版教程
          在「小白學視覺」公眾號后臺回復:擴展模塊中文教程即可下載全網(wǎng)第一份OpenCV擴展模塊教程中文版,涵蓋擴展模塊安裝、SFM算法、立體視覺、目標跟蹤、生物視覺、超分辨率處理等二十多章內(nèi)容。

          下載2:Python視覺實戰(zhàn)項目52講
          小白學視覺公眾號后臺回復:Python視覺實戰(zhàn)項目即可下載包括圖像分割、口罩檢測、車道線檢測、車輛計數(shù)、添加眼線、車牌識別、字符識別、情緒檢測、文本內(nèi)容提取、面部識別等31個視覺實戰(zhàn)項目,助力快速學校計算機視覺。

          下載3:OpenCV實戰(zhàn)項目20講
          小白學視覺公眾號后臺回復:OpenCV實戰(zhàn)項目20講,即可下載含有20個基于OpenCV實現(xiàn)20個實戰(zhàn)項目,實現(xiàn)OpenCV學習進階。

          交流群


          歡迎加入公眾號讀者群一起和同行交流,目前有SLAM、三維視覺、傳感器、自動駕駛、計算攝影、檢測、分割、識別、醫(yī)學影像、GAN、算法競賽等微信群(以后會逐漸細分),請掃描下面微信號加群,備注:”昵稱+學校/公司+研究方向“,例如:”張三 + 上海交大 + 視覺SLAM“。請按照格式備注,否則不予通過。添加成功后會根據(jù)研究方向邀請進入相關(guān)微信群。請勿在群內(nèi)發(fā)送廣告,否則會請出群,謝謝理解~


          瀏覽 41
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  免费欧美小黄片 | 亚洲无吗高清视频 | 国产乱伦a片视频 | 一区二区三区精品久久 | 天天天天爽夜夜夜夜爽 |