tf2.0搭建自編碼器

何爲自編碼器

以下是來自TensorFlow實戰-黃文堅這本書。
在這裏插入圖片描述

在這裏插入圖片描述

這裏有一個自編碼器的思想來源,就是說雖然圖片,音頻,視頻千千萬,但是往往“表達”他們的基本機構是少數的一些基本固定的結構。稱爲特徵的稀疏表達。
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

這裏來解釋一下,自編碼器就是輸入的圖片不知道自己的基本結構是什麼的。需要不斷的訓練來近似得到基本結構。怎麼得到呢?就是把輸出也設置爲輸入的原圖像。使之不斷的優化以得到最佳的基本結構。一般自編碼器都是中間小,兩頭大的一個網絡結構。因爲中間的每一層表達的是“基本結構”。

如何實現

具體的實現形式有很多,比如簡單的三層網絡,深層網絡,卷積網絡等。
還可以把它應用到圖像去噪上面去。這時把輸入設置爲加噪的圖片,輸出設置爲未加燥的圖片,自編碼器依然要不斷的學習以獲得最佳的適合輸出的基本結構。這是前面說的升級版了。
下面是自編碼器應用於圖像去噪的例子:(CNN)

import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt

# 加載數據集
minst = tf.keras.datasets.mnist
(x_train, _), (x_test, _) = minst.load_data()

# 設置數據格式
x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
x_train = x_train/255
x_test = x_test/255
x_train = np.reshape(x_train, (len(x_train), 28, 28, 1))
x_test = np.reshape(x_test, (len(x_test), 28, 28, 1))

# 加噪聲
noise_factor = 0.5
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 = 20
plt.figure(figsize=(60, 12))    # 指定寬爲20,高爲4
for i in range(1, 10):
    ax = plt.subplot(2, n/2, i)  # 表示將設置爲2行,n/2列,當前位置在i。
    plt.imshow(x_train[i].reshape(28, 28))
    plt.gray()
    ax.get_xaxis().set_visible(False)
    ax.get_yaxis().set_visible(False)
    ax = plt.subplot(2, n/2, 10+i)
    plt.imshow(x_train_noisy[i].reshape(28, 28))
    plt.gray()
    ax.get_xaxis().set_visible(False)
    ax.get_yaxis().set_visible(False)
plt.show()

# 模型建立
model = tf.keras.models.Sequential([
    tf.keras.layers.Conv2D(filters=16, kernel_size=(3, 3), padding="same", activation=tf.nn.relu, input_shape=(28, 28, 1)),
    tf.keras.layers.MaxPooling2D(pool_size=(2, 2), padding="same"),
    tf.keras.layers.Conv2D(filters=8, kernel_size=(3, 3), padding="same", activation=tf.nn.relu),
    tf.keras.layers.MaxPooling2D(pool_size=(2, 2), padding="same"),
    tf.keras.layers.Conv2D(filters=8, kernel_size=(3, 3), padding="same", activation=tf.nn.relu),
    tf.keras.layers.MaxPooling2D(pool_size=(2, 2), padding="same"),
    # encode 4,4,8
    # let us decode
    # 中間縮小到很小。。表達的是基本結構。
    # 然後下面再給他還原回去。
    tf.keras.layers.Conv2D(8, (3, 3), activation="relu", padding="same"),
    tf.keras.layers.UpSampling2D((2, 2)),
    tf.keras.layers.Conv2D(8, (3, 3), activation="relu", padding="same"),
    tf.keras.layers.UpSampling2D((2, 2)),
    tf.keras.layers.Conv2D(16, (3, 3), activation="relu"),
    tf.keras.layers.UpSampling2D((2, 2)),
    tf.keras.layers.Conv2D(1, (3, 3), activation="sigmoid", padding="same"),
])

learning_rate = 0.001
# 優化器
adam_optimizer = tf.keras.optimizers.Adam(learning_rate)
model.compile(optimizer=adam_optimizer, loss=tf.keras.losses.binary_crossentropy)

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

decoded_imgs = model.predict(x_test_noisy)

n = 10
plt.figure(figsize=(20, 4))
for i in range(1, n):
    # display original
    ax = plt.subplot(2, n, i)
    plt.imshow(x_test_noisy[i].reshape(28, 28))
    plt.gray()
    ax.get_xaxis().set_visible(False)
    ax.get_yaxis().set_visible(False)

    # display reconstruction
    ax = plt.subplot(2, n, i + n)
    plt.imshow(decoded_imgs[i].reshape(28, 28))
    plt.gray()
    ax.get_xaxis().set_visible(False)
    ax.get_yaxis().set_visible(False)
plt.show()

效果:50輪,loss爲0.12左右。
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章