機械学習の解釈性とパフォーマンスの両立を目指して:Human-in-the-Loop Interpretability Prior

機械学習、特にニューラルネットワークなどのアルゴリズムを使った場合、出力された結果は何万・何十万次元のベクトル演算の結果であり、人間が直接解釈することは難しい。ニューラルネットワークの解釈性については近年様々な研究が行われている。一般的に解釈性の低いモデルは高い精度を出すことが多く、適度な解釈性と適度な精度のバランスが取れたモデルが必要なケースが考えられる。

この論文「Human-in-the-Loop Interpretability Prior」は機械学習モデルに対して人間がある尺度(論文ではHIS:Human Interpretability Scoreという、人間がモデルに従って入力から出力を予測するのにかかった時間の逆数)を事前確率として、データXが与えられた際にそのデータを最も適切に説明できるモデルMをp(M|X)をMAP推定することにより選択するという手法を用いている。著者らは4種類のデータセットで実験を行っており、タスクごとにreasonableな解釈性を持ったモデルを選択できていることを確かめている。

読んだ感想としてはHISの決め方が果たして、人間がかかった時間の逆数という尺度を使うのは解釈性の尺度として適切なのか?といった疑問や、新しいモデルを作るたびにユーザの評価が必要になり汎用性は低そうに思った。HISを何らかの尺度(例えば計算時間や消費メモリ)によって算出することが出来れば、この手法を人の手を介さずに適用することも可能なのではないかと考える。

大規模データのクラスタリングには Mini Batch K-Means を使うべきという話

タイトルの通りですが、大規模データをクラスタリングする際には単純なK-Means法ではなく、Mini Batch K-Means法を使うべきという話です。

とある大規模データ(150万件ほどの文章ベクトル)をクラスタリングしたいことがあったのですが、単純にScikit-learnのK-Means法に投げてクラスタリングを走らせていたところ、数時間経っても一向に終わる気配がありませんでした。色々と調べていると、大規模データのクラスタリングにはMini Batch K-Means法を使うべきという記述を見つけました。公式ドキュメントによると、大体1万件を超えるデータをクラスタリングする場合にはMini Batch K-Meansを使うべきとのことです。

APIとしては単純にKMeansをMiniBatchKMeansに置き換えれば動きます。理論的な背景としては、論文 “Web Scale K-Means clustering” D. Sculley, Proceedings of the 19th international conference on World wide web (2010)に書かれており、ざっと読んだところランダムサンプリングしてクラスタの中心を計算していくのですが、KMeansとは異なり、各点ごとに中心を逐次的にアップデートしていくことで計算量を減らしています。

論文に載っていた速度比較ですが、圧倒的にMiniBatchKMeansが高速です。図の青がMiniBatchKMeans、赤がKMeans、横軸が時間。

この手法を使ったところ、KMeansでは数時間経っても終わらなかったクラスタリングが、MiniBatchKMeansでは数分程度で終わりました。ということで、大規模データのクラスタリングにはMIniBatchKMeansを使うべきということを学んだという話でした。

RNNのDropoutはどこに入れるべきか?:Where to Apply Dropout in Recurrent Neural Networks for Handwriting Recognition?

タイトルの通り、RNNに対してDropout層を追加する場合、どこに入れるのが適切なのか?と思い少し調べてみました。

ことの発端は、KerasにあるLSTMとGRUの、GPUによる高速化版であるCuDNNLSTMとCuDNNGRUには、dropoutとrecurrent_dropoutというCPU版には存在するパラメータが無いため、これらの層の前後にDropoutを入れても効果あるのかな?と疑問に思ったことが始まりです。

以下のKerasのgithubでこれらのパラメータについての議論が行われており、作者のChollet氏は以下のように述べており、通常のDropoutはRNNに対して効果が無いように読み取れます。https://github.com/keras-team/keras/issues/8935

Recurrent dropout is not implemented in cuDNN RNN ops. At the cuDNN level. So we can’t have it in Keras.

The dropout option in the cuDNN API is not recurrent dropout (unlike what is in Keras), so it is basically useless (regular dropout doesn’t work with RNNs).

Actually using such dropout in a stacked RNN will wreck training.

その後、少し調べてみるとタイトルにある論文「Where to Apply Dropout in Recurrent Neural Networks for Handwriting Recognition?」を見つけたので読んでみました。この論文では、手書き文字認識タスクにRNNを使用して、DropoutをRNNの前、中、後に入れてみて汎化性能を試しています。何種類かのデータセットで実験を行っていますが、結果はまちまちで、傾向としてはRNNの前にDropoutを使うのが性能が良いことが多いが、中、後に入れる場合も性能が良くなることがあり何とも言えない感じの結論となっています。ただ、著者らは複数層のRNNモデルに対しても実験を行っており、その場合にはネットワークの最初と最後にDropoutを入れるのが良い性能の傾向があると結論付けています。

