注意: 這篇文章的內容需要一些對Keras的理解, 這先確認你/妳己先閱讀並練習過以下的連結內容:
為了獲得最好的學習效果與理解, 強烈建議先行聆聽以下的線上課程:
在本教程中,我們將回答關於autoencoders的一些常見問題,我們將介紹以下模型的代碼示例:
“自動編碼(Autoencoding)”是一種數據壓縮算法,其中壓縮和解壓縮功能是:
另外,在幾乎所有使用術語“自動編碼器”的情況下,壓縮和解壓縮功能都是用神經網絡來實現的。
自動編碼器是針對特定的數據,這意味著它們只能壓縮類似於他們所訓練的數據。這與例如MPEG-2音頻層壓縮算法不同,後者通常只保留關於“聲音”的假設,而不涉及特定類型的聲音。在"臉部"圖片上訓練的自動編碼器在壓縮"樹"的圖片方面做得相當差,因為它將學習的特徵是"臉部"特定的。
自動編碼器是有損失的壓縮,這意味著與原始輸入相比,解壓縮的輸出會降低(類似於MP3或JPEG壓縮)。這與無損壓縮算法不同。
自動編碼器是從數據中自動學習的,這是一很有用的特性:這意味著很容易訓練出特定的算法實例,在特定類型的輸入上運行良好。它不需要任何新的工程,只需要適當的訓練數據。
要構建一個自動編碼器,需要三件事:編碼函數,解碼函數和數據壓縮表示與解壓縮表示(即“丟失”函數)之間的信息損失量之間的距離函數。
編碼器和解碼器將被選擇為參數函數(通常為神經網絡),並且相對於距離函數是可微分的,因此可以優化編碼/解碼函數的參數以最小化重構損失,使用隨機梯度下降。這很簡單!而且你甚至不需要理解這些詞語就可以在實踐中開始使用自動編碼器。
一般來說並不擅長。例如在圖片壓縮中,訓練一個比JPEG這樣的基本算法效果更好的自動編碼器是相當困難的,而且通常可以實現的唯一方法是將自己限制在一個非常特定類型的圖片上(例如用於哪個JPEG做不好)。自動編碼器是用特定的 數據所訓練出來的事實使得它們對於不能有效的解決現實世界中的數據壓縮問題:您只能將它們用於與其所訓練的數據類似的數據,並使其更加通用,因此需要大量的訓練數據。但是誰知道,未來的進展可能會改變這一點。
自動編碼器在實際應用中很少被使用。在2012年,它們被發現可以應用於一種用於深層卷積神經網絡的貪心分層預訓練上[1],但是隨著我們開始意識到更好的隨機加權初始化方案足以從頭開始訓練深度網絡,它很快就又被拋棄了。在2014年,批量標準化(batch normalization)[2]開始允許更深層次的網絡,從2015年下半年起,我們可以使用殘差學習(residual learning)從頭開始任意深度訓練網絡[3]。
今天自動編碼器的兩個有趣的實際應用是數據去噪(我們在後面將會介紹)和數據可視化的降維。通過適當的維度和稀疏性約束,自動編碼器可以學習比PCA或其他基本技術更有趣的數據投影。
對於2D可視化而言,t-SNE(發音為“tee-snee”)可能是最好的算法,但它通常需要相對較低維的數據。因此,在高維數據中可視化相似關係的一個好方法是先使用自動編碼器將數據壓縮到低維空間(例如32維),然後使用t-SNE將壓縮數據映射到2D平面。請注意,Keras中的一個很好的參數實現t-SNE是由Kyle McDonald開發的,可在Github上找到。否則scikit-learn也有一個簡單實用的實現。
他們的主要聲譽來自於在線提供的許多入門機器學習課程中的特色。因此,這個領域的很多新手絕對喜歡自動編碼器,但卻苦於不知該如何入門。這就是本教程存在的原因!
另外吸引如此多研究和關注的一個原因是因為它們一直被認為是解決無監督學習問題的潛在途徑,即無需標籤就可以學習有用的表示(representation)。但是,自動編碼器不是一個真正的無監督學習技術(這將意味著完全不同的學習過程),它們是一個自我監督的技術,一個監督學習的特定實例,其中目標是從輸入數據生成的。為了獲得自我監督的模型來學習有趣的特徵,你必須提出一個有趣的合成目標和損失函數,這就是問題出現的地方:僅僅學習重新構造你的輸入可能不是一個正確的選擇。在這一點上,有重要的證據表明,例如,重點放在像素級的圖像重建不能有效地學習標籤監督學習所引起的有趣的抽象特徵(其中目標是相當抽象的概念) “由諸如”狗“,”汽車“等人類)。實際上,有人可能會爭辯說,在這方面,autoencoder最好的特點是在那些你所感興趣的主要任務(分類,定位等等)上使用不怎麼樣的特徵輸入然而獲得高性能的精確重建。
在應用於計算機視覺的自我監督學習中,自動編碼器式輸入重建的一個潛在的而且富有成效的替代方法是使用玩具任務,例如拼圖遊戲求解或細節上下文匹配(能夠將高分辨率但小塊的圖片與他們從中提取的圖片的低分辨率版本)。下面的文章研究了拼圖遊戲的解決方法,並做了一個非常有趣的閱讀:Noroozi和Favaro(2016)通過解決拼圖遊戲的視覺表示的無監督學習。這些任務為模型提供了關於傳統自動編碼器中缺少的輸入數據的內置假設,例如“視覺宏觀結構比像素級細節更重要”。
我們將從簡單的開始,將一個完全連接(fully-connected)的神經層作為編碼器和解碼器:
from keras.layers import Input, Dense
from keras.models import Model
# 這是我們要進行編碼表示(representation)的大小
encoding_dim = 32 # 32 浮點數 -> 假如我們的輸入是784個浮點數, 那麼壓縮係數為: 784/32 = 24.5
# 這是我們的輸入的佔位符(place holder)
input_img_fc = Input(shape=(784,))
# "encoded"是輸入編碼過後的表示(representation)
encoded_fc = Dense(encoding_dim, activation='relu')(input_img_fc)
# "decoded"是有損失的解碼結果
decoded_fc = Dense(784, activation='sigmoid')(encoded_fc)
# 串接編碼(encoded)與解碼(decoded)的模型
autoencoder_fc = Model(input_img_fc, decoded_fc)
Using TensorFlow backend.
我們還要創建一個單獨的編碼器模型:
# 這個模型串接輸入到編碼表示(representation)
encoder_fc = Model(input_img_fc, encoded_fc)
以及解碼器模型:
# 產生一個佔位符來做為"編碼表示(32-dimensional)"的輸入
encoded_input_fc = Input(shape=(encoding_dim,))
# 取得autoencoder模型最後一層的神經層
decoder_layer_fc = autoencoder_fc.layers[-1]
# 產生解碼模型
decoder_fc = Model(encoded_input_fc, decoder_layer_fc(encoded_input_fc))
現在讓我們訓練我們的自動編碼器來重建MNIST數字。
首先,我們將我們的模型配置為使用每像素二進制信號(binary crossentropy)損失函數,以及Adadelta優化器:
# 模型參數設定
autoencoder_fc.compile(optimizer='adadelta', loss='binary_crossentropy')
# 秀出模型結構
autoencoder_fc.summary()
_________________________________________________________________ Layer (type) Output Shape Param # ================================================================= input_1 (InputLayer) (None, 784) 0 _________________________________________________________________ dense_1 (Dense) (None, 32) 25120 _________________________________________________________________ dense_2 (Dense) (None, 784) 25872 ================================================================= Total params: 50,992 Trainable params: 50,992 Non-trainable params: 0 _________________________________________________________________
讓我們準備我們的輸入數據。我們使用的是MNIST數字,我們放棄了標籤(因為我們只對編碼/解碼輸入圖像感興趣)。
from keras.datasets import mnist
import numpy as np
(x_train, _), (x_test, _) = mnist.load_data()
我們將歸一化(normalize)所有像素值落於0和1之間,我們將把28x28的圖像打平變成784的向量。
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)
(60000, 784) (10000, 784)
現在讓我們訓練我們的自動編碼器50個循環(epochs):
autoencoder_fc.fit(x_train, x_train,
epochs=50,
batch_size=256,
shuffle=True,
validation_data=(x_test, x_test))
Train on 60000 samples, validate on 10000 samples Epoch 1/50 60000/60000 [==============================] - 3s 45us/step - loss: 0.3856 - val_loss: 0.2742 Epoch 2/50 60000/60000 [==============================] - 1s 24us/step - loss: 0.2681 - val_loss: 0.2593 Epoch 3/50 60000/60000 [==============================] - 1s 23us/step - loss: 0.2497 - val_loss: 0.2373 Epoch 4/50 60000/60000 [==============================] - 1s 20us/step - loss: 0.2290 - val_loss: 0.2184 Epoch 5/50 60000/60000 [==============================] - 1s 25us/step - loss: 0.2129 - val_loss: 0.2048 Epoch 6/50 60000/60000 [==============================] - 1s 24us/step - loss: 0.2009 - val_loss: 0.1943 Epoch 7/50 60000/60000 [==============================] - 1s 24us/step - loss: 0.1915 - val_loss: 0.1862 Epoch 8/50 60000/60000 [==============================] - 1s 24us/step - loss: 0.1841 - val_loss: 0.1795 Epoch 9/50 60000/60000 [==============================] - 1s 23us/step - loss: 0.1780 - val_loss: 0.1738 Epoch 10/50 60000/60000 [==============================] - 1s 23us/step - loss: 0.1727 - val_loss: 0.1689 Epoch 11/50 60000/60000 [==============================] - 1s 24us/step - loss: 0.1682 - val_loss: 0.1649 Epoch 12/50 60000/60000 [==============================] - 1s 23us/step - loss: 0.1641 - val_loss: 0.1608 Epoch 13/50 60000/60000 [==============================] - 2s 27us/step - loss: 0.1604 - val_loss: 0.1573 Epoch 14/50 60000/60000 [==============================] - 2s 28us/step - loss: 0.1570 - val_loss: 0.1540 Epoch 15/50 60000/60000 [==============================] - 2s 27us/step - loss: 0.1539 - val_loss: 0.1510 Epoch 16/50 60000/60000 [==============================] - 1s 21us/step - loss: 0.1510 - val_loss: 0.1482 Epoch 17/50 60000/60000 [==============================] - 2s 29us/step - loss: 0.1482 - val_loss: 0.1457 Epoch 18/50 60000/60000 [==============================] - 1s 22us/step - loss: 0.1457 - val_loss: 0.1431 Epoch 19/50 60000/60000 [==============================] - 1s 21us/step - loss: 0.1434 - val_loss: 0.1408 Epoch 20/50 60000/60000 [==============================] - 1s 22us/step - loss: 0.1411 - val_loss: 0.1387 Epoch 21/50 60000/60000 [==============================] - 2s 26us/step - loss: 0.1390 - val_loss: 0.1366 Epoch 22/50 60000/60000 [==============================] - 2s 29us/step - loss: 0.1370 - val_loss: 0.1345 Epoch 23/50 60000/60000 [==============================] - 1s 22us/step - loss: 0.1350 - val_loss: 0.1326 Epoch 24/50 60000/60000 [==============================] - 1s 22us/step - loss: 0.1331 - val_loss: 0.1307 Epoch 25/50 60000/60000 [==============================] - 2s 30us/step - loss: 0.1313 - val_loss: 0.1290 Epoch 26/50 60000/60000 [==============================] - 1s 24us/step - loss: 0.1296 - val_loss: 0.1273 Epoch 27/50 60000/60000 [==============================] - 1s 21us/step - loss: 0.1280 - val_loss: 0.1257 Epoch 28/50 60000/60000 [==============================] - 1s 22us/step - loss: 0.1264 - val_loss: 0.1242 Epoch 29/50 60000/60000 [==============================] - 1s 22us/step - loss: 0.1250 - val_loss: 0.1227 Epoch 30/50 60000/60000 [==============================] - 1s 23us/step - loss: 0.1236 - val_loss: 0.1214 Epoch 31/50 60000/60000 [==============================] - 2s 26us/step - loss: 0.1223 - val_loss: 0.1201 Epoch 32/50 60000/60000 [==============================] - 1s 21us/step - loss: 0.1210 - val_loss: 0.1189 Epoch 33/50 60000/60000 [==============================] - 1s 24us/step - loss: 0.1199 - val_loss: 0.1178 Epoch 34/50 60000/60000 [==============================] - 1s 24us/step - loss: 0.1188 - val_loss: 0.1167 Epoch 35/50 60000/60000 [==============================] - 1s 22us/step - loss: 0.1178 - val_loss: 0.1158 Epoch 36/50 60000/60000 [==============================] - 1s 22us/step - loss: 0.1169 - val_loss: 0.1148 Epoch 37/50 60000/60000 [==============================] - 1s 23us/step - loss: 0.1160 - val_loss: 0.1140 Epoch 38/50 60000/60000 [==============================] - 1s 21us/step - loss: 0.1152 - val_loss: 0.1132 Epoch 39/50 60000/60000 [==============================] - 1s 24us/step - loss: 0.1144 - val_loss: 0.1125 Epoch 40/50 60000/60000 [==============================] - 2s 28us/step - loss: 0.1137 - val_loss: 0.1118 Epoch 41/50 60000/60000 [==============================] - 2s 26us/step - loss: 0.1131 - val_loss: 0.1112 Epoch 42/50 60000/60000 [==============================] - 1s 20us/step - loss: 0.1125 - val_loss: 0.1106 Epoch 43/50 60000/60000 [==============================] - 1s 23us/step - loss: 0.1119 - val_loss: 0.1100 Epoch 44/50 60000/60000 [==============================] - 1s 24us/step - loss: 0.1114 - val_loss: 0.1095 Epoch 45/50 60000/60000 [==============================] - 2s 25us/step - loss: 0.1109 - val_loss: 0.1090 Epoch 46/50 60000/60000 [==============================] - 2s 27us/step - loss: 0.1104 - val_loss: 0.1086 Epoch 47/50 60000/60000 [==============================] - 2s 26us/step - loss: 0.1100 - val_loss: 0.1081 Epoch 48/50 60000/60000 [==============================] - 2s 26us/step - loss: 0.1096 - val_loss: 0.1077 Epoch 49/50 60000/60000 [==============================] - 2s 28us/step - loss: 0.1092 - val_loss: 0.1073 Epoch 50/50 60000/60000 [==============================] - 1s 24us/step - loss: 0.1088 - val_loss: 0.1070
<keras.callbacks.History at 0x204acd59f28>
在50個訓練循環之後,自動編碼器似乎達到穩定的訓練/測試損失值約0.11。我們可以視覺化輸入的重建和編碼表示。我們將使用Matplotlib。
# 編碼與解碼一些手寫數字圖像
encoded_imgs_fc = encoder_fc.predict(x_test)
decoded_imgs_fc = decoder_fc.predict(encoded_imgs_fc)
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_fc[i].reshape(28, 28))
plt.gray()
ax.get_xaxis().set_visible(False)
ax.get_yaxis().set_visible(False)
plt.show()
以上是我們得到的結果。上面的一行是原始數字圖像,下面一行是重建的數字圖像。如果我們所說的這個autoencoder會失去很多細節(有損的壓縮)。
我們不必將自己限制在一個單獨的神經層上作為編碼器或解碼器,而是可以使用一堆神經層,例如:
input_img_deep = Input(shape=(784,))
encoded_deep = Dense(128, activation='relu')(input_img_deep)
encoded_deep = Dense(64, activation='relu')(encoded_deep)
encoded_deep = Dense(32, activation='relu')(encoded_deep)
decoded_deep = Dense(64, activation='relu')(encoded_deep)
decoded_deep = Dense(128, activation='relu')(decoded_deep)
decoded_deep = Dense(784, activation='sigmoid')(decoded_deep)
# 串接編碼(encoded)與解碼(decoded)的模型
autoencoder_deep = Model(input_img_deep, decoded_deep)
# 模型參數設定
autoencoder_deep.compile(optimizer='adadelta', loss='binary_crossentropy')
# 開始訓練模型
autoencoder_deep.fit(x_train, x_train,
epochs=100,
batch_size=256,
shuffle=True,
validation_data=(x_test, x_test))
Train on 60000 samples, validate on 10000 samples Epoch 1/100 60000/60000 [==============================] - 2s 41us/step - loss: 0.3414 - val_loss: 0.2625 Epoch 2/100 60000/60000 [==============================] - 2s 30us/step - loss: 0.2551 - val_loss: 0.2453 Epoch 3/100 60000/60000 [==============================] - 2s 27us/step - loss: 0.2355 - val_loss: 0.2263 Epoch 4/100 60000/60000 [==============================] - 2s 28us/step - loss: 0.2193 - val_loss: 0.2111 Epoch 5/100 60000/60000 [==============================] - 2s 32us/step - loss: 0.2081 - val_loss: 0.2035 Epoch 6/100 60000/60000 [==============================] - 2s 26us/step - loss: 0.1992 - val_loss: 0.1917 Epoch 7/100 60000/60000 [==============================] - 2s 37us/step - loss: 0.1875 - val_loss: 0.1815 Epoch 8/100 60000/60000 [==============================] - 2s 32us/step - loss: 0.1797 - val_loss: 0.1763 Epoch 9/100 60000/60000 [==============================] - 2s 29us/step - loss: 0.1742 - val_loss: 0.1701 Epoch 10/100 60000/60000 [==============================] - 2s 29us/step - loss: 0.1692 - val_loss: 0.1653 Epoch 11/100 60000/60000 [==============================] - 2s 29us/step - loss: 0.1651 - val_loss: 0.1619 Epoch 12/100 60000/60000 [==============================] - 2s 29us/step - loss: 0.1611 - val_loss: 0.1577 Epoch 13/100 60000/60000 [==============================] - 2s 28us/step - loss: 0.1573 - val_loss: 0.1534 Epoch 14/100 60000/60000 [==============================] - 2s 28us/step - loss: 0.1535 - val_loss: 0.1506 Epoch 15/100 60000/60000 [==============================] - 2s 27us/step - loss: 0.1504 - val_loss: 0.1471 Epoch 16/100 60000/60000 [==============================] - 2s 28us/step - loss: 0.1477 - val_loss: 0.1452 Epoch 17/100 60000/60000 [==============================] - 2s 27us/step - loss: 0.1454 - val_loss: 0.1415 Epoch 18/100 60000/60000 [==============================] - 2s 27us/step - loss: 0.1432 - val_loss: 0.1399 Epoch 19/100 60000/60000 [==============================] - 2s 29us/step - loss: 0.1414 - val_loss: 0.1406 Epoch 20/100 60000/60000 [==============================] - 2s 29us/step - loss: 0.1396 - val_loss: 0.1391 Epoch 21/100 60000/60000 [==============================] - 2s 25us/step - loss: 0.1381 - val_loss: 0.1350 Epoch 22/100 60000/60000 [==============================] - 2s 32us/step - loss: 0.1365 - val_loss: 0.1344 Epoch 23/100 60000/60000 [==============================] - 2s 31us/step - loss: 0.1351 - val_loss: 0.1342 Epoch 24/100 60000/60000 [==============================] - 2s 32us/step - loss: 0.1338 - val_loss: 0.1311 Epoch 25/100 60000/60000 [==============================] - 2s 33us/step - loss: 0.1326 - val_loss: 0.1303 Epoch 26/100 60000/60000 [==============================] - 2s 31us/step - loss: 0.1314 - val_loss: 0.1300 Epoch 27/100 60000/60000 [==============================] - 2s 26us/step - loss: 0.1302 - val_loss: 0.1290 Epoch 28/100 60000/60000 [==============================] - 2s 34us/step - loss: 0.1289 - val_loss: 0.1265 Epoch 29/100 60000/60000 [==============================] - 2s 27us/step - loss: 0.1278 - val_loss: 0.1265 Epoch 30/100 60000/60000 [==============================] - 2s 28us/step - loss: 0.1267 - val_loss: 0.1252 Epoch 31/100 60000/60000 [==============================] - 2s 28us/step - loss: 0.1259 - val_loss: 0.1237 Epoch 32/100 60000/60000 [==============================] - 1s 24us/step - loss: 0.1248 - val_loss: 0.1231 Epoch 33/100 60000/60000 [==============================] - 2s 35us/step - loss: 0.1239 - val_loss: 0.1213 Epoch 34/100 60000/60000 [==============================] - 2s 32us/step - loss: 0.1231 - val_loss: 0.1219 Epoch 35/100 60000/60000 [==============================] - 2s 30us/step - loss: 0.1223 - val_loss: 0.1213 Epoch 36/100 60000/60000 [==============================] - 1s 24us/step - loss: 0.1216 - val_loss: 0.1198 Epoch 37/100 60000/60000 [==============================] - 2s 26us/step - loss: 0.1208 - val_loss: 0.1191 Epoch 38/100 60000/60000 [==============================] - 2s 26us/step - loss: 0.1202 - val_loss: 0.1173 Epoch 39/100 60000/60000 [==============================] - 2s 30us/step - loss: 0.1194 - val_loss: 0.1175 Epoch 40/100 60000/60000 [==============================] - 2s 28us/step - loss: 0.1188 - val_loss: 0.1173 Epoch 41/100 60000/60000 [==============================] - 2s 33us/step - loss: 0.1182 - val_loss: 0.1168 Epoch 42/100 60000/60000 [==============================] - 2s 34us/step - loss: 0.1175 - val_loss: 0.1159 Epoch 43/100 60000/60000 [==============================] - 2s 30us/step - loss: 0.1170 - val_loss: 0.1143 Epoch 44/100 60000/60000 [==============================] - 2s 28us/step - loss: 0.1165 - val_loss: 0.1146 Epoch 45/100 60000/60000 [==============================] - 2s 31us/step - loss: 0.1158 - val_loss: 0.1141 Epoch 46/100 60000/60000 [==============================] - 2s 34us/step - loss: 0.1153 - val_loss: 0.1154 Epoch 47/100 60000/60000 [==============================] - 2s 28us/step - loss: 0.1149 - val_loss: 0.1128 Epoch 48/100 60000/60000 [==============================] - 2s 37us/step - loss: 0.1144 - val_loss: 0.1122 Epoch 49/100 60000/60000 [==============================] - 2s 26us/step - loss: 0.1139 - val_loss: 0.1117 Epoch 50/100 60000/60000 [==============================] - 2s 32us/step - loss: 0.1135 - val_loss: 0.1119 Epoch 51/100 60000/60000 [==============================] - 2s 33us/step - loss: 0.1130 - val_loss: 0.1111 Epoch 52/100 60000/60000 [==============================] - 2s 26us/step - loss: 0.1126 - val_loss: 0.1112 Epoch 53/100 60000/60000 [==============================] - 2s 30us/step - loss: 0.1122 - val_loss: 0.1113 Epoch 54/100 60000/60000 [==============================] - 2s 33us/step - loss: 0.1118 - val_loss: 0.1103 Epoch 55/100 60000/60000 [==============================] - 2s 30us/step - loss: 0.1113 - val_loss: 0.1111 Epoch 56/100 60000/60000 [==============================] - 2s 29us/step - loss: 0.1111 - val_loss: 0.1100 Epoch 57/100 60000/60000 [==============================] - 2s 26us/step - loss: 0.1105 - val_loss: 0.1095 Epoch 58/100 60000/60000 [==============================] - 2s 26us/step - loss: 0.1102 - val_loss: 0.1081 Epoch 59/100 60000/60000 [==============================] - 2s 27us/step - loss: 0.1099 - val_loss: 0.1089 Epoch 60/100 60000/60000 [==============================] - 2s 30us/step - loss: 0.1095 - val_loss: 0.1087 Epoch 61/100 60000/60000 [==============================] - 2s 27us/step - loss: 0.1091 - val_loss: 0.1079 Epoch 62/100 60000/60000 [==============================] - 2s 26us/step - loss: 0.1090 - val_loss: 0.1070 Epoch 63/100 60000/60000 [==============================] - 2s 29us/step - loss: 0.1086 - val_loss: 0.1075 Epoch 64/100 60000/60000 [==============================] - 2s 27us/step - loss: 0.1084 - val_loss: 0.1064 Epoch 65/100 60000/60000 [==============================] - 2s 31us/step - loss: 0.1081 - val_loss: 0.1072 Epoch 66/100 60000/60000 [==============================] - 2s 25us/step - loss: 0.1078 - val_loss: 0.1063 Epoch 67/100 60000/60000 [==============================] - 2s 35us/step - loss: 0.1074 - val_loss: 0.1054 Epoch 68/100 60000/60000 [==============================] - 2s 31us/step - loss: 0.1072 - val_loss: 0.1053 Epoch 69/100 60000/60000 [==============================] - 2s 31us/step - loss: 0.1068 - val_loss: 0.1066 Epoch 70/100 60000/60000 [==============================] - 2s 27us/step - loss: 0.1066 - val_loss: 0.1045 Epoch 71/100 60000/60000 [==============================] - 2s 28us/step - loss: 0.1064 - val_loss: 0.1059 Epoch 72/100 60000/60000 [==============================] - 2s 35us/step - loss: 0.1061 - val_loss: 0.1057 Epoch 73/100 60000/60000 [==============================] - 2s 33us/step - loss: 0.1058 - val_loss: 0.1044 Epoch 74/100 60000/60000 [==============================] - 2s 33us/step - loss: 0.1056 - val_loss: 0.1034 Epoch 75/100 60000/60000 [==============================] - 2s 30us/step - loss: 0.1052 - val_loss: 0.1046 Epoch 76/100 60000/60000 [==============================] - 2s 28us/step - loss: 0.1050 - val_loss: 0.1035 Epoch 77/100 60000/60000 [==============================] - 2s 32us/step - loss: 0.1048 - val_loss: 0.1040 Epoch 78/100 60000/60000 [==============================] - 2s 32us/step - loss: 0.1045 - val_loss: 0.1027 Epoch 79/100 60000/60000 [==============================] - 2s 38us/step - loss: 0.1042 - val_loss: 0.1035 Epoch 80/100 60000/60000 [==============================] - 1s 25us/step - loss: 0.1040 - val_loss: 0.1040 Epoch 81/100 60000/60000 [==============================] - 2s 31us/step - loss: 0.1037 - val_loss: 0.1023 Epoch 82/100 60000/60000 [==============================] - 2s 32us/step - loss: 0.1035 - val_loss: 0.1015 Epoch 83/100 60000/60000 [==============================] - 2s 27us/step - loss: 0.1031 - val_loss: 0.1007 Epoch 84/100 60000/60000 [==============================] - 2s 33us/step - loss: 0.1030 - val_loss: 0.1010 Epoch 85/100 60000/60000 [==============================] - 2s 31us/step - loss: 0.1027 - val_loss: 0.1015 Epoch 86/100 60000/60000 [==============================] - 2s 29us/step - loss: 0.1025 - val_loss: 0.1024 Epoch 87/100 60000/60000 [==============================] - 2s 29us/step - loss: 0.1023 - val_loss: 0.1011 Epoch 88/100 60000/60000 [==============================] - 2s 27us/step - loss: 0.1020 - val_loss: 0.1013 Epoch 89/100 60000/60000 [==============================] - 2s 29us/step - loss: 0.1018 - val_loss: 0.1006 Epoch 90/100 60000/60000 [==============================] - 1s 24us/step - loss: 0.1017 - val_loss: 0.0998 Epoch 91/100 60000/60000 [==============================] - 2s 27us/step - loss: 0.1014 - val_loss: 0.0997 Epoch 92/100 60000/60000 [==============================] - 2s 29us/step - loss: 0.1012 - val_loss: 0.1002 Epoch 93/100 60000/60000 [==============================] - 2s 30us/step - loss: 0.1010 - val_loss: 0.1001 Epoch 94/100 60000/60000 [==============================] - 2s 28us/step - loss: 0.1007 - val_loss: 0.1016 Epoch 95/100 60000/60000 [==============================] - 2s 27us/step - loss: 0.1007 - val_loss: 0.0999 Epoch 96/100 60000/60000 [==============================] - 2s 26us/step - loss: 0.1004 - val_loss: 0.1015 Epoch 97/100 60000/60000 [==============================] - 2s 26us/step - loss: 0.1003 - val_loss: 0.0994 Epoch 98/100 60000/60000 [==============================] - 2s 28us/step - loss: 0.1001 - val_loss: 0.1004 Epoch 99/100 60000/60000 [==============================] - 2s 28us/step - loss: 0.1000 - val_loss: 0.0986 Epoch 100/100 60000/60000 [==============================] - 2s 28us/step - loss: 0.0999 - val_loss: 0.0995
<keras.callbacks.History at 0x2071a5f78d0>
# 編碼與解碼一些手寫數字圖像
decoded_imgs_deep = autoencoder_deep.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+1+n)
plt.imshow(decoded_imgs_deep[i].reshape(28, 28))
plt.gray()
ax.get_xaxis().set_visible(False)
ax.get_yaxis().set_visible(False)
plt.show()
由於我們的輸入是圖像,所以使用卷積神經網絡(convnets)作為編碼器和解碼器是有意義的。在實際設置中,應用於圖像的自動編碼器始終是卷積自動編碼器 - 它們只是表現得更好。
我們來實現一個。編碼器將包含一堆Conv2D和MaxPooling2D層(最大池用於空間向下採樣down-sampling),而解碼器將包含一堆Conv2D和UpSampling2D層。
from keras.layers import Input, Dense, Conv2D, MaxPool2D, UpSampling2D
from keras.models import Model
input_img_cov = Input(shape=(28, 28, 1)) # 使用`channels_first`圖像數據格式
x = Conv2D(16, (3, 3), activation='relu', padding='same')(input_img_cov)
x = MaxPool2D((2, 2), padding='same')(x)
x = Conv2D(8, (3, 3), activation='relu', padding='same')(x)
x = MaxPool2D((2, 2), padding='same')(x)
x = Conv2D(8, (3, 3), activation='relu', padding='same')(x)
encoded_cov = MaxPool2D((2, 2), padding='same')(x)
# 到這個節點的編碼表示的結構是 (4, 4, 8), 也可以想成是 128-dimensional
x = Conv2D(8, (3, 3), activation='relu', padding='same')(encoded_cov)
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_cov = Conv2D(1, (3, 3), activation='sigmoid', padding='same')(x)
# 串接編碼(encoded)與解碼(decoded)的模型
autoencoder_cov = Model(input_img_cov, decoded_cov)
# 模型參數設定
autoencoder_cov.compile(optimizer='adadelta', loss='binary_crossentropy')
# 秀出模型結構
autoencoder_cov.summary()
_________________________________________________________________ Layer (type) Output Shape Param # ================================================================= input_4 (InputLayer) (None, 28, 28, 1) 0 _________________________________________________________________ conv2d_1 (Conv2D) (None, 28, 28, 16) 160 _________________________________________________________________ max_pooling2d_1 (MaxPooling2 (None, 14, 14, 16) 0 _________________________________________________________________ conv2d_2 (Conv2D) (None, 14, 14, 8) 1160 _________________________________________________________________ max_pooling2d_2 (MaxPooling2 (None, 7, 7, 8) 0 _________________________________________________________________ conv2d_3 (Conv2D) (None, 7, 7, 8) 584 _________________________________________________________________ max_pooling2d_3 (MaxPooling2 (None, 4, 4, 8) 0 _________________________________________________________________ conv2d_4 (Conv2D) (None, 4, 4, 8) 584 _________________________________________________________________ up_sampling2d_1 (UpSampling2 (None, 8, 8, 8) 0 _________________________________________________________________ conv2d_5 (Conv2D) (None, 8, 8, 8) 584 _________________________________________________________________ up_sampling2d_2 (UpSampling2 (None, 16, 16, 8) 0 _________________________________________________________________ conv2d_6 (Conv2D) (None, 14, 14, 16) 1168 _________________________________________________________________ up_sampling2d_3 (UpSampling2 (None, 28, 28, 16) 0 _________________________________________________________________ conv2d_7 (Conv2D) (None, 28, 28, 1) 145 ================================================================= Total params: 4,385 Trainable params: 4,385 Non-trainable params: 0 _________________________________________________________________
為了訓練它,我們將使用原始MNIST數字(樣本,28,28),並且我們僅對像素值進行歸一化讓數值落在0和1之間。
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)) # 使用`channels_first`圖像數據格式
x_test = np.reshape(x_test, (len(x_test), 28, 28, 1)) # 使用`channels_first`圖像數據格式
print(x_train.shape)
print(x_test.shape)
(60000, 28, 28, 1) (10000, 28, 28, 1)
讓我們訓練這個模型50個循環。為了演示如何在訓練過程中顯示模型的結果,我們將使用TensorFlow後端和TensorBoard回調。
首先,打開一個終端並啟動一個TensorBoard服務器,該服務器將讀取存儲在/tmp/autoencoder中的日誌。
# 開始訓練模型
autoencoder_cov.fit(x_train, x_train,
epochs=50,
batch_size=128,
shuffle=True,
validation_data=(x_test, x_test))
Train on 60000 samples, validate on 10000 samples Epoch 1/50 60000/60000 [==============================] - 6s 97us/step - loss: 0.2409 - val_loss: 0.1732 Epoch 2/50 60000/60000 [==============================] - 5s 75us/step - loss: 0.1648 - val_loss: 0.1551 Epoch 3/50 60000/60000 [==============================] - 4s 71us/step - loss: 0.1477 - val_loss: 0.1390 Epoch 4/50 60000/60000 [==============================] - 4s 74us/step - loss: 0.1376 - val_loss: 0.1317 Epoch 5/50 60000/60000 [==============================] - 4s 74us/step - loss: 0.1313 - val_loss: 0.1305 Epoch 6/50 60000/60000 [==============================] - 5s 80us/step - loss: 0.1264 - val_loss: 0.1224 Epoch 7/50 60000/60000 [==============================] - 4s 67us/step - loss: 0.1235 - val_loss: 0.1205 Epoch 8/50 60000/60000 [==============================] - 4s 70us/step - loss: 0.1209 - val_loss: 0.1187 Epoch 9/50 60000/60000 [==============================] - 5s 76us/step - loss: 0.1192 - val_loss: 0.1189 Epoch 10/50 60000/60000 [==============================] - 5s 75us/step - loss: 0.1177 - val_loss: 0.1178 Epoch 11/50 60000/60000 [==============================] - 4s 72us/step - loss: 0.1160 - val_loss: 0.1152 Epoch 12/50 60000/60000 [==============================] - 4s 72us/step - loss: 0.1140 - val_loss: 0.1147 Epoch 13/50 60000/60000 [==============================] - 5s 84us/step - loss: 0.1131 - val_loss: 0.1106 Epoch 14/50 60000/60000 [==============================] - 4s 70us/step - loss: 0.1124 - val_loss: 0.1100 Epoch 15/50 60000/60000 [==============================] - 5s 77us/step - loss: 0.1118 - val_loss: 0.1094 Epoch 16/50 60000/60000 [==============================] - 4s 68us/step - loss: 0.1105 - val_loss: 0.1111 Epoch 17/50 60000/60000 [==============================] - 4s 68us/step - loss: 0.1099 - val_loss: 0.1073 Epoch 18/50 60000/60000 [==============================] - 4s 75us/step - loss: 0.1094 - val_loss: 0.1105 Epoch 19/50 60000/60000 [==============================] - 4s 70us/step - loss: 0.1089 - val_loss: 0.1089 Epoch 20/50 60000/60000 [==============================] - 5s 81us/step - loss: 0.1077 - val_loss: 0.1065 Epoch 21/50 60000/60000 [==============================] - 5s 82us/step - loss: 0.1075 - val_loss: 0.1052 Epoch 22/50 60000/60000 [==============================] - 5s 79us/step - loss: 0.1071 - val_loss: 0.1041 Epoch 23/50 60000/60000 [==============================] - 5s 75us/step - loss: 0.1065 - val_loss: 0.1049 Epoch 24/50 60000/60000 [==============================] - 5s 79us/step - loss: 0.1062 - val_loss: 0.1070 Epoch 25/50 60000/60000 [==============================] - 4s 73us/step - loss: 0.1056 - val_loss: 0.1042 Epoch 26/50 60000/60000 [==============================] - 5s 78us/step - loss: 0.1053 - val_loss: 0.1040 Epoch 27/50 60000/60000 [==============================] - 5s 76us/step - loss: 0.1048 - val_loss: 0.1038 Epoch 28/50 60000/60000 [==============================] - 5s 77us/step - loss: 0.1044 - val_loss: 0.1026 Epoch 29/50 60000/60000 [==============================] - 5s 79us/step - loss: 0.1045 - val_loss: 0.1020 Epoch 30/50 60000/60000 [==============================] - 5s 75us/step - loss: 0.1041 - val_loss: 0.1018 Epoch 31/50 60000/60000 [==============================] - 4s 74us/step - loss: 0.1036 - val_loss: 0.1029 Epoch 32/50 60000/60000 [==============================] - 5s 78us/step - loss: 0.1033 - val_loss: 0.1020 Epoch 33/50 60000/60000 [==============================] - 4s 72us/step - loss: 0.1031 - val_loss: 0.1009 Epoch 34/50 60000/60000 [==============================] - 4s 73us/step - loss: 0.1031 - val_loss: 0.1009 Epoch 35/50 60000/60000 [==============================] - 4s 74us/step - loss: 0.1027 - val_loss: 0.1018 Epoch 36/50 60000/60000 [==============================] - 5s 77us/step - loss: 0.1025 - val_loss: 0.1026 Epoch 37/50 60000/60000 [==============================] - 5s 77us/step - loss: 0.1023 - val_loss: 0.1011 Epoch 38/50 60000/60000 [==============================] - 4s 72us/step - loss: 0.1018 - val_loss: 0.1005 Epoch 39/50 60000/60000 [==============================] - 5s 79us/step - loss: 0.1016 - val_loss: 0.1009 Epoch 40/50 60000/60000 [==============================] - 4s 74us/step - loss: 0.1014 - val_loss: 0.0997 Epoch 41/50 60000/60000 [==============================] - 5s 78us/step - loss: 0.1011 - val_loss: 0.0993 Epoch 42/50 60000/60000 [==============================] - 5s 78us/step - loss: 0.1010 - val_loss: 0.1005 Epoch 43/50 60000/60000 [==============================] - 5s 76us/step - loss: 0.1009 - val_loss: 0.0998 Epoch 44/50 60000/60000 [==============================] - 4s 70us/step - loss: 0.1005 - val_loss: 0.0983 Epoch 45/50 60000/60000 [==============================] - 4s 74us/step - loss: 0.1002 - val_loss: 0.0988 Epoch 46/50 60000/60000 [==============================] - 5s 78us/step - loss: 0.1004 - val_loss: 0.0998 Epoch 47/50 60000/60000 [==============================] - 5s 86us/step - loss: 0.1003 - val_loss: 0.0986 Epoch 48/50 60000/60000 [==============================] - 4s 70us/step - loss: 0.1002 - val_loss: 0.0980 Epoch 49/50 60000/60000 [==============================] - 5s 80us/step - loss: 0.0998 - val_loss: 0.0975 Epoch 50/50 60000/60000 [==============================] - 5s 77us/step - loss: 0.0997 - val_loss: 0.0982
<keras.callbacks.History at 0x2072ac72cc0>
該模型收斂到0.094的損失,明顯好於我們之前的模型(這在很大程度上是由於編碼表示的更高的熵容量,128維度與之前的32維度)。我們來看看重建的數字圖像:
decoded_imgs_conv = autoencoder_cov.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+1+n)
plt.imshow(decoded_imgs_conv[i].reshape(28, 28))
plt.gray()
ax.get_xaxis().set_visible(False)
ax.get_yaxis().set_visible(False)
plt.show()
讓我們把我們的卷積自動編碼器工作在一個圖像去噪問題。這很簡單:我們將訓練自動編碼器將噪聲數字圖像處理成清晰的數字圖像。
以下是我們如何生成合成噪聲數字圖像:我們只是應用高斯噪聲矩陣,並在0和1之間剪切圖像。
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)) # 使用`channels_first`圖像數據格式
x_test = np.reshape(x_test, (len(x_test), 28, 28, 1)) # 使用`channels_first`圖像數據格式
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()
如果你瞇起眼睛,你仍然勉強可以認出他們。我們的自動編碼器能學會如何恢復原始數字圖像嗎?讓我們試試看。
與上一個的捲積自動編碼器相比,為了提高重建質量,我們將使用稍微不同的模型,每層有更多的濾波器:
input_img_conv2 = Input(shape=(28, 28, 1))
x = Conv2D(32, (3, 3), activation='relu', padding='same')(input_img_conv2)
x = MaxPool2D((2, 2), padding='same')(x)
x = Conv2D(32, (3, 3), activation='relu', padding='same')(x)
encoded_conv2 = MaxPool2D((2, 2), padding='same')(x)
# 到這個節點的編碼表示的結構是 (7, 7, 32)
x = Conv2D(32, (3, 3), activation='relu', padding='same')(encoded_conv2)
x = UpSampling2D((2, 2))(x)
x = Conv2D(32, (3, 3), activation='relu', padding='same')(x)
x = UpSampling2D((2, 2))(x)
decoded_conv2= Conv2D(1, (3, 3), activation='sigmoid', padding='same')(x)
# 串接編碼(encoded)與解碼(decoded)的模型
autoencoder_conv2 = Model(input_img_conv2, decoded_conv2)
# 模型參數設定
autoencoder_conv2.compile(optimizer='adadelta', loss='binary_crossentropy')
# 模型參數設定
autoencoder_conv2.summary()
_________________________________________________________________ Layer (type) Output Shape Param # ================================================================= input_5 (InputLayer) (None, 28, 28, 1) 0 _________________________________________________________________ conv2d_8 (Conv2D) (None, 28, 28, 32) 320 _________________________________________________________________ max_pooling2d_4 (MaxPooling2 (None, 14, 14, 32) 0 _________________________________________________________________ conv2d_9 (Conv2D) (None, 14, 14, 32) 9248 _________________________________________________________________ max_pooling2d_5 (MaxPooling2 (None, 7, 7, 32) 0 _________________________________________________________________ conv2d_10 (Conv2D) (None, 7, 7, 32) 9248 _________________________________________________________________ up_sampling2d_4 (UpSampling2 (None, 14, 14, 32) 0 _________________________________________________________________ conv2d_11 (Conv2D) (None, 14, 14, 32) 9248 _________________________________________________________________ up_sampling2d_5 (UpSampling2 (None, 28, 28, 32) 0 _________________________________________________________________ conv2d_12 (Conv2D) (None, 28, 28, 1) 289 ================================================================= Total params: 28,353 Trainable params: 28,353 Non-trainable params: 0 _________________________________________________________________
讓我們訓練它100個循環:
autoencoder_conv2.fit(x_train_noisy, x_train,
epochs=100,
batch_size=128,
shuffle=True,
validation_data=(x_test_noisy, x_test))
Train on 60000 samples, validate on 10000 samples Epoch 1/100 60000/60000 [==============================] - 6s 97us/step - loss: 0.2192 - val_loss: 0.1322 Epoch 2/100 60000/60000 [==============================] - 5s 85us/step - loss: 0.1264 - val_loss: 0.1170 Epoch 3/100 60000/60000 [==============================] - 5s 88us/step - loss: 0.1162 - val_loss: 0.1110 Epoch 4/100 60000/60000 [==============================] - 6s 95us/step - loss: 0.1113 - val_loss: 0.1074 Epoch 5/100 60000/60000 [==============================] - 6s 98us/step - loss: 0.1085 - val_loss: 0.1062 Epoch 6/100 60000/60000 [==============================] - 5s 91us/step - loss: 0.1065 - val_loss: 0.1035 Epoch 7/100 60000/60000 [==============================] - 6s 95us/step - loss: 0.1049 - val_loss: 0.1023 Epoch 8/100 60000/60000 [==============================] - 6s 93us/step - loss: 0.1039 - val_loss: 0.1021 Epoch 9/100 60000/60000 [==============================] - 6s 97us/step - loss: 0.1029 - val_loss: 0.1033 Epoch 10/100 60000/60000 [==============================] - 6s 98us/step - loss: 0.1022 - val_loss: 0.1016 Epoch 11/100 60000/60000 [==============================] - 6s 96us/step - loss: 0.1016 - val_loss: 0.1008 Epoch 12/100 60000/60000 [==============================] - 5s 89us/step - loss: 0.1012 - val_loss: 0.0993 Epoch 13/100 60000/60000 [==============================] - 6s 96us/step - loss: 0.1007 - val_loss: 0.0990 Epoch 14/100 60000/60000 [==============================] - 6s 93us/step - loss: 0.1002 - val_loss: 0.0998 Epoch 15/100 60000/60000 [==============================] - 6s 92us/step - loss: 0.1000 - val_loss: 0.0983 Epoch 16/100 60000/60000 [==============================] - 6s 97us/step - loss: 0.0997 - val_loss: 0.0985 Epoch 17/100 60000/60000 [==============================] - 6s 96us/step - loss: 0.0994 - val_loss: 0.0982 Epoch 18/100 60000/60000 [==============================] - 5s 91us/step - loss: 0.0991 - val_loss: 0.0976 Epoch 19/100 60000/60000 [==============================] - 6s 92us/step - loss: 0.0988 - val_loss: 0.0984 Epoch 20/100 60000/60000 [==============================] - 6s 93us/step - loss: 0.0988 - val_loss: 0.0976 Epoch 21/100 60000/60000 [==============================] - 6s 95us/step - loss: 0.0985 - val_loss: 0.0981 Epoch 22/100 60000/60000 [==============================] - 5s 89us/step - loss: 0.0984 - val_loss: 0.0984 Epoch 23/100 60000/60000 [==============================] - 6s 95us/step - loss: 0.0982 - val_loss: 0.0969 Epoch 24/100 60000/60000 [==============================] - 5s 88us/step - loss: 0.0980 - val_loss: 0.0977 Epoch 25/100 60000/60000 [==============================] - 6s 92us/step - loss: 0.0979 - val_loss: 0.0969 Epoch 26/100 60000/60000 [==============================] - 5s 91us/step - loss: 0.0978 - val_loss: 0.0967 Epoch 27/100 60000/60000 [==============================] - 6s 92us/step - loss: 0.0975 - val_loss: 0.0973 Epoch 28/100 60000/60000 [==============================] - 6s 95us/step - loss: 0.0974 - val_loss: 0.0967 Epoch 29/100 60000/60000 [==============================] - 6s 94us/step - loss: 0.0973 - val_loss: 0.0970 Epoch 30/100 60000/60000 [==============================] - 5s 88us/step - loss: 0.0972 - val_loss: 0.0961 Epoch 31/100 60000/60000 [==============================] - 5s 91us/step - loss: 0.0971 - val_loss: 0.0965 Epoch 32/100 60000/60000 [==============================] - 6s 92us/step - loss: 0.0970 - val_loss: 0.0960 Epoch 33/100 60000/60000 [==============================] - 6s 96us/step - loss: 0.0969 - val_loss: 0.0959 Epoch 34/100 60000/60000 [==============================] - 6s 96us/step - loss: 0.0969 - val_loss: 0.0960 Epoch 35/100 60000/60000 [==============================] - 6s 102us/step - loss: 0.0968 - val_loss: 0.0960 Epoch 36/100 60000/60000 [==============================] - 6s 96us/step - loss: 0.0966 - val_loss: 0.0955 Epoch 37/100 60000/60000 [==============================] - 6s 95us/step - loss: 0.0965 - val_loss: 0.0956 Epoch 38/100 60000/60000 [==============================] - 6s 97us/step - loss: 0.0965 - val_loss: 0.0965 Epoch 39/100 60000/60000 [==============================] - 6s 98us/step - loss: 0.0964 - val_loss: 0.0959 Epoch 40/100 60000/60000 [==============================] - 6s 96us/step - loss: 0.0963 - val_loss: 0.0952 Epoch 41/100 60000/60000 [==============================] - 5s 89us/step - loss: 0.0963 - val_loss: 0.0954 Epoch 42/100 60000/60000 [==============================] - 6s 93us/step - loss: 0.0961 - val_loss: 0.0951 Epoch 43/100 60000/60000 [==============================] - 5s 90us/step - loss: 0.0961 - val_loss: 0.0951 Epoch 44/100 60000/60000 [==============================] - 5s 88us/step - loss: 0.0960 - val_loss: 0.0950 Epoch 45/100 60000/60000 [==============================] - 5s 91us/step - loss: 0.0960 - val_loss: 0.0951 Epoch 46/100 60000/60000 [==============================] - 6s 102us/step - loss: 0.0959 - val_loss: 0.0963 Epoch 47/100 60000/60000 [==============================] - 6s 96us/step - loss: 0.0958 - val_loss: 0.0956 Epoch 48/100 60000/60000 [==============================] - 5s 91us/step - loss: 0.0958 - val_loss: 0.0949 Epoch 49/100 60000/60000 [==============================] - 5s 91us/step - loss: 0.0958 - val_loss: 0.0950 Epoch 50/100 60000/60000 [==============================] - 6s 94us/step - loss: 0.0957 - val_loss: 0.0948 Epoch 51/100 60000/60000 [==============================] - 6s 96us/step - loss: 0.0956 - val_loss: 0.0967 Epoch 52/100 60000/60000 [==============================] - 6s 92us/step - loss: 0.0956 - val_loss: 0.0950 Epoch 53/100 60000/60000 [==============================] - 6s 93us/step - loss: 0.0955 - val_loss: 0.0956 Epoch 54/100 60000/60000 [==============================] - 6s 96us/step - loss: 0.0955 - val_loss: 0.0948 Epoch 55/100 60000/60000 [==============================] - 5s 90us/step - loss: 0.0955 - val_loss: 0.0946 Epoch 56/100 60000/60000 [==============================] - 6s 94us/step - loss: 0.0954 - val_loss: 0.0950 Epoch 57/100 60000/60000 [==============================] - 6s 94us/step - loss: 0.0953 - val_loss: 0.0950 Epoch 58/100 60000/60000 [==============================] - 5s 91us/step - loss: 0.0953 - val_loss: 0.0947 Epoch 59/100 60000/60000 [==============================] - 6s 92us/step - loss: 0.0953 - val_loss: 0.0947 Epoch 60/100 60000/60000 [==============================] - 6s 97us/step - loss: 0.0952 - val_loss: 0.0952 Epoch 61/100 60000/60000 [==============================] - 6s 93us/step - loss: 0.0952 - val_loss: 0.0945 Epoch 62/100 60000/60000 [==============================] - 6s 92us/step - loss: 0.0952 - val_loss: 0.0944 Epoch 63/100 60000/60000 [==============================] - 6s 93us/step - loss: 0.0951 - val_loss: 0.0944 Epoch 64/100 60000/60000 [==============================] - 5s 87us/step - loss: 0.0950 - val_loss: 0.0945 Epoch 65/100 60000/60000 [==============================] - 5s 90us/step - loss: 0.0950 - val_loss: 0.0948 Epoch 66/100 60000/60000 [==============================] - 5s 91us/step - loss: 0.0951 - val_loss: 0.0949 Epoch 67/100 60000/60000 [==============================] - 6s 99us/step - loss: 0.0949 - val_loss: 0.0950 Epoch 68/100 60000/60000 [==============================] - 6s 94us/step - loss: 0.0950 - val_loss: 0.0949 Epoch 69/100 60000/60000 [==============================] - 6s 95us/step - loss: 0.0949 - val_loss: 0.0945 Epoch 70/100 60000/60000 [==============================] - 5s 91us/step - loss: 0.0948 - val_loss: 0.0948 Epoch 71/100 60000/60000 [==============================] - 6s 94us/step - loss: 0.0949 - val_loss: 0.0947 Epoch 72/100 60000/60000 [==============================] - 6s 96us/step - loss: 0.0948 - val_loss: 0.0945 Epoch 73/100 60000/60000 [==============================] - 6s 95us/step - loss: 0.0948 - val_loss: 0.0943 Epoch 74/100 60000/60000 [==============================] - 6s 94us/step - loss: 0.0947 - val_loss: 0.0947 Epoch 75/100 60000/60000 [==============================] - 6s 98us/step - loss: 0.0948 - val_loss: 0.0942 Epoch 76/100 60000/60000 [==============================] - 6s 98us/step - loss: 0.0946 - val_loss: 0.0942 Epoch 77/100 60000/60000 [==============================] - 6s 92us/step - loss: 0.0947 - val_loss: 0.0946 Epoch 78/100 60000/60000 [==============================] - 5s 90us/step - loss: 0.0946 - val_loss: 0.0952 Epoch 79/100 60000/60000 [==============================] - 5s 92us/step - loss: 0.0946 - val_loss: 0.0948 Epoch 80/100 60000/60000 [==============================] - 6s 96us/step - loss: 0.0946 - val_loss: 0.0939 Epoch 81/100 60000/60000 [==============================] - 6s 96us/step - loss: 0.0945 - val_loss: 0.0940 Epoch 82/100 60000/60000 [==============================] - 6s 94us/step - loss: 0.0945 - val_loss: 0.0938 Epoch 83/100 60000/60000 [==============================] - 6s 94us/step - loss: 0.0946 - val_loss: 0.0939 Epoch 84/100 60000/60000 [==============================] - 6s 95us/step - loss: 0.0945 - val_loss: 0.0943 Epoch 85/100 60000/60000 [==============================] - 6s 95us/step - loss: 0.0945 - val_loss: 0.0940 Epoch 86/100 60000/60000 [==============================] - 5s 90us/step - loss: 0.0945 - val_loss: 0.0938 Epoch 87/100 60000/60000 [==============================] - 5s 90us/step - loss: 0.0944 - val_loss: 0.0943 Epoch 88/100 60000/60000 [==============================] - 5s 91us/step - loss: 0.0944 - val_loss: 0.0937 Epoch 89/100 60000/60000 [==============================] - 5s 88us/step - loss: 0.0944 - val_loss: 0.0938 Epoch 90/100 60000/60000 [==============================] - 6s 93us/step - loss: 0.0943 - val_loss: 0.0947 Epoch 91/100 60000/60000 [==============================] - 6s 94us/step - loss: 0.0943 - val_loss: 0.0944 Epoch 92/100 60000/60000 [==============================] - 6s 100us/step - loss: 0.0944 - val_loss: 0.0937 Epoch 93/100 60000/60000 [==============================] - 6s 101us/step - loss: 0.0943 - val_loss: 0.0938 Epoch 94/100 60000/60000 [==============================] - 6s 98us/step - loss: 0.0943 - val_loss: 0.0940 Epoch 95/100 60000/60000 [==============================] - 5s 91us/step - loss: 0.0943 - val_loss: 0.0940 Epoch 96/100 60000/60000 [==============================] - 6s 92us/step - loss: 0.0942 - val_loss: 0.0945 Epoch 97/100 60000/60000 [==============================] - 6s 98us/step - loss: 0.0942 - val_loss: 0.0941 Epoch 98/100 60000/60000 [==============================] - 6s 93us/step - loss: 0.0942 - val_loss: 0.0940 Epoch 99/100 60000/60000 [==============================] - 5s 91us/step - loss: 0.0943 - val_loss: 0.0936 Epoch 100/100 60000/60000 [==============================] - 6s 96us/step - loss: 0.0941 - val_loss: 0.0936
<keras.callbacks.History at 0x2072e3dba58>
decoded_imgs_conv2 = autoencoder_conv2.predict(x_test_noisy)
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+1+n)
plt.imshow(decoded_imgs_conv2[i].reshape(28, 28))
plt.gray()
ax.get_xaxis().set_visible(False)
ax.get_yaxis().set_visible(False)
plt.show()
現在我們來看看結果。第一行展現的是有噪點的數字圖像,以及第二行由網絡重建的數字圖像。 它似乎效果很好。如果您將此過程擴展為更大的卷積網絡,那麼就可以開始構建文檔去噪或音頻去噪的模型。
在這篇文章中有一些個人學習到的一些有趣的重點:
MIT License
Copyright (c) 2017 François Chollet
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.