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

          深度學(xué)習(xí)項(xiàng)目示例 | 手把手教你使用自編碼器進(jìn)行模糊圖像修復(fù)

          共 6353字,需瀏覽 13分鐘

           ·

          2022-04-24 21:07


          來(lái)源:DeepHub IMBA

          本文約2600字,建議閱讀9分鐘

          本文教你如何應(yīng)用深度學(xué)習(xí)處理模糊圖像。


          圖像模糊是由相機(jī)或拍攝對(duì)象移動(dòng)、對(duì)焦不準(zhǔn)確或使用光圈配置不當(dāng)導(dǎo)致的圖像不清晰。為了獲得更清晰的照片,我們可以使用相機(jī)鏡頭的首選焦點(diǎn)重新拍攝同一張照片,或者使用深度學(xué)習(xí)知識(shí)重現(xiàn)模糊的圖像。由于我的專(zhuān)長(zhǎng)不是攝影,只能選擇使用深度學(xué)習(xí)技術(shù)對(duì)圖像進(jìn)行去模糊處理!


          在開(kāi)始這個(gè)項(xiàng)目之前,本文假定讀者應(yīng)該了解深度學(xué)習(xí)的基本概念,例如神經(jīng)網(wǎng)絡(luò)、CNN。還要稍微熟悉一下 Keras、Tensorflow 和 OpenCV。

          有各種類(lèi)型的模糊——運(yùn)動(dòng)模糊、高斯模糊、平均模糊等。但我們將專(zhuān)注于高斯模糊圖像。在這種模糊類(lèi)型中,像素權(quán)重是不相等的。模糊在中心處較高,在邊緣處按照鐘形曲線(xiàn)減少。


          數(shù)據(jù)集


          在開(kāi)始使用代碼之前,首先需要的是一個(gè)由 2 組圖像組成的數(shù)據(jù)集——模糊圖像和干凈圖像。目前可能沒(méi)有現(xiàn)成的數(shù)據(jù)集可以使用,但是就像我們上面所說(shuō)的,如果你有opencv的基礎(chǔ)這個(gè)對(duì)于我們來(lái)說(shuō)是非常個(gè)簡(jiǎn)單的,只要我們有原始圖像,使用opencv就可以自己生成訓(xùn)練需要的數(shù)據(jù)集。

          這里我的數(shù)據(jù)集大小約為 50 張圖像(50 張干凈圖像和 50 張模糊圖像),因?yàn)橹皇茄菔灸康乃灾贿x擇了少量圖像。

          編寫(xiě)代碼


          已經(jīng)準(zhǔn)備好數(shù)據(jù)集,可以開(kāi)始編寫(xiě)代碼了。

          依賴(lài)項(xiàng)

          import numpy as npimport pandas as pdimport matplotlib.pyplot as plt
          %matplotlib inlineimport randomimport cv2import osimport tensorflow as tffrom tqdm import tqdm

          這里導(dǎo)入了 tqdm 庫(kù)來(lái)幫助我創(chuàng)建進(jìn)度條,這樣可以知道運(yùn)行代碼需要多長(zhǎng)時(shí)間。

          導(dǎo)入數(shù)據(jù)

          good_frames = '/content/drive/MyDrive/mini_clean'bad_frames = '/content/drive/MyDrive/mini_blur'

          現(xiàn)在創(chuàng)建了2 個(gè)列表。我們將使用 keras 預(yù)處理庫(kù)讀取“.jpg”、“jpeg”或“.png”類(lèi)型的圖像,并轉(zhuǎn)換為數(shù)組。這里圖像尺寸為 128x128。

          clean_frames = []for file in tqdm(sorted(os.listdir(good_frames))):if any(extension in file for extension in ['.jpg', 'jpeg', '.png']):  image = tf.keras.preprocessing.image.load_img(good_frames + '/' + file, target_size=(128,128))  image = tf.keras.preprocessing.image.img_to_array(image).astype('float32') / 255  clean_frames.append(image)
          clean_frames = np.array(clean_frames)
          blurry_frames = []for file in tqdm(sorted(os.listdir(bad_frames))):if any(extension in file for extension in ['.jpg', 'jpeg', '.png']): image = tf.keras.preprocessing.image.load_img(bad_frames + '/' + file, target_size=(128,128)) image = tf.keras.preprocessing.image.img_to_array(image).astype('float32') / 255 blurry_frames.append(image)
          blurry_frames = np.array(blurry_frames)

          導(dǎo)入模型庫(kù)

          from keras.layers import Dense, Inputfrom keras.layers import Conv2D, Flattenfrom keras.layers import Reshape, Conv2DTransposefrom keras.models import Modelfrom keras.callbacks import ReduceLROnPlateau, ModelCheckpointfrom keras.utils.vis_utils import plot_modelfrom keras import backend as K
          random.seed = 21np.random.seed = seed

          將數(shù)據(jù)集拆分為訓(xùn)練集和測(cè)試集

          現(xiàn)在我們按 80:20 的比例將數(shù)據(jù)集分成訓(xùn)練和測(cè)試集。


          x = clean_frames;y = blurry_frames;
          from sklearn.model_selection import train_test_splitx_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=42)


          檢查訓(xùn)練和測(cè)試數(shù)據(jù)集的形狀。


          print(x_train[0].shape)print(y_train[0].shape)
          r = random.randint(0, len(clean_frames)-1)print(r)fig = plt.figure()fig.subplots_adjust(hspace=0.1, wspace=0.2)ax = fig.add_subplot(1, 2, 1)ax.imshow(clean_frames[r])ax = fig.add_subplot(1, 2, 2)ax.imshow(blurry_frames[r])

          上面的代碼可以查看來(lái)自訓(xùn)練和測(cè)試數(shù)據(jù)集的圖像,例如:


          下面初始化一些編寫(xiě)模型時(shí)需要用到的參數(shù):

          # Network Parametersinput_shape = (128, 128, 3)batch_size = 32kernel_size = 3latent_dim = 256
          # Encoder/Decoder number of CNN layers and filters per layerlayer_filters = [64, 128, 256]

          編碼器模型

          自編碼器的結(jié)構(gòu)我們以前的文章中已經(jīng)詳細(xì)介紹過(guò)多次了,這里就不詳細(xì)說(shuō)明了:

          inputs = Input(shape = input_shape, name = 'encoder_input')x = inputs

          首先就是輸入(圖片的數(shù)組),獲取輸入后構(gòu)建一個(gè) Conv2D(64) - Conv2D(128) - Conv2D(256) 的簡(jiǎn)單的編碼器,編碼器將圖片壓縮為 (16, 16, 256) ,該數(shù)組將會(huì)是解碼器的輸入。

          for filters in layer_filters:  x = Conv2D(filters=filters,              kernel_size=kernel_size,              strides=2,              activation='relu',              padding='same')(x)shape = K.int_shape(x)x = Flatten()(x)latent = Dense(latent_dim, name='latent_vector')(x)

          這里的 K.int_shape()將張量轉(zhuǎn)換為整數(shù)元組。

          實(shí)例化編碼器模型,如下:

          encoder = Model(inputs, latent, name='encoder')encoder.summary()

          解碼器模型

          解碼器模型類(lèi)似于編碼器模型,但它進(jìn)行相反的計(jì)算。解碼器已將輸入解碼回 (128, 128, 3)。所以這里的將使用 Conv2DTranspose(256) - Conv2DTranspose(128) - Conv2DTranspose(64)。

          latent_inputs = Input(shape=(latent_dim,), name='decoder_input')x = Dense(shape[1]*shape[2]*shape[3])(latent_inputs)x = Reshape((shape[1], shape[2], shape[3]))(x)for filters in layer_filters[::-1]:  x = Conv2DTranspose(filters=filters,                      kernel_size=kernel_size,                      strides=2,                      activation='relu',                      padding='same')(x)
          outputs = Conv2DTranspose(filters=3, kernel_size=kernel_size, activation='sigmoid', padding='same', name='decoder_output')(x)

          解碼器如下:

          decoder = Model(latent_inputs, outputs, name='decoder')decoder.summary()

          整合成自編碼器

          自編碼器 = 編碼器 + 解碼器

          autoencoder = Model(inputs, decoder(encoder(inputs)), name='autoencoder')autoencoder.summary()

          最后但是非常重要的是在訓(xùn)練我們的模型之前需要設(shè)置超參數(shù)。


          autoencoder.compile(loss='mse', optimizer='adam',metrics=["acc"])


          我選擇損失函數(shù)為均方誤差,優(yōu)化器為adam,評(píng)估指標(biāo)為準(zhǔn)確率。然后還需要定義學(xué)習(xí)率調(diào)整的計(jì)劃,這樣可以在指標(biāo)沒(méi)有改進(jìn)的情況下降低學(xué)習(xí)率:


          lr_reducer = ReduceLROnPlateau(factor=np.sqrt(0.1),                              cooldown=0,                              patience=5,                              verbose=1,                              min_lr=0.5e-6)

          學(xué)習(xí)率的調(diào)整需要在訓(xùn)練的每個(gè)輪次都調(diào)用:


          callbacks = [lr_reducer]

          訓(xùn)練模型

          history = autoencoder.fit(blurry_frames,                    clean_frames,                    validation_data=(blurry_frames, clean_frames),                    epochs=100,                    batch_size=batch_size,                    callbacks=callbacks)

          運(yùn)行此代碼后,可能需要大約 5-6 分鐘甚至更長(zhǎng)時(shí)間才能看到最終輸出,因?yàn)槲覀冊(cè)O(shè)置了訓(xùn)練輪次為100:


          最后結(jié)果


          現(xiàn)在已經(jīng)成功訓(xùn)練了模型,讓我們看看我們的模型的預(yù)測(cè):

          print("\n       Input                       Ground Truth                 Predicted Value")
          for i in range(3):
          r = random.randint(0, len(clean_frames)-1)
          x, y = blurry_frames[r],clean_frames[r] x_inp=x.reshape(1,128,128,3) result = autoencoder.predict(x_inp) result = result.reshape(128,128,3)
          fig = plt.figure(figsize=(12,10)) fig.subplots_adjust(hspace=0.1, wspace=0.2)
          ax = fig.add_subplot(1, 3, 1) ax.imshow(x)
          ax = fig.add_subplot(1, 3, 2) ax.imshow(y)
          ax = fig.add_subplot(1, 3, 3) plt.imshow(result)


          可以看到該模型在去模糊圖像方面做得很好,并且?guī)缀跄軌颢@得原始圖像。因?yàn)槲覀冎挥昧?層的卷積架構(gòu),所以如果我們使用更深的模型,還有一些超參數(shù)的調(diào)整應(yīng)該會(huì)獲得更好的結(jié)果。

          為了查看訓(xùn)練的情況,可以繪制損失函數(shù)和準(zhǔn)確率的圖表,可以通過(guò)這些數(shù)據(jù)做出更好的決策。

          損失的變化

          plt.figure(figsize=(12,8))plt.plot(history.history['loss'])plt.plot(history.history['val_loss'])plt.legend(['Train', 'Test'])plt.xlabel('Epoch')plt.ylabel('Loss')plt.xticks(np.arange(0, 101, 25))plt.show()

          可以看到損失顯著減少,然后從第 80 個(gè) epoch 開(kāi)始停滯不前。

          準(zhǔn)確率

          plt.figure(figsize=(12,8))plt.plot(history.history['acc'])plt.plot(history.history['val_acc'])plt.legend(['Train', 'Test'])plt.xlabel('Epoch')plt.ylabel('Accuracy')plt.xticks(np.arange(0, 101, 25))plt.show()

          這里可以看到準(zhǔn)確率顯著提高,如果訓(xùn)練更多輪,它可能會(huì)進(jìn)一步提高。因此,可以嘗試增加 epoch 大小并檢查準(zhǔn)確率是否確實(shí)提高了,或者增加早停機(jī)制,讓訓(xùn)練自動(dòng)停止。

          總結(jié)


          我們?nèi)〉昧瞬诲e(cuò)的準(zhǔn)確率,為 78.07%。對(duì)于實(shí)際的應(yīng)用本文只是開(kāi)始,例如更好的網(wǎng)絡(luò)架構(gòu),更多的數(shù)據(jù),和超參數(shù)的調(diào)整等等,如果你有什么改進(jìn)的想法也歡迎留言。

          作者:Chandana Kuntala
          編輯:黃繼彥




          瀏覽 83
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <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>
                  天天综合7799精品视频 | 亚洲美女被操 | 欧美骚穴| 精品一区二区三区四 | 中文AV字幕网 |