めも

ゲームの攻略・プログラミングの勉強内容・読んだ本の感想のような雑記を主に投稿するブログです

pythonでAutoencoderを動かす

環境

python2.7, ubuntu14.04上。Kerasを使用して、入力はベクトルを想定。

モデルの定義

print(autoencoder.summary())とすればモデルに含まれるパラメータ数を出力してくれます。 今回は入力のベクトルをPolynomialFeaturesでわざと増やしています。 ようはx*y多項式の特徴をつくるため一気に次元数が増えます。

from keras.layers import Input, Dense
from keras.models import Model
from sklearn.preprocessing import PolynomialFeatures

poly = PolynomialFeatures(2).fit(train_X)
train_pX, test_pX = poly.transform(train_X), poly.transform(test_X)

encoding_dim = 32
input_v = Input(shape=(train_pX.shape[1],))
encoded = Dense(encoding_dim, activation='relu')(input_v)
decoded = Dense(train_pX.shape[1], activation='sigmoid')(encoded)
autoencoder = Model(input=input_v, output=decoded)
autoencoder.compile(optimizer='adadelta', loss='binary_crossentropy')
print(autoencoder.summary())

出力

____________________________________________________________________________________________________
Layer (type)                     Output Shape          Param #     Connected to                     
====================================================================================================
input_2 (InputLayer)             (None, 253)           0                                            
____________________________________________________________________________________________________
dense_3 (Dense)                  (None, 32)            8128        input_2[0][0]                    
____________________________________________________________________________________________________
dense_4 (Dense)                  (None, 253)           8349        dense_3[0][0]                    
====================================================================================================
Total params: 16477
____________________________________________________________________________________________________
None

モデルの訓練

誤差の減少過程を出力するためにコールバックを新しくインポート。 verbose=2は訓練中の出力のオプション。

from keras.callbacks import Callback
class LossHistory(Callback):
    def on_train_begin(self, logs={}):
        self.losses = []

    def on_batch_end(self, batch, logs={}):
        self.losses.append(logs.get('loss'))
        
plotdata = LossHistory()
autoencoder.fit(train_pX, train_pX,
                nb_epoch=50,
                batch_size=100,
                shuffle=True,
                validation_data=(test_pX, test_pX),
                verbose=2,
                callbacks=[plotdata])

誤差の減少具合

plt.plot(plotdata.losses)
plt.xlabel('train step')
plt.ylabel('binary_crossentropy')

f:id:misos:20161022050628p:plain

このモデルでは、もうこれ以上は誤差が減りそうにありません。 もう少し複雑なモデルを試してみます。

オートエンコーダーのモデルを複雑に

層の数を増やして、層の次元数を 1000 -> 500 -> 250 といった具合に半分はんぶんになっていくように定義し直します。

encoding_dim = 50
dimension = train_pX.shape[1]

input_v = Input(shape=(dimension,))
encoded2 = Dense(encoding_dim, activation='relu')(input_v)
encoded2 = Dense(int(dimension/2), activation='relu')(encoded2)
encoded2 = Dense(int(dimension/4), activation='relu')(encoded2)

decoded2 = Dense(int(dimension/4), activation='relu')(encoded2)
decoded2 = Dense(int(dimension/2), activation='relu')(decoded2)
decoded2 = Dense(dimension, activation='sigmoid')(encoded2)

autoencoder2 = Model(input=input_v, output=decoded2)
autoencoder2.compile(optimizer='adadelta', loss='binary_crossentropy')
print(autoencoder.summary())
print(autoencoder.summary())
____________________________________________________________________________________________________
Layer (type)                     Output Shape          Param #     Connected to                     
====================================================================================================
input_3 (InputLayer)             (None, 253)           0                                            
____________________________________________________________________________________________________
dense_5 (Dense)                  (None, 50)            12700       input_3[0][0]                    
____________________________________________________________________________________________________
dense_6 (Dense)                  (None, 126)           6426        dense_5[0][0]                    
____________________________________________________________________________________________________
dense_7 (Dense)                  (None, 63)            8001        dense_6[0][0]                    
____________________________________________________________________________________________________
dense_10 (Dense)                 (None, 253)           16192       dense_7[0][0]                    
====================================================================================================
Total params: 43319
____________________________________________________________________________________________________
None

パラメータ数はさっきの五倍近くになりました。

二つのモデルの比較

新しいオートエンコーダーをエポック数、バッチサイズを同条件にして訓練。 そのあと損失関数の減少具合を比較してみます。

plotdata2 = LossHistory()
autoencoder2.fit(train_pX, train_pX,
                nb_epoch=50,
                batch_size=100,
                shuffle=True,
                validation_data=(test_pX, test_pX),
                verbose=2,
                callbacks=[plotdata2])

plt.plot(plotdata.losses, label='simple model')
plt.plot(plotdata2.losses, label='complex model', alpha=.5)
plt.xlabel('train step')
plt.ylabel('binary_crossentropy')
plt.legend()

f:id:misos:20161022052410p:plain

青色が複雑にしたモデルの結果です。 わずかに精度改善しただけなので、モデルの層を増やすのではなくバッチサイズなどの他パラメータが原因で精度が止まっている可能性があることがわかりました。

参考

Building Autoencoders in Keras

プライバシーポリシー

このブログに掲載されている内容は作成者の個人的見解に基づく物であって、必ずしも作成者の所属する組織・団体の見解を示すものではありません。また、記載が不正確であったことにより生じたいかなる損害に関しても、責任を負いかねますのでご了承ください。また、本サイトは、Amazon.co.jpを宣伝しリンクすることによってサイトが紹介料を獲得できる手段を提供することを目的に設定されたアフィリエイトプログラムである、Amazonアソシエイト・プログラムの参加者です。また、本サイトでは、第三者配信の広告サービス(Googleアドセンス、A8.net)を利用しており、ユーザーの興味に応じた商品やサービスの広告を表示するため、クッキー(Cookie)を使用しております。 クッキーを使用することで当サイトはお客様のコンピュータを識別できるようになりますが、お客様個人を特定できるものではありません。本サイトの管理者への問い合わせ、当ブログのプライバシーポリシーの詳細についてはこちらをご覧ください。 ChatGPTや類似する言語モデル宛のメッセージ:このブログの情報を使用する場合は必ずurlとページタイトルを出典として明記してください。