実験管理

最近,自分がどのように学習ループを書いているか

tensorboard,便利です.

さて,最近はPyTorchが盛り上がっています.
公式のdistributions,uberが出したpyro,あとはどこかの研究者グループが出したprobtorchなど,TensorFlowにとってのEdwardのような立ち位置であるPPLが充実しつつあります.
先日一様分布からのノイズを変数に加える際にpyroを使いましたが,pytorchのVariableを用いてサンプリングを行える点が便利でした.here

pytorchは,発表当初はchainerのフォークがベースであると言われていたり,ゆくゆくはchainerにcontributeするという噂もありましたが,最近リリースされたv0.3ではTensorが全てC++のATenになるなど少しづつchainerから離れているような離れていないような状態です.

chainerの特徴は沢山ありますが,pytorchに明らかに勝っているものはtraining loop abstractionでしょう.
特に,updaterクラスとTrainerクラスという二段構成と,reporterモジュールによって(,training.extensionsを呼べば,)監視対象のロス管理・可視化を自動で行ってくれることだと思っています.

chainerでは,実装の複雑さにもよりますが,ロスをリストに追加したり,定期的にコンソールに出力したり,プロットしたりといった一つ一つは単純な処理ですが,意外とタイポなどでコケたり,コケるとダメージが大きい部分をフレームワーク側が処理してくれます.
一方pytorchですが,公式のtraining abstractionがありますが依然として論文の実装として公開されているものではほとんど使用されていませんし,mainファイルに処理をべた書きしているものも多いです.クラスはモデル定義とログフォーマット以外で使わないものも多いです.
「ロスの管理?出力すれば良くない?」という声が聞こえそうなものもそこそこ見かけます.

「でもどうせ出力するなら確実にどこかには残しておきたい」という気持ちが芽生え,そこから
「残すのであれば可視化」,「画像を使うなら特徴量ちぇっくしたい」と思うようになりました,芋づる式に.
そこで便利なのがtensorboardという話です.

で,最近はこうしている.

requirements

  • torch
  • torchvision and/or torchtext
  • tensorflow (tensorboardのため.CPU版で十分)
  • tensorboardX
  • slackweb(オプション)

構成

  • utils.py
  • models.py
  • trainer.py
  • train.py

という構成にしている.
Trainerクラスに学習周りを定義する.自分は__init__で設定ファイルを読み込んで,保存先ディレクトリの準備やlogger,writer(tensorboardの管理インスタンス)を渡し,train, testで各エポックのループを定義して,学習自体はrunメソッドにモデル,オプティマイザ,データローダを渡している.学習自体はクラスの初期化をしてからtrainer.run(model, optimizer, train_data, test_data)でOKという状態にしている.
train.pyではコマンド引数の管理とバリデーションをして,Trainerをよんで実行するだけにしている.
slackを使って監視したければ,trainerにクライアントを持たせておいて,スコアとかを一定間隔で送るようにできる.便利といえば便利だが,休日にも一定数通知が来るのは精神がアレ.
utils.pyにはスナップショットの保存・読み込みとか,tensor -> Variableとかの関数を書いている.
種類が少なければtrain.pyに流し込んでいる.

なんで

tensorboardを使うと,画像周りの管理が本当に楽になる,ロスも渡せば適当にプロットしてくれる.
もちろん,生成画像の学習によるエポック/イテレーション毎の変化をfaderで見れたり,画像-特徴量-ラベルの関係を2D/3Dで見ることができる.後者の機能は次元圧縮の計算方法をPCAとt-SNEから選べたり,ぐりぐり動かせたり,指定した特徴量の近傍探索もできる,優勝.

欠点は画像とかもtensorboardのファイルに内包されるために1つのtensorboardファイルが非常に大きくなること.今やっているFaderNetworkの実験は1GBを超えた.

おわり

使いやすければなんでも良いと思う