深度學習 實驗八 自編碼器

深度學習 實驗八 自編碼器

一、問題描述

自編碼器是一種數據的壓縮算法,其中數據的壓縮和解壓縮函數有如下幾個特點:

1)數據相關的

2)有損的

3)從樣本中自動學習。

在大部分提到的自動編碼器的場合,壓縮和解壓縮的函數是通過神經網絡實現的。

搭建一個自動編碼器需要完成下面三項工作:搭建編碼器,搭建解碼器,設定一個損失函數,用以衡量由於壓縮而損失掉的信息。本實驗會通過搭建一個簡單的自編碼器觀測數據信息,並再搭建一個卷積自編碼器作爲對比,並學會使用自編碼器進行降噪。

二、設計簡要描述

1. 自編碼器

​ 1.1 自編碼器簡介

​ 1.2 搭建簡單的自編碼器模型

​ 1.3 導入數據集

1.4 擬合模型

1.5 查看重構的輸出與原來的輸出對比

2. 卷積自編碼器

​ 2.1 搭建卷積自編碼器

2.2加載數據並擬合模型

2.3查看重構的輸出與原來的輸出對比

3. 自編碼器的應用

​ 3.1介紹

​ 把訓練樣本用噪聲污染,然後使用解碼器解碼出乾淨的照片,以獲得去噪自動編碼器。

​ 3.2 把原圖片加入高斯噪聲

3.3 構建自編碼器

​ 參考2.1按如下步驟使用Keras函數模型搭建自編碼器並擬合

​ 1)設置input_img參數

​ 2)搭建編碼器,添加Conv2D層,輸入是input_img,輸出維度32,卷積核大小3×3,激活函數’‘relu’,padding設置爲‘same’,返回給x

​ 3)添加Maxpooling2D層,大小是(2,2),padding設置爲‘same’

​ 4)添加Conv2D層,輸出維度32,卷積核大小3×3,激活函數’‘relu’,padding設置爲‘same’

​ 5)添加Maxpooling2D層,大小是(2,2),padding設置爲‘same’,返回給encoded

​ 6)設置解碼器,添加Conv2D層,輸入是encoded,輸出維度32,卷積核大小3×3,激活函數’‘relu’,padding設置爲‘same’,返回給x

​ 7)添加上採樣層,大小是(2,2)

8)添加Conv2D層,輸出維度32,卷積核大小3×3,激活函數’‘relu’,padding設置爲‘same’

​ 9)添加上採樣層,大小是(2,2)

​ 10)添加Conv2D層,輸入是encoded,輸出維度1,卷積核大小3×3,激活函數’‘sigmoid’,padding設置爲‘same’,返回給decoded

​ 11)設置自編碼器,輸入是input_img,decoded

​ 12)編譯自編碼器,參數不變。

​ 13)擬合數據,參數與2.1節一致

3.4查看重構的輸出與原來的輸出對比

​ 參考1.5節查看10張重構後的圖像與原圖像的對比

三、程序清單

# test8_自編碼器

# 1   自編碼器
# 1.1 自編碼器簡介 
# 1.2 搭建簡單的自編碼器模型
from keras.layers import Input, Dense
from keras.models import Model

# 編碼器維度
encoding_dim = 32  

input_img = Input(shape=(784,))
# "encoded" 是把輸入編碼表示
encoded = Dense(encoding_dim, activation='relu')(input_img)
# "decoded" 是輸入的有損重構
decoded = Dense(784, activation='sigmoid')(encoded)

# 搭建自編碼模型
autoencoder = Model(input_img, decoded)
autoencoder.compile(optimizer='adadelta', loss='binary_crossentropy')

# 1.3 導入數據集
from keras.datasets import mnist
import numpy as np
(x_train, _), (x_test, _) = mnist.load_data()
x_train = x_train.astype('float32') / 255.
x_test = x_test.astype('float32') / 255.
x_train = x_train.reshape((len(x_train),np.prod(x_train.shape[1:])))
x_test  =x_test.reshape((len(x_test), np.prod(x_test.shape[1:])))
print(x_train.shape)
print(x_test.shape)

