KerasでAutoEncoder【備忘録】

はじめに

こんにちは、がんがんです。
大学の前期期間中、ノイズ除去に関することをよく学習してました。
Kerasのコーディング力を高めるためにやってました。


今回は、そのときのことを思い出しながら、改めて実験してみます。
以前参考にしたのはこちらです。
Kerasで学ぶAutoencoder


今回はKerasのブログを見ながら改めて実験してみました。
Building Autoencoders in Keras

思い出してやってみると、結構忘れているところもあったのでやってみてよかったです。

追記【2018.12.27】

鹿児島大学生 Advent Calendar 2018の11日目にて掲載させて頂いております。
見て頂きありがとうございます。

参考記事

参考記事を改めてまとめておきます。
elix-tech.github.io

Building Autoencoders in Keras

AutoEncoderは昔からある技術です。AEの理解はこちらを参考にしました。
deepage.net

AutoEncoder

まずはベースのAEを試していきます。

コード

#------------------------------------------------------------
#
#	AutoEncoder
#		https://blog.keras.io/building-autoencoders-in-keras.html
#------------------------------------------------------------
import numpy as np
import matplotlib.pyplot as plt

from keras.layers import Input, Dense
from keras.models import Model
from keras.datasets import mnist

"""
	モデル構築
"""
encoding_dim = 32
input_img = Input(shape=(784,))

#  Encode部分
encoded = Dense(encoding_dim, activation="relu")(input_img)
encoder = Model(input_img, encoded)

#  Decode部分
decoded = Dense(784, activation="sigmoid")(encoded)

autoencoder = Model(input_img, decoded)

encoded_input = Input(shape=(encoding_dim,))
decoder_layer = autoencoder.layers[-1]
decoder = Model(encoded_input, decoder_layer(encoded_input))


"""
	モデルコンパイル
"""
autoencoder.compile(optimizer="adadelta",
		    loss="binary_crossentropy")
					
"""
	データ読み込み
"""
(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:])))

autoencoder.fit(x_train, x_train,
		epochs=50,
		batch_size=256,
		shuffle=True,
		validation_data=(x_test, x_test))
				 
encoded_imgs = encoder.predict(x_test)
decoded_imgs = decoder.predict(encoded_imgs)

"""
	データの可視化
"""
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()

結果

MNISTなのでやはりすぐに結果が出ますね。

f:id:gangannikki:20181206161029p:plain
上段:オリジナル画像 下段:出力画像

Deep AE

こちらは層を少しだけ深くしたAutoEncoderになります。

コード

#------------------------------------------------------------
#
#	DeepAutoEncoder
#		https://blog.keras.io/building-autoencoders-in-keras.html
#------------------------------------------------------------
import numpy as np
import matplotlib.pyplot as plt
from keras.layers import Input, Dense
from keras.models import Model
from keras.datasets import mnist
from keras.utils import plot_model

"""
	モデル生成
"""
input_img = Input(shape=(784,))

#  Encode部分
encoded = Dense(128, activation="relu")(input_img)
encoded = Dense(64, activation="relu")(encoded)
encoded = Dense(32, activation="relu")(encoded)

#  Decode部分
decoded = Dense(64, activation="relu")(encoded)
decoded = Dense(128, activation="relu")(decoded)
decoded = Dense(784, activation="sigmoid")(decoded)

#  Model
autoencoder = Model(input_img, decoded)
autoencoder.compile(optimizer="adadelta",
		    loss="binary_crossentropy")

#  アーキテクチャの可視化
plot_model( autoencoder, to_file="architecture.png" )

"""
	データ読み込み
"""
(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:])))

epochs = 100
batch_size = 256

autoencoder.fit(x_train, x_train,
		epochs=epochs,
		batch_size=batch_size,
		shuffle=True,
		validation_data=(x_test, x_test))
				 
"""
	データの可視化
"""
decoded_imgs = autoencoder.predict(x_test)

n = 10
plt.figure(figsize=(20, 4))
for i in range(n):
	#  display original
	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()

結果

f:id:gangannikki:20181207181152p:plain
上段:オリジナル画像 下段:出力画像

Convolutional AE

MNISTは28×28の画像です。画像を扱う場合はDense層よりもConvolution層を用いたほうがより特徴を抽出することが可能です。

コード

#------------------------------------------------------------
#
#    CAE
#        https://blog.keras.io/building-autoencoders-in-keras.html
#
#------------------------------------------------------------
import numpy as np
import matplotlib.pyplot as plt
from keras.layers import Input, Conv2D, MaxPooling2D, UpSampling2D
from keras.models import Model
from keras.datasets import mnist
from keras import backend as K
from keras.utils import plot_model
from keras.callbacks import TensorBoard

"""
	モデルの生成
"""
input_img = Input(shape=( 28, 28, 1))

#  Encode_Conv1
x = Conv2D( 16, (3, 3), activation='relu', padding='same' )(input_img)
x = MaxPooling2D(( 2, 2), padding='same' )(x)
#  Encode_Conv2
x = Conv2D( 8, (3, 3), activation='relu', padding='same' )(x)
x = MaxPooling2D(( 2, 2), padding='same' )(x)
#  Encode_Conv3
x = Conv2D( 8, (3, 3), activation='relu', padding='same' )(x)
encoded = MaxPooling2D(( 2, 2), padding='same' )(x)

#  Decode_Conv1
x = Conv2D( 8, (3, 3), activation='relu', padding='same' )(encoded)
x = UpSampling2D(( 2, 2))(x)
#  Decode_Conv2
x = Conv2D( 8, (3, 3), activation='relu', padding='same' )(x)
x = UpSampling2D(( 2, 2))(x)
#  Decode_Conv3
x = Conv2D( 16, (3, 3), activation='relu' )(x)
x = UpSampling2D(( 2, 2))(x)
#  Decode_Conv4
decoded = Conv2D( 1, (3, 3), activation='sigmoid', padding='same' )(x)

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

#  アーキテクチャの可視化
plot_model( autoencoder, to_file="architecture.png" )

"""
	データの読み込み
"""
(x_train, _), (x_test, _) = mnist.load_data()    #  (60000, 28, 28)
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) )

epochs = 50
batch_size = 128

autoencoder.fit(x_train, x_train,
		epochs=epochs,
		batch_size=batch_size,
		shuffle=True,
		validation_data=(x_test,x_test),
		callbacks=[TensorBoard(log_dir='./autoencoder')] )

"""
	グラフへ可視化
"""
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()

結果

モデルの構造、結果画像の順に示します。

f:id:gangannikki:20181209235322p:plain
アーキテクチャ

f:id:gangannikki:20181207181235p:plain
上段:オリジナル画像 下段:出力画像

まとめ

今回はAutoEncoderを中心にまとめました。
改めてやり直すと忘れていることが多いですね。

次回はノイズ除去で使用されているDenoising AE(通称、DAE)についてまとめていきます。