「MXNet/Gluon」開発チームによる「ハンズオン」に参加して時系列予測について勉強してきたのでまとめる

「MXNet/Gluon」のハンズオンに参加してきました!3日目は「時系列予測」についてです。 MXNetのエコシステムについても浅く広く教えてもらいました。
2018.12.21

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

2018年12月17日(月)~19日(水)にAWSJ主催で実施された「MXNet/Gluon」のハンズオン に参加してきましたので、まとめレポートを書こうと思います。
本エントリーは12月19日(水)のハンズオンのまとめレポートです。
この日は「時系列予測」についてのハンズオンでした。

MXNet、時系列予測については今まで殆どやったことが無かったので、「MXNetのエコシステム」や「時系列予測に用いられるアルゴリズム」についての解説を受けることができて、凄くためになりました。
当日の報告内容をまとめましたので、MXNetや時系列予測に興味がある方は是非ご覧ください。

当日の報告資料は取得次第添付しようと思います。
当日の報告資料はこちらです。(2018年12月27日に追記しました)
MXNet_Gluon_Workshop_Day3

目次

1.報告内容

当日の報告内容は下記の4点でした。それぞれの概要をまとめます。

  • DeepARの理論とハンズオン
  • MXNetのエコシステム
  • LSTMの理論とハンズオン
  • LSTNetの理論とハンズオン

2.DeepARの理論とハンズオン

3日目は「DeepARの理論紹介とハンズオン」から始まりました。

2-1.DeepARの理論について

まずは、「DeepAR」の理論についての説明です。
「DeepAR」はSageMakerで用意されている「時系列予測のためのビルトインアルゴリズム」です。
アルゴリズムの詳細については「paper」を、実際にやってみるとどんなことができるのか、といったイメージについてはこちらをご参照いただきたいのですが、下記から当日のハンズオンでの解説内容について紹介します。

「DeepAR」は「LSTMを使ったRNN」と「モンテカルロシミュレーション」を利用したアルゴリズムです。

予測したいタイムステップにおける「条件付き確率分布」をOUTPUTとして出力します。
この確率分布は「尤度を最大化」することで求められるのですが、この尤度を計算する際のパラメータをRNNで計算しています。

分布はハイパーパラメータとして色々選べますが、デフォルトだとガウス分布が選択されます。例えばガウス分布を使う場合は、「平均」と「分散」がパラメータとなるので、これらをRNNで学習することとなります。
この分布はデータの特性に合わせて選択する必要があるので、ご注意ください。

学習時には「RNNの出力をINPUT(下記でのh,z)とした対数尤度」を最大化するように学習し、計算結果を次のステップでの計算に利用します。予測する際は「モンテカルロシミュレーション」で「次のステップ」の確率分布を計算し、次のステップでの推論に利用します。

論文では下記のように表現されています。左側がモデルの学習時で、右側が推論時です。
引用Fig.2

モンテカルロシミュレーションなので、「解析的」に計算しているわけではなく尤度関数の計算式を「近似」していることになるのですが、回数を重ねれば重ねるだけ、よりそれらしい確率分布を予測することができます。

「DeepAR」の理論の説明は以上で、続いてハンズオンに移りました。
ハンズオンではqwikLABSを使いました。
また、実際に使ったノートブックファイルについてはこちらをご参照ください。
「qwikLABS」についてはAWS Cloud Roadshowでオンラインハンズオン- qwikLAB -をやってみた #AWSRoadshowをご参照ください。

ハンズオンでは「電力の需用量予測」をし、下記のようなOUTPUTを得ました。
黒い線が正解の値、青い線が予測値、青い背景部が信頼区間です。
この信頼区間の幅も推論時に指定できるので、柔軟に値を指定できます。
このようにDeepARでは「指定したタイムステップにおける目的変数はこの値です!」ときっちり予測するのではなく、「確率分布として出力」してくれるので、より使い勝手がいいものです。

推論の形式についてはこちらをご参照ください。

3.MXNetのエコシステム

続いて、MXNetのエコシステムについての報告です。

MXNetは色々な言語から扱うことができます。
また、裏ではC++で動くので処理も高速です。

MXNetを支えるエコシステムには色々なモジュールがあります。
それぞれの概要を見てみましょう。

Model Server

「Model Server」の役割は、学習結果のモデルを様々な環境にデプロイ(実態としては、コンテナ上にモデルを展開)することです。
「Amazon ECS」上でもモデルサーバを稼働させることが可能です。

一度学習したモデルをデプロイするまでには、下記のように考慮すべき事項が多々存在するのですが、「Model Server」ではそのような各事項を殆ど意識しなくてもいいような機能が提供されています。

ONNX

