sam_yusukeの日記

機械学習について書きます。

ローレベルなライブラリでdeepnet作って思い通りに動かなかったときの対処法

PyTorchなどの計算グラフからニューラルネットを作るライブラリを使ってプログラムを組んだ場合に、プログラムのバグなのかアルゴリズムのバグなのかを切り分けるためのテクニックを調べたものと最近使ったものでまとめます。

 

2018年年末現在画像分類、テキスト分類など枯れてきたものは品質の高いライブラリやAPIが利用可能であるだろうから、そういったものを利用する際は遭遇する問題の数は少ないと思われます。最新の論文の手法をゼロから実装した場合や成熟していないライブラリを利用する場合は何らかの事情で自分で1から実装しなければならない場合はデバッグのテクニックが重要になってきます。その際、理論的な理解や経験則が必要になってきます。重要なことは

  • 早く検証できる条件で検証すること
  • 他のパーツをできる限り単純なものにしてテストすること

です。

 

対象システムの全体像


f:id:sam_yusuke:20181216072948p:plain

本記事で対象としているのは、下の図のような現在よくある構造の機械学習システムです。評価結果が芳しくない場合、このすべてのコンポーネントが関わってきます。全体としてどういう評価が得られるのが妥当であるかは新しいモデルを新しいデータに適用している場合はっきりとはわかりません。できることとしては、個々のパーツのアルゴリズムとしての妥当性、プログラムが意図通りに動いていることを検証する必要があります。それぞれ、検証方法を考えます。

 

学習のパイプラインの検証

Optimizerデバッグ

このステップは単純です。損失関数、モデル、学習データのパイプラインを単なる一次微分可能な関数f(x)とみなして、最適化のステップが意図通りに行われていることを確認すれば良いです。それぞれのアルゴリズムのパラメータとその動作傾向について調べてください。また、このステップは少ない学習データ(10個程度)で、少ないエポック数(20程度)で試すと、早く終わります。

 

例えば、SGDであれば、学習率が大きすぎれば学習データの損失は局所解付近で振動します。学習率が小さければ学習データの損失はスムーズに下がっていきます。下のグラフのような感じです。

 

f:id:sam_yusuke:20181216072831p:plain

 

f:id:sam_yusuke:20181216072843p:plain

 

ここができるとOptimizerに最適化対象を正しく渡せていて、毎エポックの損失関数が正しく測定出来ていることをわりと強く確信できます。また、一通りの計算がエラーなく動くことがわかります。

 

モデルのデバッグ

これは難しいです。モデルによりますが、例えば、ConvolutionalNetworkなら、1つ目の畳込み層の重みを可視化することで、どのような特徴が取れているかイメージがわきます。明らかにノイズのようなものであれば学習がうまく行ってないと考えられます。

例えば、AlexNetで学習がうまく言っている場合、1層目の畳み込みそうは下記の図のようになります。

 

データ強化のデバッグ

データ強化の結果を出力して五感で確認しましょう。

 

損失関数のデバッグ+設計検証

ユニットテストやグラフを使ったデバッグをすればよいです

また、評価指標と損失関数が変数に対して同じように変化すること、
つまり、損失関数が評価関数の代理コスト関数として正しくなっていることを確認しましょう。損失関数はあくまで評価関数を最適化アルゴリズムの観点で効率の良いものに変えただけのものです。

 

評価パイプラインの検証

評価関数のデバッグ

ユニットテストを書けばいいでしょう。

 

全体的に

ユニットテストを活用しましょう。