# 1.4 擬合模型
# 通過以上數據擬合模型autoencoder
autoencoder.fit(x_train, x_train,
                epochs=50,
                batch_size=256,
                shuffle=True,
                validation_data=(x_test, x_test))

# 1.5 查看重構的輸出與原來的輸出對比
# 可以通過以下方式來查看
get_ipython().run_line_magic('matplotlib', 'inline')
# 從測試集選取一些數據來編碼和解碼
# encoded_imgs = autoencoder.predict(x_test)
decoded_imgs = autoencoder.predict(x_test)  
import matplotlib.pyplot as plt
n = 10  # 打印的圖片數量
plt.figure(figsize=(20, 4))
for i in range(n):
    # 顯示原來圖像
    ax = plt.subplot(2, n, i + 1)
    plt.imshow(x_test[i].reshape(28, 28))
    plt.gray()
    ax.get_xaxis().set_visible(False)
    ax.get_yaxis().set_visible(False)

    # 顯示重構後的圖像
    ax = plt.subplot(2, n, i + 1 + 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()

# 2 卷積自編碼器
# 2.1 搭建卷積自編碼器
# 創建如下的卷積編碼器和解碼器並編譯
from keras.layers import Input, Dense, Conv2D, MaxPooling2D, UpSampling2D
from keras.models import Model
from keras import backend as K

input_img = Input(shape=(28, 28, 1))  #輸入圖像形狀
#編碼器
x=Conv2D(16, (3, 3), activation='relu', padding='same')(input_img)
#卷積層
x = MaxPooling2D((2, 2), padding='same')(x)#空域下采樣
x = Conv2D(8, (3, 3), activation='relu', padding='same')(x)
x = MaxPooling2D((2, 2), padding='same')(x)
x = Conv2D(8, (3, 3), activation='relu', padding='same')(x)
encoded = MaxPooling2D((2, 2), padding='same')(x)

#解碼
x = Conv2D(8, (3, 3), activation='relu', padding='same')(encoded)
x = UpSampling2D((2, 2))(x)#上採樣層
x = Conv2D(8, (3, 3), activation='relu', padding='same')(x)
x = UpSampling2D((2, 2))(x)
x = Conv2D(16, (3, 3), activation='relu')(x)
x = UpSampling2D((2, 2))(x)
decoded = Conv2D(1, (3, 3), activation='sigmoid', padding='same')(x)

autoencoder = Model(input_img, decoded)
autoencoder.compile(optimizer='adadelta', loss='binary_crossentropy')#編譯


# 2.2加載數據並擬合模型
# 參考1.3和1.4節加載數據並完成模型擬合
# x_train用reshape重構時參數設置爲x_train = np.reshape(x_train, (len(x_train), 28, 28, 1)) ,x_test類似
# autoencoder中的batch_size設置爲128,其他不變
from keras.datasets import mnist
import numpy as np

(x_train, _), (x_test, _) = mnist.load_data()

x_train = x_train.astype('float32') / 255.
x_test = x_test.astype('float32') / 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)) 
autoencoder.fit(x_train, x_train,
                epochs=50,
                batch_size=128,
                shuffle=True,
                validation_data=(x_test, x_test),)

# 2.3查看重構的輸出與原來的輸出對比
# 參考1.5節查看10張重構後的圖像與原圖像的對比
import matplotlib.pyplot as plt
get_ipython().run_line_magic('matplotlib', 'inline')
decoded_imgs = autoencoder.predict(x_test)

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

    # 顯示重構後的圖像
    ax = plt.subplot(2, n, i + n+1)
    plt.imshow(decoded_imgs[i].reshape(28, 28))
    plt.gray()
    ax.get_xaxis().set_visible(False)
    ax.get_yaxis().set_visible(False)
plt.show()

# 3 自編碼器的應用
# 3.1介紹
# 把訓練樣本用噪聲污染,然後使用解碼器解碼出乾淨的照片,以獲得去噪自動編碼器。
# 3.2 把原圖片加入高斯噪聲
# 通過以下方式來加入噪聲並查看加噪後的圖片
from keras.datasets import mnist
import numpy as np
import matplotlib.pyplot as plt
get_ipython().run_line_magic('matplotlib', 'inline')

(x_train, _), (x_test, _) = mnist.load_data()