「ONNX」「異なる機械学習のフレームワーク間で、モデルをコンバート」することができます。
あまり機会は多くないかもしれませんが、例えばモデルの学習にPytorchを使い、推論時はMXNetを使いたい場合等に「ONNX」を使うことができます。

例えば、Pytorchで学習したモデルのパラメータを出力する際は、下記のようにシンプルな記述で出力できます。
(「onnx」という拡張子のファイルで出力されます)

そして、MXNetで上記のモデルを利用する場合は、下記のように記述します。
シンプルですね。

上記まではPytorchとMXNetでご紹介しましたが、当然それ以外にも様々なフレームワークに対応しています。

TVM

TVMの役割は「異なるアーキテクチャに合わせてモデルをコンバート」することです。
TVMでモデルをコンバートすることで、「推論時間の短縮」が図れます。

例えば下記の図の右側はラズパイ上での推論処理時間を計測したもので、緑色がTVMを使ってコンバートした方なのですが、圧倒的に処理時間が短くなっていることがわかるかと思います。

TensorRT

モデルを最適化することで、推論処理時間を短くするために利用されるライブラリです。
下記は様々な環境・モデルに対してTensorRTでコンパイルした際の推論処理時間を計測した結果ですが、推論処理の短縮が確認できます。

Keras-MXNet

続いて、KerasとMXNetの連携についてです。
通常、Kerasを利用する際はバックエンドとしてTensorFlow,Theano,CNTKのいずれかを利用していることかと思います。
「Keras-MXNet」では、バックエンドで稼働しているフレームワークとしてMXNetを指定できます。

こちらはTensorFlowをバックエンドとして利用した際とのベンチマークテストの比較です。
GPUが1つの時は殆ど差が無いのですが、GPU数が増えるにつれて差が大きくなっています。
複数のGPUを使って並列処理をする際は、バックエンドとしてMXNetを使った方が処理が効率的にできそうです。

もし気になる方がいらっしゃったら下記のコマンドでインストールして試してみてください。
Kerasの書き方は特に変わらないので、従来からKerasを利用していた方なら特に違和感なく使うことができるかと思います。
pip install keras-mxnet

GluonNLP

GluonNLPは、その名の通り「Gluonで自然言語タスクを実施するためのライブラリ」です。

既に「Model Zoo」にも様々なモデルが用意されているので、特にカスタマイズが不要ならすぐに試すことができます。

MXBoard

続いては、「MXBoard」の紹介です。これは一言で言うと「MXNet版TensorBoard」です。
やはりこういう学習の過程を可視化できるGUIツールの有無は、フレームワーク選定においては個人的に重視しているので嬉しいところですね。

コミュニティ

MXNetの最新情報にキャッチアップする方法についても紹介されました。
下記に色々と情報を発信している媒体を記述しますが、最新情報の概要を把握する、くらいでいいのなら「とりあえずTwitterをフォローする」くらいから始めるといいかもしれません。

Twitter
Youtube
medium
reddit

また、どうしてもわからないことがあった場合は、こちらで質問もできます。

4.LSTMの理論とハンズオン

続いて、RNNの学習でよく用いられる「LSTM」の説明とハンズオンに移りました。
「LSTM」の説明の前に、まず「LSTM」が提唱されるに至った背景についての解説から始まりました。

4-1.LSTMの理論について

突然ですが、下記の文章の最後の単語を予測する時、どこに着目するでしょうか?
このような文章では「最初の単語(He,She)」に着目しないと、最後の単語を正確に予測することはできません。
つまり、「過去の情報をある程度の期間記憶しておく」必要があります。

上記のような、「過去の情報をある程度の期間記憶しておく」必要がある場合に、「RNN(Recurrent Neural Network)」は良く使われます。 例えば下記の例でいうと、「次にどんな単語がくるのか」を予測する場合に「過去にどのような単語が出てきたのか」という情報を保持しておいて、利用しています。

一見、「RNN」は過去の情報をよく学習できるように見えますが、実際には「勾配消失」という「ネットワークが大きくなると学習がうまくいかなくなる」問題がありました。
そこで、「LSTM」という「長期的な依存関係を学習するための」構造が考えられました。
下記の例では「CEC」セルというメインの情報を保持するセルと、セルを制御する3つのゲート(「FORGET GATE」、「INPUT GATE」、「OUTPUT GATE」)からなります。
ネットワークが大きくなっても勾配情報を伝えられるようにCECセルが情報を保持しつつ、3つのゲートがこのCECセル内の情報を「どの程度忘れさせるか」、「計算結果をどの程度使うか」、「どういった情報を出力するか」といった制御をします。
(LSTMにも色々なバージョンがありますのでご注意ください)

4-2.LSTMのハンズオン

