「モデルにDropoutを噛ませたら,テスト時にはDropout_rate=0にしましょう」という今更すぎる自戒です.
Dropout
Dropoutは,モデルのOverfittingを防ぐテクニック.
学習epoch毎に,ネットワークのweightを一定の割合(Dropout_rate)無視する(敢えてモデルの表現能力をフルに使わない)ことで,より広いデータにフィットするモデルを獲得する.無視するweightは毎epoch変わる.
テスト時には全てのweightを使って(Dropout_rate=0で)predictを行う.
やらかしたこと
テスト時にもDropoutしていた.
TensorFlowの方で,訓練とテストでよしなにDropout_rateを変えてくれると勝手に思っていたんです許して.
具体的には
def my_model(input):
hidden = tf.layers.dense(input, unit=2048, activation=tf.nn.sigmiod)
dropout = tf.layers.dropout(inputs=hidden, rate=0.2)
みたいにモデル定義にDropout_rateを直書きしていた.これだとテスト時にも2割のweightを無視してしまう.
正しくは
モデルの方では引数でDropout_rateを決めるようにしておいて,
def my_model(input, drate):
dropout = tf.layers.dropout(inputs=hidden, rate=drate)
runするときにplaceholderからdrateを指定してやる.
drate_p = tf.placeholder(tf.float32)
model = my_model(input_p, drate_p)
sess=tf.Session()
sess.run([model], {input_p: my_image, drate_p: 0.2})
テスト時にはdrate_p: 0.0でrunすればいい.
ちなみにkerasだとmodel.fitの時とmodel.predictの時でよしなにやってくれそう.