Tensorflow2.0環境で動くように手直ししたkerasのAutoencoderサンプルに中間層の出力をつけくわえてみました。
今回やってみること
前回、keras Blogの「Building Autoencoders in Keras」を、Tensorflow2.0環境で動くようにしてみました。
ついでなので、中間レイヤーの出力も以前と同じようにできるかやってみます。
ポイント
ベースは前回のソースです。
なので、以前のkerasと、tensorflow2.0環境のtf.kerasの違いの吸収方法について、繰り返しは説明しません。
kerasで中間レイヤーを出力する方法のおさらいだけやります。
まず、出力対象とする中間レイヤー名称が必要です。
これは「summary()」を使います。
今回の場合だと、こうです。
autoencoder.summary()
出力例です。
左端のLayer列の「dense_1」等が指定する名前です。
もうひとつ重要な情報が「output shape」です。
画像で中間レイヤーのイメージを出力時のreshape()に必須の情報です。
今回は「dense_4」の出力する例にします。
まず、入力から中間レイヤーまでのモデルを生成します。
intermediate_layer_model = tf.keras.Model(
inputs=input_img,
outputs=autoencoder.get_layer('dense_4').output)
そして、そのモデルで「predict()」して、そのアウトプットを出力します。
intermediate_imgs = intermediate_layer_model.predict(x_test)
あとは、最後の出力に追加します。
# display reconstruction
ax = plt.subplot(3, n, i + 1 + n)
plt.imshow(intermediate_imgs[i].reshape(16, 8))
plt.gray()
ax.get_xaxis().set_visible(False)
ax.get_yaxis().set_visible(False)
サイズが128なので、reshape(16, 8)にします。
これで中間レイヤーの出力ができます。
ソースコード全文です
Deep autoencoderのケースだけやってます。
データはファッションMINISTに変えてみました。
import tensorflow as tf from tensorflow.keras.layers import Dense from tensorflow.keras.datasets import fashion_mnist as mnist import numpy as np # use Matplotlib (don't ask) import matplotlib.pyplot as plt # this is the size of our encoded representations # 32 floats -> compression of factor 24.5, assuming the input is 784 floats encoding_dim = 32 # this is our input placeholder input_img = tf.keras.Input(shape=(784,)) encoded = Dense(128, activation='relu')(input_img) encoded = Dense(64, activation='relu')(encoded) encoded = Dense(32, activation='relu')(encoded) decoded = Dense(64, activation='relu')(encoded) decoded = Dense(128, activation='relu')(decoded) decoded = Dense(784, activation='sigmoid')(decoded) # this model maps an input to its reconstruction autoencoder = tf.keras.Model(inputs=input_img, outputs=decoded) autoencoder.summary() (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) autoencoder.compile( optimizer=tf.keras.optimizers.Adam(), loss=tf.keras.losses.BinaryCrossentropy()) # autoencoder.load_weights('autoencoder.h5') autoencoder.fit(x_train, x_train, epochs=100, batch_size=256, shuffle=True, validation_data=(x_test, x_test)) autoencoder.save_weights('autoencoder.h5') # encode and decode some digits # note that we take them from the *test* set decoded_imgs = autoencoder.predict(x_test) intermediate_layer_model = tf.keras.Model( inputs=input_img, outputs=autoencoder.get_layer('dense_4').output) intermediate_imgs = intermediate_layer_model.predict(x_test) n = 10 # how many digits we will display plt.figure(figsize=(10, 4)) for i in range(n): # display original ax = plt.subplot(3, 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) # display reconstruction ax = plt.subplot(3, n, i + 1 + n) plt.imshow(intermediate_imgs[i].reshape(16, 8)) plt.gray() ax.get_xaxis().set_visible(False) ax.get_yaxis().set_visible(False) # display reconstruction ax = plt.subplot(3, n, i + 1 + n + 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()
今回も学習を繰り返さなくてすむように
autoencoder.save_weights('autoencoder.h5')
を追加しています。
一度学習したあとは、こちらをコメントアウトして、こちら
# autoencoder.load_weights('autoencoder.h5')
のコメントを外して、結果表示してます。
実行します。
ロス率は、たぶん、0.27あたりで頭打ちにはなります。
上段が元画像・中に中間レイヤー画像、下段に結果画像を10個表示します。
今回はこんなところで。
ではでは。