x_train = x_train.astype('float32') / 255.
x_test = x_test.astype('float32') / 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 = 10
plt.figure(figsize=(20, 2))
for i in range(n):
    ax = plt.subplot(1, n, i+1)
    plt.imshow(x_test_noisy[i].reshape(28, 28))
    plt.gray()
    ax.get_xaxis().set_visible(False)
    ax.get_yaxis().set_visible(False)
plt.show()

# 3.3 構建自編碼器
#  參考2.1按如下步驟使用Keras函數模型搭建自編碼器並擬合
# 1)設置input_img參數
# 2)搭建編碼器,添加Conv2D層,輸入是input_img,輸出維度32,卷積核大小3×3,激活函數’‘relu’,padding設置爲‘same’,返回給x
# 3)添加Maxpooling2D層,大小是(2,2),padding設置爲‘same’
# 4)添加Conv2D層,輸出維度32,卷積核大小3×3,激活函數’‘relu’,padding設置爲‘same’
# 5)添加Maxpooling2D層,大小是(2,2),padding設置爲‘same’,返回給encoded
# 6)設置解碼器,添加Conv2D層,輸入是encoded,輸出維度32,卷積核大小3×3,激活函數’‘relu’,padding設置爲‘same’,返回給x
# 7)添加上採樣層,大小是(2,2)
# 8)添加Conv2D層,輸出維度32,卷積核大小3×3,激活函數’‘relu’,padding設置爲‘same’
# 9)添加上採樣層,大小是(2,2)
# 10)添加Conv2D層,輸入是encoded,輸出維度1,卷積核大小3×3,激活函數’‘sigmoid’,padding設置爲‘same’,返回給decoded
# 11)設置自編碼器,輸入是input_img,decoded
# 12)編譯自編碼器,參數不變。
# 13)擬合數據,參數與2.1節一致
from keras.layers import Input, Dense, Conv2D, MaxPooling2D, UpSampling2D
from keras.models import Model
from keras import backend as K

input_img = Input(shape=(28, 28, 1)) 

x = Conv2D(32, (3, 3), activation='relu', padding='same')(input_img)
x = MaxPooling2D((2, 2), padding='same')(x)
x = Conv2D(32, (3, 3), activation='relu', padding='same')(x)
encoded = MaxPooling2D((2, 2), padding='same')(x)

x = Conv2D(32, (3, 3), activation='relu', padding='same')(encoded)
x = UpSampling2D((2, 2))(x)
x = Conv2D(32, (3, 3), activation='relu', padding='same')(x)
x = UpSampling2D((2, 2))(x)
decoded = Conv2D(1, (3, 3), activation='sigmoid', padding='same')(x)

autoencoder = Model(input_img, decoded)
autoencoder.compile(optimizer='adadelta', loss='binary_crossentropy')
autoencoder.fit(x_train_noisy, x_train,
                epochs=100,
                batch_size=128,
                shuffle=True,
                validation_data=(x_test_noisy, x_test),)

# 3.4查看重構的輸出與原來的輸出對比
# 參考1.5節查看10張重構後的圖像與原圖像的對比
decoded_imgs = autoencoder.predict(x_test)

n = 10
plt.figure(figsize=(20, 4))
for i in range(n):
    
    ax = plt.subplot(2, n, i + 1)
    plt.imshow(x_test_noisy[i].reshape(28, 28))
    plt.gray()
    ax.get_xaxis().set_visible(False)
    ax.get_yaxis().set_visible(False)
    
    
    ax = plt.subplot(2, n, i + n + 1)
    plt.imshow(decoded_imgs[i].reshape(28, 28))
    plt.gray()
    ax.get_xaxis().set_visible(False)
    ax.get_yaxis().set_visible(False)
plt.show()
.reshape(28, 28))
    plt.gray()
    ax.get_xaxis().set_visible(False)
    ax.get_yaxis().set_visible(False)
    
    
    ax = plt.subplot(2, n, i + n + 1)
    plt.imshow(decoded_imgs[i].reshape(28, 28))
    plt.gray()
    ax.get_xaxis().set_visible(False)
    ax.get_yaxis().set_visible(False)
plt.show()
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章