Chainerあれこれ

12月3日にChainerのNStepLSTMの使い方についてQiitaに投稿した。12月に入って今の研究テーマで進めていた手法が行き詰まったために系列ラベリングの手法を考えていたときだった。

BidirectionalなLSTMを使おうと思っていたのだが、これまでChainerのLSTMはサイズの合っていないデータをミニバッチで処理するときにあれやこれや処理が必要だった。改めて調べなおしてみるとNStepLSTMというものが1.16.0から導入されたようだった。NStepLSTMはミニバッチで処理するデータのサイズを合わせたりサイズの降順でソートしたりが不要になっただけでなく、cuDNNを使った実装になっていて動作が速くなっていた。それでまずはBLSTMをタスクに依存せずに汎用的に使えるよう実装してプロジェクトのコードに取り込んだ。速度も精度も良い感じだったので10月ごろに実装したLSTM+CRF for Chinese Word SegmentationをNStepLSTMを使ったBLSTMに差し替えて公開したいなと思った。

思い返せば夏休みはずっと機械学習の勉強をしていて9月ごろからようやくニューラルネットワークの勉強を始めた。いくつかのフレームワークでサンプルコードを写経してみて研究で使うフレームワークとしてChainerを選んでプロジェクトで使い始めたのは10月ごろかなあ。Chainerはネットワークを直感的で柔軟に使える反面で、ミニバッチを前提としたin/outは複雑なネットワークを組む際にはmatrixではなくtensorを考えないといけなくて煩わしい面もあった。ドキュメントがあまり充実していないので基本的にソースコードを読んでいた。速度が出ないときは自分でforwardとbackwardの演算を書いたりしてChainerの実装だけでなくニューラルネットワークに対しても理解が深まった。他に得られた知見としては演算以外のところはフレームワークに頼らないほうがいいということ。データのミニバッチ化や前処理やエポックの処理やテストや評価については自分で汎用的なコードを書いたほうがいい。実験において非本質的な部分であるのに内部の挙動を理解する必要があるAPIなんか、フレームワークごとに理解していたら時間がいくらあっても足りない。ChainerにおいてはTrainerやEvaluatorやDatasetはそれぞれが依存しすぎていて使いづらいし、サンプルコードで上がっているタスクでないといまいち使えないと感じた。自前で書いたほうがフレームワークを切り替えやすいという点も大きい。

閑話休題。ともかくChainerに詳しくなって良い点・悪い点が見えてきて個人的に気に入っているので、何かしらコミュニティに貢献できればと思った。そこで前出のNStepLSTMを使ったBLSTMを公開しようと12/2に思っていたところ、ちょうどQiitaでChainerのAdvent Calendarをやっており、しかも 12/3の枠が空いていて3日目にしてAdvent Calendarが途切れそうだったので勢いでやることにした。0時ごろから作業して、BLSTMの使用例としてCWSのアプリケーションコードを書いて、明け方にコードのリファクタリングまで終わって、朝から実験を回しながら記事を書いて昼前に投稿した。フレームワークに依存しないアプリケーションの汎用的処理や実験の処理についても、常々考えているところをサブモジュールとしてまとめることができたので個人的には満足。エンジニアとしては5年近くやっているのにQiitaに投稿するのはこれが初めてで、しかもそれが開発業務ではなく研究関連で投稿するとは思っても見なかった。

いまも現在進行系でChainerを使って先行研究の実装をしているので、できあがったコードはバンバン公開していこうと思う。

LINEで送る
Pocket

コメントを残す

*