はっきりとした結論は言えそうも無く、結局はタスクによるんじゃないかという感じですが、この辺はやはりディープラーニングはハイパーパラメータチューニング職人の世界であるといわれる一因なんじゃないかと感じました。

 

Kerasの作者が書いたDeep Learning解説本:「Deep Learning with Python」を読んだ

タイトルの通り、広く使われているディープラーニングフレームワークであるKerasの作者François Chollet氏によるDeep Learningを解説した本「Deep Learning with Python」を読みました。今月末には日本語版が出るのでその前に読み終えることが出来て良かった。かなり分かりやすく、今まで何となく知っていた知識の整理に役だったのでオススメです。英語版を読んだので日本語版の翻訳が良いのか分からないですが、コードや図表が多いので日本語版でも理解は容易だと推測します。ちなみに英語版はUSのAmazonでかなりの高評価を受けています。


この本の特徴は、すべてのコードがKerasを用いて書かれており、コードが簡潔で理解しやすいという点だと思います。そして、本書を通じて(多分)一度も数式が登場していないので初学者にはとても読みやすいと思います(ただ、文章で説明するよりも数式なら一発で分かることというのもあるので、この点はレベルによります)。例えば、多層ニューラルネットが何をしているのかといった説明に、くしゃくしゃに丸めた紙を一層毎に開いていくイメージに似ている、といった説明がされており、初めて学ぶ人にとっては理解しやすいかと感じました。

カバーされている内容は、基本的なFully Connected Layerを用いたDNNから、畳み込み層を用いたCNN、RNNによる時系列データの取り扱い、GANやVAEなどによる画像生成などこの一冊でかなり広い分野をカバーできるようになっています。目を引いたのはCNNを用いた分類器の判断根拠を示す可視化手法(中間層の活性化状況やGrad-GAMといったヒートマップを用いた可視化)を書かれており内容が充実しています。その他にもRNNモデルの解説でLSTMやGRUが内部で何をしているかなどには、深く立ち入らず概念だけ説明して、Kerasを使えばこれだけでできるよ、と書かれているところも研究者よりは実践者向けだと感じました。

その他には、最後の章に著者が考えるディープラーニングの限界や、ディープラーニング技術の将来予測が書かれており興味深かったです。また、「この本を読み終わった後に進歩の速いディープラーニング分野の勉強を続けるにはどうしたらいいか」という内容が最後に書かれており、そこには「Kaggleをやれ、arXivで論文を読め」と書かれているのでその辺りを頑張って行きたいと思います。

恐らく、機械学習を学び始めて「ゼロから学ぶディープラーニング」を読み終えた人が、ディープラーニングを使って何か自分で試してみたいと思った時に、Kerasを学んで簡単にモデルを構築できるようになるためのステップとして最適な本だと思いました。

CNNによる価格予測の論文:「The Price is Right: Predicting Prices with Product Images」を読んだ

タイトルの通り、CNNモデルを利用して、自動車・自転車の画像から価格を予測する論文、「The Price is Right: Predicting Prices with Product Images」を読んだ。

この論文を読んだ動機は、ネットを調べるとCNNを用いて画像を分類するという例は山ほど出てくるが、CNNを用いて画像から何らかの数値を出力するregression問題に取り組んだ例があまり見つからず、ちょっとそういったことをやる必要に迫られたので読んでみた。

自転車と自動車の画像からそれぞれの価格を推定するregressionタスクにCNNを用いた。ベースラインモデルである多クラスSVMと線形モデルに対して同等~高い精度が出た。VGGとMobileNetによる転移学習よりも精度の高いネットワーク構造PriceNetReg CNNを提案している。また、CNNモデルに関して、画像のどの部分が予測に効いているかをVisualizationすることにより示している。

CNNモデルが画像のどの部分に着目して判断を行っているかということをVisualizationしているのが面白い。次はこういった可視化技術の論文を読んでみたい。

まとめスライドはこちら。

The Price is Right Predicting Prices with Product Images_slide

CNNによるセグメンテーション論文:「U-Net Convolutional Networks for Biomedical Image Segmentation」を読んだ

タイトルの通り、CNNを用いて医療画像をセグメンテーションするU-Netというネットワーク構造の論文を読んだ。

2015年に発表されたネットワーク構造だが、その後セグメンテーションでは古典的な内容になっており、いくつか発展形のネットワークも提案されている。

論文のまとめは以下。

U-Net Convolutional Networks for Biomedical Image Segmentation_Slide

Pythonでデータ整形まわりをまとめた本:「Python for Data Analysis (第2版)」を読んだ

最近、Pythonを使って機械学習を勉強しているがnumpyやpandas, グラフ作成辺りの体系的な知識が足りない気がしていたので、この辺りをまとめた本「Python for Data Analysis (第2版)」を読んだ。感想としてはもっと早くに読んでおくべきだったと思う。今まで何となく書いていたnumpyやpandasが割と頭の中で整理できたと思う。