LSTMの解説は以上で終わり、続いてハンズオンに移りました。
ハンズオンでは下記の2ファイルを使い、解説を交えながらのハンズオンとなりました。
解説用
code

まず、一番シンプルなRNNの構造について復習しました。
下の部分のように「過去の計算結果&今回のデータ」を使って計算していることがわかるかと思います。

また、CNN同様に複数の層を重ねることが可能です。
これで階層的に特徴を抽出できるので、単層のネットワークよりも複雑な学習ができるようになります。

「過去の情報を使う」だけでなく、「未来の情報」も使うことができます。
例えば下記の文の例であるように、「I arrived at the ○○ after crossing the river.」といった文章中の「○○」の部分に入る単語を予測する際は、「○○」以降の文脈を理解できると有用なことが直感的にわかるかと思います。

続いて、先ほど学習した「LSTM」です。
下部が先ほど解説したものの詳細なのですが、左から「FORGET GATE」、「INPUT GATE」、「OUTPUT GATE」です。

最後に、ここまでの全てを利用した「Stacked Bi-directional LSTMs」構成の紹介がありました。
この構成の場合はどうしてもネットワークが大きくなってしまうので、記述するのも学習するのも大変そうです。

5.LSTNetの理論とハンズオン

最後に「LSTNet(Long- and Short-term Time-series network)」というアルゴリズムの理論紹介とハンズオンがありました。
本アルゴリズムの詳細についてはarxivをご参照ください。

5-1.LSTNetの理論

「LSTNet」は「畳み込み層」、「RNN」、「多変量自己回帰」を使った時系列予測で、2017年に提案されました。

ネットワークの構成図
引用:Figure 2

ざっくりと処理の流れを書くと、下記の通りです。
1.畳み込み層の出力結果を、RNNのINPUTとする。
2.RNNは2つのネットワーク(両方とも「GRU」ベース)を用意する。片方にはスキップ構造を取り入れる。
3.2つのRNNの出力を全結合層でまとめる
4.「3」の出力結果と、多変量自己回帰モデルの出力結果を、足し合わせたものを最終出力とする。

GRU:LSTMの「FORGET GATE」、「INPUT GATE」を統合して「UPDATE GATE」としたものです。概念や役割はLSTMとほぼ同じです。
スキップ構造:指定したスキップ数前のCECセルの値を利用する。

本ネットワークのコンセプトは下記の通りです。

  • 「畳み込み層」で短期的トレンドを取得し、「RNN」で長期的なトレンドを取得します。
  • 「データのスケールの急激な変動に対して頑健なモデルにする」ために、自己回帰は良い結果をもたらしている、と論文中では考察されています。
    (論文中の「4.6 Ablation Study」を参照)

    5-2.LSTNetのハンズオン

    LSTNetの解説については以上で終了し、続いてハンズオンに移りました。
    ハンズオンでは、時系列予測における評価指標として「RSE(Root Relative Squared Error)」、「CORR(Correlation Coefficient)」の2つともを観察することの重要性について解説がありました。
    「RSE」は真の関数と予測した関数の誤差を、「CORR」は「相関」なので真の関数と予測した関数の傾向がどれだけ似ているか、をそれぞれ計測しています。
    (RSEは小さい方が、CORRは大きい方が好ましいです)

    例えば、青色の関数(y = sin)が真の関数だとして、この関数を予測するために、オレンジ色(y = sin-5)、緑色(y = 0)の関数を予測したので評価しようとしているとします。
    これらの関数はいずれもあまり真の関数に近いとは言えないのですが、「RSE」,「CORR」の片方だけで評価してしまうと、誤って「良い関数」だと判断してしまうかもしれません。
    オレンジ色の関数(sin - 5):RSEは大、CORRも大
    緑色の関数(y = 0): RSEは小、CORRも小

    このような事象を避けるためにも、時系列のモデリング時には、「RSE」、「CORR」の両方を使ってモデルを評価しないといけない、とのことでした。

    下記はハンズオンで実際に利用したわけでは無いのですが、もし「LSTNet」を動かしてみたいという方がいたら参考になるかもしれません。
    SageMakerでLSTNetを学習する
    複数のGPUで並列でLSTNetを学習させる
    Pytorchでの実装

    6.まとめ

    以上で、3日目のトレーニングの紹介を終わります。
    3日目は時系列予測についてのトレーニングでしたが、DeepAR、LSTNet等の論文を読むいい機会になったので、個人的にはとても楽しかったです。
    また、MXNetには興味があったものの、周辺知識が無かったのでエコシステムについて知ることができたので、効率よく勉強を進めることができそうです。

    MXNetを使おうとしているどなたかの参考になれば幸いです。