###前提
オートエンコーダで事前学習を行った後、学習したモデルの一部と重みを使って回帰分析のための深層学習を行いたいと考えています。
(以下のイメージ、手順・・・、そもそもこれで合っているか?)
MNISTなどの画像の入出力を行うオートエンコーダについては色々紹介されていますが、回帰分析を前提とした事前学習のためのオートエンコーダについては中々事例が見つからず、こちらで質問をさせていただきます。
###実現したいこと
・図のような名前で Dense にレイヤー名をつける
・1. 2. の順で学習を行い、重みを保存する
・3. で 2. までの重みデータを使い、最後を1つのノードにつないで 回帰分析を行う(活性化関数なし)
図1.のモデルでは Input ~ Output まで学習するだけなので問題なく、
図2.のモデルでは encode1 までは重みを固定して学習しないように
・図1.&2.のモデル で 同じレイヤーに同じ名前をつける(name = 'enc_1'など)
・図2. のモデルで 図1. でも作ったレイヤーは学習を禁止する(trainable = False)
としました。
(以下のコードの様に)
Python
1 2# AutoEncoder 1 3input_ = Input(shape = (input_size, )) 4encoded = input_ 5 6e = Dense(dense_size_AE11, activation = AF, kernel_initializer = kinit, name = 'enc_1')(encoded) 7 8decoded = Dense(input_size, activation = None, name = 'dec_2')(e) 9output_ = decoded 10 11model = Model(input_, output_) 12 13encoder = Model(input_, encoded) 14decoder = Model(input_, decoded) 15 16(中略) 17 18# AutoEncoder 2 19input_ = Input(shape = (input_size, )) 20encoded = Dense(dense_size_AE11, trainable = False, name = 'enc_1')(input_) 21e = Dense(dense_size_AE12, activation = AF, kernel_initializer = kinit, name = 'enc_2')(encoded) 22 23decoded = Dense(dense_size_AE11, activation = AF, kernel_initializer = kinit, name = 'dec_1')(e) 24output_ = Dense(input_size, activation = None, trainable = False,name = 'dec_2')(decoded) 25 26model = Model(input_, output_) 27 28encoder = Model(input_, encoded) 29decoder = Model(input_, decoded) 30
なお、input からノード数が減るところまでを encoder として、
同じく output までを decoder として別途定義して、モデルを3種類作成しています。
ここまでは良かったのですが、結果的に、図2. のモデルの学習で躓きました。
上記のやり方で学習を行うと 1. の損失関数は順調に良くなるのですが、
図2. の学習では 損失関数が一向に良くならないため、原因を考えました。
###試したこと
回帰分析のため、損失関数には mse を使いました。
図1. のモデルは encoder + decoder = model になるので無事学習できたのだと思います。
一方 図2. のモデルは 凍結レイヤーを含んでいるため
mse の計算は 下図で言うと input と output の差から計算するものだと思いますが、
encode1 ~ encode2 ~ decode1 と訓練するなら encode1 と decode1 の差が必要で、
当然 input ≠ encode1 だし、decode1 ≠ output となるため、
図1.のモデルと同じように普通に mse 最小となるよう学習しても うまくいかないのではないか、
と考えました。
要は図2. の右側のように 凍結レイヤーがない状態で mse を計算しないといけないと思ったので、
Python
1ae_hist = model.fit(encoder.predict(X_train), decoder.predict(X_train), batch_size = BATCH_SIZE, 2 initial_epoch = INITIAL, epochs = EPOCHS, 3 validation_data = (encoder.predict(X_val), decoder.predict(X_val)) 4 5''' 6元々は以下のように学習していたものを train と val を上記の様に変更した 7hist = model.fit(X_train, y_train, batch_size = BATCH_SIZE, initial_epoch = INITIAL, 8 epochs = EPOCHS, validation_data = (X_val, y_val)) 9''' 10
として学習したところ、以下のようなエラーが出ました。
ValueError: Error when checking input: expected input_2 to have shape (8,) but got array with shape (6,)
試した内容に無理があったので、エラーが出る原因はすぐにわかりました。
encoder.predict(X_train) としてしまうと、Input のデータのノード数が変わるからなので
この方法は諦めようと思っています。
他に 図2. の学習ができるような 損失関数の定義、もしくはモデルの構築方法はないでしょうか?
###環境
Python 3.6.8
keras 2.2.4
tensorflow 1.13.1
あなたの回答
tips
プレビュー