日本語版は第1版の翻訳が出ているようだ。Amazonのレビューを見ると第1版はPython2系列で書かれており、今読むとしたら内容が古いのでオススメはしない。第2版ではPython3で書かれている。

以下に学んだことをピックアップしておく。

  • IPythonでは変数の後に「?」をつけると変数の情報が見れる
  • リストに要素を逐次的に追加していく場合、extendメソッドを使った方が要素を結合するよりも速い
  • arr2d[0][2]とarr2d[0,2]は同じ意味。
  • ffillメソッドで前方向のinterpolationができる
  • 大きなCSVファイルをpandasで読み込む際には、read_csv()にchunksizeを指定して処理していく
  • データ分析において前処理にかかる時間は全体の80%くらいという報告がある
  • Jupyter notebookではplotの設定がセル毎なので複雑なプロットは一つのセルにコマンドをまとめて書く必要がある
  • plot.kde()でカーネル密度推定をグラフにプロットすることが出来る
  • pandasのrolling()メソッドを使うことで、Moving Window Averageが取れる
  • 時系列データ分析では、exponentially weighted functionsが最近のデータに大きい重みをつける手法としてよく使われる
  • 特定の値しかとらないデータカラムはcategory型にすると使用するメモリが減って、機械学習の処理の高速化を見込める
  • DataFrameをNumPy配列に変換するにはdata.values
  • Pythonの関数を高速化する手法としてnumbaがある。numba.jit()を使うことで関数をJITコンパイルできる

最後の章に、この本よりもさらに学ぶのにオススメの本が挙げられている。「Hands-On Machine Learning with Scikit-Learn and TensorFlow」は読んだことがあるが、とても分かりやすく、特にこの本でnumpyやpandasを学んでからならすんなりと機械学習の手法を理解することが出来ると思う。読んだ際の感想はこちら。Hands-On Machine Learning with Scikit-Learn and TensorFlow: Concepts, Tools, and Techniques to Build Intelligent Systems を読んだ

紹介されている次に読むべきオススメの本:





ビルゲイツの新しい最も好きな本: 「Enlightenment Now」

ビルゲイツが自身のブログで新しい最も好きな本としてSteven Pinkerの「Enlightenment Now」であると発表しました。

My new favorite book of all time

今までビルゲイツはSteven Pinkerの「The Better Angels of Our Nature」(邦題「暴力の人類史」上下,青土社)を最高の本だと言っていた。


Steven Pinkerの新たな本「Enlightenment Now」が新たな最も好きな本であると、ビルゲイツは述べている。まだ出版されていないが、ビルゲイツのブログから登録することで無料の章を読むことが出来る。

「Enlightenment Now」では、どのようにして人類・世界が良い方向へと進んでいっているのかを述べている本であるそうだ。ビルゲイツ自身が気に入った5つの世界が進歩している理由を以下のように述べている。

1. You’re 37 times less likely to be killed by a bolt of lightning than you were at the turn of the century.

2. Time spent doing laundry fell from 11.5 hours a week in 1920 to an hour and a half in 2014.

3. You’re way less likely to die on the job.

4. The global average IQ score is rising by about 3 IQ points every decade.

5. War is illegal.

要するに、今は昔に比べてはるかに安全であり、家事に使う時間ははるかに減っており、世界の平均IQも上がってきている。歴史の本をよく読んでいるビルゲイツのオススメ本なので読んでみたいと思う。

Kaggleで人気 XGBoostの論文 「XGBoost: A Scalable Tree Boosting System」を読んだ

タイトルの通りなんですが、Kaggleでとても人気のある手法のXGBoostがどういった仕組みで動いているのかを知るために次の論文を読みました。

XGBoost: A Scalable Tree Boosting System

詳しいことは、日本語で読める分かりやすい解説記事(こことか)があるのでそちらを参照していただきたいです。この記事は個人的な備忘録です。

要するにXGBoostとは決定木をすでに作った木の情報をもとにしながら何個も作ってそれらの結果を足し合わせることで、性能を向上させるBoostingの手法を効率的に実装したものと言えます。

基本的なポイントは単純ですが、決定木を作っていくうえですべての木の中から最も良いものを調べて選択するのは計算量的に難しいため、ある種の近似を用いて精度的に問題の少ない気を作っていき高速に実行可能なアルゴリズムとなっています。また、オーバーフィッティングを防ぐために、サブサンプリングや縮退化などの仕組みも導入されており、汎化性能が良くなるようになっていることもKaggleのコンテストで人気の理由の一つだと思います。

また、論文では並列化や分散処理をした場合の速度性能の評価が行われており、高い並列性能が出ています。提供されているライブラリではキャッシュが当たりやすくなるようになどの最適化が施されているので、自分で実装せずにライブラリを使いましょう。pipで簡単に入れられるようです。