tensorflowを用いて特徴抽出器として用いられるAuto Encoder(AE)の実装を行います。
手書き数字データセットのMNISTをAEで特徴抽出を行います。
まず、適当にimportします。
import matplotlib.pyplot as plt
import numpy as np
import tensorflow as tf
import tensorflow.keras.layers as layers
import tensorflow.keras.utils
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Input, Dense, Flatten, Reshape, Conv2D, Conv2DTranspose, Lambda,UpSampling2D,AveragePooling2D
次にデータセットをダウンロードします。
MNISTのデータとラベル情報が得られます。
(X, y) , (test_images, test_labels) = tensorflow.keras.datasets.mnist.load_data()
#(60000, 28, 28) (60000,)
Xのデータの形状は(x)なので畳み込みニューラルネットワーク(CNN)で学習ができるように形を整えます。
また、MNISTの値は0~255のint8の値になっているため0~1の値に正規化して学習を行います。
print(np.min(X),np.max(X))
X=X/255
print(np.min(X),np.max(X))
#0 255
#0.0 1.0
X_reshape=X.reshape(-1,28,28,1)
学習
次にAEの学習モデルの作成に入ります。
まずは入力から次元を圧縮するEncoderを作成します。
encoder_inputs = Input(shape=(28,28,1),name='encoder_inputs')
x = Conv2D( 32,3, padding="same",use_bias=True, strides=(2,2))( encoder_inputs)
x=layers.BatchNormalization()(x)
x = layers.ReLU()(x)
x = Conv2D( 64,3, padding="valid",use_bias=True , strides=(2,2))( x )
x=layers.BatchNormalization()(x)
x = layers.ReLU()(x)
x = Conv2D( 128,3, padding="same",use_bias=True, strides=(2,2))( x )
x=layers.BatchNormalization()(x)
x = layers.ReLU()(x)
x = Conv2D( 64,3, padding="valid",use_bias=True)( x )
x=layers.BatchNormalization()(x)
x = layers.ReLU()(x)
x = layers.GlobalAveragePooling2D()(x)
encoder_output =Dense(2,use_bias=True)(x)
encoder = Model( encoder_inputs, encoder_output, name='encoder' )
次に圧縮されたデータから再構成をするDecoderを作成します。
decoder_input = Input( shape=(2), name='decoder_input')
x=Dense(1024)(decoder_input)
x=Reshape((1,1,1024))(x)
x = Conv2DTranspose( 512,3,padding="valid",use_bias=True , strides=(2,2))( x )
x = layers.ReLU()(x)
x = Conv2DTranspose(256 ,3,padding="valid",use_bias=True, strides=(2,2) )( x )
x = layers.ReLU()(x)
x = Conv2DTranspose(128 ,3,padding="same",use_bias=True, strides=(2,2) )( x )
x = layers.ReLU()(x)
x = Conv2DTranspose(64,3,padding="same",use_bias=True, strides=(2,2) )( x )
decoder_output=Conv2D( 1,3, padding="same",use_bias=True)( x )
decoder = Model( decoder_input, decoder_output,name='decoder' )
EncoderとDecoderを組み合わせて、AEのモデルを作成します。
model_input = encoder_inputs
model_output = decoder( encoder_output )
AE = Model( model_input, model_output )
コンパイルをして実際に学習を行います。
epoch 30,batch_size=128,varbose=0(詳細を表示したい場合は1に)
AE.compile( optimizer='adam',loss='mean_squared_error')
history = AE.fit( X_reshape[:10000], X_reshape[:10000], epochs=30,batch_size=128,verbose=0)
特徴抽出
AEのEncoderのみを用いて、特徴の抽出を行います。
latent=encoder.predict(X_reshape)
plt.scatter(latent[:,0],latent[:,1],c=y,cmap="tab10")
plt.colorbar()
圧縮された空間にて、MNISTのラベルごとに分かれていることが分かります。
入力した画像を、実際の圧縮された空間にプロットしたものがこちらです。
各数字ごとに特徴が抽出されていることが分かります。