一段全結合の AutoEncoder による、MNist の画像の色付け
参考 2019-09-08 Python: Keras で AutoEncoder を書いてみる 「CUBE SUGAR CONTAINER 技術系のこと書きます。」
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#https://blog.amedama.jp/entry/keras-auto-encoder
import numpy as np
from keras import layers
from keras import models
from keras import callbacks
from keras.datasets import mnist
import cv2
from matplotlib import pyplot as plt
from matplotlib import cm
import sakamoto as s
def getColorArray(x,y,c):
result=[]
for i in range(len(x)):
result.append(s.colorizeImage(x[i],c[y[i]]))
return result
image_height, image_width, image_depth = 28, 28, 3
# 中間層で圧縮される次元数
encoding_dim = 36 # 中間層の出力を 6 x 6 の画像として可視化するため
def main():
# MNIST データセットを読み込む
(x_train, y_train), (x_test, y_test) = mnist.load_data()
#white , red, blue, green ,cyan , yellow,orange, greenyellow, pink, saddlebrown
cstr='#ffffff #ff0000 #0000ff #008000 #00ffff #ffff00 #ffa500 #adff2f #ffc0cb #8b4513'
carray=s.getColorSet(cstr)
z_train=np.array(getColorArray(x_train,y_train,carray))
z_test=np.array(getColorArray(x_test,y_test,carray))
x_train = x_train.reshape(x_train.shape[0], image_height * image_width)
x_test = x_test.reshape(x_test.shape[0], image_height * image_width)
z_train = z_train.reshape(z_train.shape[0], image_height * image_width*image_depth)
z_test = z_test.reshape(z_test.shape[0], image_height * image_width*image_depth)
# Normalization
x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
x_train = x_train / 256
x_test = x_test /256
z_train = z_train.astype('float32')
z_test = z_test.astype('float32')
z_train = z_train / 256
z_test = z_test /256
# p = np.random.random_integers(0, len(x_test), 10)
# x_test_sampled = x_test[p]
# x_test_sampled_pred = z_test[p]
# x_test_sampled_enc = np.array([a[0:encoding_dim] for a in x_test[p]])
# print(x_test_sampled_enc.shape)
# plotresult(p,y_test,x_test_sampled,x_test_sampled_enc,x_test_sampled_pred)
# print('+++++++++++++++++++++++++++++++++++++++++++++++++++++')
# cv2.waitKey(0)
model = models.Sequential()
model.add(layers.Dense(encoding_dim, activation='relu',
input_shape=(image_height * image_width,)))
model.add(layers.Dense(image_height * image_width * image_depth,
activation='sigmoid'))
print(model.summary())
model.compile(optimizer='adam',
loss='binary_crossentropy')
fit_callbacs = [
callbacks.EarlyStopping(monitor='val_loss',
patience=5,
mode='min')
]
# モデルを学習させる
model.fit(x_train, z_train,
epochs=100,
batch_size=256,
shuffle=True,
validation_data=(x_test, z_test),
callbacks=fit_callbacs,
)
# テストデータの損失を確認しておく
score = model.evaluate(x_test, z_test, verbose=0)
print('test xentropy:', score)
# 学習済みのモデルを元に、次元圧縮だけするモデルを用意する
encoder = models.clone_model(model)
encoder.compile(optimizer='adam',
loss='binary_crossentropy')
encoder.set_weights(model.get_weights())
# 最終段のレイヤーを取り除く
encoder.pop()
# テストデータからランダムに 10 点を選び出す
p = np.random.random_integers(0, len(x_test), 10)
x_test_sampled = x_test[p]
# 選びだしたサンプルを AutoEncoder にかける
x_test_sampled_pred = model.predict_proba(x_test_sampled,
verbose=0)
# 次元圧縮だけする場合
x_test_sampled_enc = encoder.predict_proba(x_test_sampled,
verbose=0)
plotresult(p,y_test,x_test_sampled,x_test_sampled_enc,x_test_sampled_pred)
def plotresult(p,y,sampled,enc,pred):
# 処理結果を可視化する
fig, axes = plt.subplots(3, 10)
for i, label in enumerate(y[p]):
# 元画像を上段に表示する
img = sampled[i].reshape(image_height, image_width)
axes[0][i].imshow(img, cmap='gray')
axes[0][i].axis('off')
axes[0][i].set_title(label, color='red')
# AutoEncoder で次元圧縮した画像を下段に表示する
enc_img = enc[i].reshape(6, 6)
axes[1][i].imshow(enc_img, cmap='gray')
axes[1][i].axis('off')
# AutoEncoder で復元した画像を下段に表示する
pred_img = pred[i].reshape(image_height, image_width, image_depth)
pred_imgrgb = cv2.cvtColor(pred_img, cv2.COLOR_BGR2RGB)
axes[2][i].imshow(pred_imgrgb)
axes[2][i].axis('off')
plt.show()
if __name__ == '__main__':
main()