Deep Learning training の待ち時間にすべきこと

Deep Learning の training 時間は短いものでは数十分、長いものでは数日に及ぶ。その training が走っている間は、何をすると1番プロダクティブだろうか。いくつかの候補とそれぞれの利点と欠点を以下にまとめてみた。

SNS やメールのチェック

コーディング時には後回しにしていた、返事をするのも良いだろう。欠点はもちろん皆さんご存知の通り。気づいたらあっという間に時間を吸い取られること。そしてプロジェクトへのフォーカスが失われることだ。

リファクタリング

コードを常にクリーンに保つことは、プロジェクト全体のプロダクティビティ向上に通じる。ただし機械学習のコードはテストが書けない場合が多いので注意が必要。テストによって支えられていないリファクタリングでは必ず IDE の助けを借りよう。リファクタリングの欠点は2つ。1つ目は現在走っているコードと、リファクタリングによって改善された head のコードが離れてしまうことだ。training 用のコードにバグが見つかったら、どちらを編集すべきだろうか?などと考えないといけない。2点目は、リファクタリングは重要だがプロジェクトを前に進めるものではないということだ。そもそも現在流している training コードが向いている方向が間違っていたらリファクタリングに特に意味はない。

Self code review

個人プロジェクトの場合、誰かにコードをレビューされることはない。時間が空いたときに落ち着いて、最近書いたコードを読み直してみるのも良いだろう。これは先述のリファクタリングとほぼ同様の利点・欠点がある。

プランニング

空いている時間に、プロジェクトの方向性や次の一手などを見つめ直すのも良いだろう。コードから視点を上げて、プロジェクトがうまく行っているか見つめることは、全体のプロダクティビティ向上に大きく役立つだろう。ただし多くの場合、次の一手は今走っている training に依存するので効果は限定的な場合もある。

関連論文・ブログを読む

機械学習では、論文を読むことは避けられない作業である。関連研究やトレンドなどを追うことで、プロジェクトの成功率を高めることができるだろう。欠点は(これは筆者だけかもしれないが)、数時間もぶっ続けで論文を読めないことだ。Training の空き時間中、ずっと論文読むのは無理だ。

プロジェクトの別タスク

理想的にはプロジェクト内に 2-3 個の別タスクがあるのが望ましい。ブロックされたら残りのタスクに並行して取り組むのだ。プロジェクトへのフォーカスを失うことなく、プロダクティビティを上げることができる。難しいのは別タスクがそもそもあるかどうか。それらが良い感じに独立しているかどうかだ。

別プロジェクト

空き時間に全く別のプロジェクトに取り組むのも一つの手だ。training とは完全に独立している。メインプロジェクトが失敗した場合のバックアップにもなる。欠点は完全なコンテキストスイッチが必須になることだ。training 後にタスクを resume するときに若干の苦労を要する。

まとめ

筆者自身のためにまとめてみたが、決定打がない。もし他にアイデアがあったらぜひ教えてほしい。ちなみに別のレイヤの話として long running training を流す前に小さなデータセットで実験してみるなどの Tips があると思うので、いずれまとめたい。

RL Course by David Silver - Lecture 1 - Reinforcement Learning(強化学習)勉強メモ

Lecture PDF and YouTube.


授業を聞きながらスライドにいくつかメモしたPDF

Deep Reinforcement Learning: Pong from Pixels - Reinforcement Learning(強化学習)勉強メモ

http://karpathy.github.io/2016/05/31/rl/ 入門から実践までカバーしていて大変よい。日本語訳は https://postd.cc/deep-reinforcement-learning-pong-from-pixels-1/ にある。

  • Actions は Pong のゲームのバーを Up or Down する。
  • Reward はボールを相手のバーの向こうに飛ばせたら +1、自分がミスしたら -1。それ以外は 0 とする。
  • 入力は 210x160x3 の image frame をプリプロセスしたもの。(前後のフレームの差にするとか)
  • Agent は入力とRewardしか知らない。ゲームのルールやコツを知らない。
  • Policy Network
    • 2層のNN。bias なし。
    • 1層目がゲームの状況(ボールが上の方にあるとか、バーが真ん中にいるとか)
    • 2層目がその状況のときに Up すべきか。を決める。
    • 出力は Up の確率。最後に sigmoid で。
  • Supervised learning
    • ある image frame X に対してTarge Label y が Up だとすると。gradient 1 を backprop で入力して全ての parameters が Up の方向に動くようにモデルを更新する。
  • Policy Gradient と Supervised learning との違い
    • Label y が分からない。仮にある image frame に対しての Upの確率が0.6の場合、それは正解だろうか?正解となる訓練データがない。困った。
    • ところで log probability -1.2 がなぜ 30% になるのだろうか。sigmoid(-1.2)=0.23 なのだけど。
  • Policy Gradient の手順
    • モデルからサンプリングする。例)30% なら Down となる
    • これを正解として backprop してもいいけど。現時点では正解かどうかはわからない。
    • 分からないなら、正解がわかるまでまとう(ここが肝)
      • Pong の場合はシンプルにゲームが終わるまで待てば良い。勝てば +1 負けたら -1 の Reward をもらう(Reward の定義が上記と変わったね)
    • 例に出した Down をしたあとに最終的に負けたのであれば -1.0 を backprop でフィードバックする。モデルが Input の Image Frameに対して Down を出力しない方向に少しだけ賢くなる
  • Policy Gradient の Training
    • モデルパラメータの初期化。通常のNNと同じ。
    • 100 game プレイする。これを 1 rollout と呼ぶ。
    • 1 game は 200 frame。
    • 1 rollout 毎に 200 - 100 回の Up/Down の決断をしている
    • この全ての決断に対して parameter を学習する。
    • これが終わったら次の 1 rollout を学習する
  • 別の見方(alternative view)
    • Tensorflow など backdrop を考えなくても良いフレームワークの場合には上の考え方は分かりづらいかもしれないので別の見方を紹介する。
  • Supervised learning との違いは
    • Label y_i がないので x_i をサンプルしてその結果を y_i としている
    • 最終的な結果 Game に勝ったかどうかで loss を掛け算で調節する。そうすることで良いアクションでは log probability を上げる。だめなアクションでは逆に下げるのだ。
    • なので A_i (advantage) を log prob に掛ける形になったものを maximize する。A_i が 1 なら log(y_i|x_i) が大きくなる方向に動く。A_j が -1 なら log(y_j|x_j) が小さくなる方向に動く。
  • Using Policy Gradient in Practice

イントロ - Reinforcement Learning(強化学習)勉強メモ

Reinforcement Learning の勉強メモ。毎日追記していく予定。前提知識 Neural Network の基礎。back prop まで。

RL Course by David Silver - Lecture 2 - Markov Decision Process(強化学習)勉強メモ

YouTube
スライド + メモ

colab でプッシュ通知

colab で2-3時間の training を動かしているときにプッシュ通知があると便利。 training 終了や例外がでたときにスマホにプッシュ通知が来るようにできる。
https://www.pushbullet.com/ を設定・アプリインストール。API Key を発行。こんなに簡単にプッシュ通知が実現。API Key は秘密にすべきなので Google Drive におくのが良いでしょう。

!pip install pushbullet.py
from pushbullet import Pushbullet
pb = Pushbullet('api_key')
push = pb.push_note("This is the title", "This is the body")