TensorFlow+TPUの実装がうまくいくようになって、そろそろ本格的にFXのレート予想の研究に入ろうと思ってたところ、1つ問題が発生しました。

いくら計算が高速なTPUとはいえ、毎回5,000、10,000エポックを回すのは大変時間がかかります。

そこで計算結果の進捗が止まった時に計算をストップするようにしました。

そう、EarlyStopping()です。

ところがこれが想定通りに機能してくれません・・・

テストに使用していたのは下記のm=0.8のケースです。

min_delta=1e-5、patience=10に設定すれば、val_lossの変化が1e-5以下が10回続くとバッチが停止する
と考えていました。

ところが想定に反して、学習開始からpatience+αで止まってしまいます。

各ドキュメントの記述は以下のようになっています。

min_delta: Minimum change in the monitored quantity to qualify as an improvement, i.e. an absolute change of less than min_delta, will count as no improvement.

https://www.tensorflow.org/api_docs/python/tf/keras/callbacks/EarlyStopping

min_delta: 監視する値について改善として判定される最小変化値.つまり,min_deltaよりも絶対値の変化が小さければ改善していないとみなします.

https://keras.io/ja/callbacks/

ドキュメント見ても間違いがわかりません・・・
結局EarlyStoppingのソースを見て解決しました。

監視値に対する考え方が実装と異なっていました。(errorの場合)

誤:前回値との値の変化
正:過去最低値との値の変化

この仕様のせいで、”上下しながら少しずつ改善している”ケースでもEarlyStoppingに掛かっていたのでした。

ドキュメントの記述が紛らわしいですよね ヽ(`Д´)ノプンプン

今回のケースのような、”学習序盤は解を探してあちこちさ迷っている”とうまく機能しませんねw

独自版EarlyStoppingを作成しなければ・・・!!

おまけ:

独自のcallbackを作成する際に、callされるタイミングがよくわからなかったので調べてみました。
各メソッドでコメント出力を追加して、fit()した結果です。

1/1 MomentumOptimizer(learning_rate=0.001,momentum=0.8,) 
on_train_begin: 
on_epoch_begin: 0 
on_train_batch_begin: 0 
on_train_batch_end: 0 
on_train_batch_begin: 1 
on_train_batch_end: 1 
on_train_batch_begin: 2 
on_train_batch_end: 2 
on_train_batch_begin: 3 
on_train_batch_end: 3 
on_epoch_end: 0 
on_train_end: 
training end. elapsed 27 sec

ソースによると、fit()で呼ばれるのは on_train_batch_xxxx() のようです。

on_batch_xxxxがどんなケースで呼ばれるのかわかりませんが、私はtf.kerasしか使う予定が無いので良しとしますw

2019/4/8追記

実際に思い通りのEarlyStoppingを作成してみました。
その結果、現在の仕様が支持されている理由がわかりました・・・

shimizuの考えていた仕様だと、上のチャートのように小さな上下振動を繰り返していると、永遠に収束を検知できないですよね・・・_| ̄|○


コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です