機械学習/ディープラーニング初心者が2018年にやったこと、読んだ論文

2018年もいよいよ本日が最後となりました。皆さんいかがお過ごしでしょうか。この記事では機械学習/ディープラーニング初心者だった自分が2018年にやったことをまとめていきたいと思います。ポエムじみた記事になってしまいましたが、何らかの参考になれば幸いです。

## 2018年のBefore-After
### Before
* 今年（4月）ぐらいまで機械学習の「き」の字も知らなかった。k-Nearest Neighbor？Support Vector Machine？なにそれ美味しいのってレベル
* 昔統計をやっていたので、ロジスティクス回帰ぐらいは知っていた。オーバーフィッティングの概念ぐらいは知っていたが、厳密な定義は知らなかった。
* Pythonも触ったことなかった

![diet_before_after_s.jpg](https://qiita-image-store.s3.amazonaws.com/0/232088/9496b69e-3547-0eed-3d1b-5429125883c7.jpeg)

### After
* 機械学習とディープラーニングの基礎はだいたいわかった
* Pythonがだいたい使いこなせるようになった
* 物によってはディープラーニングの最新の研究でも、論文読んで実装できるぐらいになった
* Kaggleができるようになった
* Computer Visionにかなり強くなった
* Kerasが使いこなせるようになった。PyTorchもわかるようになった
* TPUが使えるようになった
* 機械学習の勉強した内容Qiitaに上げてたら、1年間で2000Contribution行った

Before-Afterだけ見れば「嘘やろ？」ってレベルですが全部本当です。嘘だと思う方は自分の過去の記事見てください。初心者のポエムが見れます。

以下やったことを書いていきます。

## 1. Ian Gooodfellow『深層学習』
![](https://images-na.ssl-images-amazon.com/images/I/91gaPzP0EmL.jpg)

[Amazonより](https://www.amazon.co.jp/%E6%B7%B1%E5%B1%A4%E5%AD%A6%E7%BF%92-Ian-Goodfellow/dp/4048930621)。GAN（Generative Adversarial Network）の生みの親であるIan Goodfellow先生の著書。去年ぐらいに東大の松尾研で和訳のプレビュー版を公開していたので、それを読んでみました。後述のCoursera Machine Learningをやる前でした。

ある程度のとこ（Back Propagationのあたりまで）は読めましたが、それ以降はなにやっているのかよくわからなくなって挫折しました。今読み返すと「ああ、そういうことだったんだ」とわかりましたが、個人的には初心者には難しすぎるのではないかなと思います。用語がいろいろ出ていてきちんと説明しているものの、全体の見通しが効かなくなってパンクしました。ある程度わかっている人が読むと参考になると思います。

機械学習初心者に[PRML](https://www.amazon.co.jp/%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3%E8%AA%8D%E8%AD%98%E3%81%A8%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92-%E4%B8%8A-C-M-%E3%83%93%E3%82%B7%E3%83%A7%E3%83%83%E3%83%97/dp/4621061224)を勧めるよりはひどくはないものの、似たような感じがするので、はじめにこれ読んで「わけわかんねぇ」と思っても多分正常です。むしろこれ最初に読んで理解できた方はすごいです。

## 2. Coursera Machine Learning
![ml_01.png](https://qiita-image-store.s3.amazonaws.com/0/232088/ed94bc51-295e-ec24-800b-1e830fdba705.png)
[What is Machine Learning?](https://ja.coursera.org/lecture/machine-learning/what-is-machine-learning-Ujm7v)より。機械学習の第一人者であるスタンフォード大学のAndrew Ng先生がやっているオンライン講座。4月～5月ぐらいにやりました。これは**めちゃくちゃ参考になりました**。修了証が必要なら課金するパターンで、課題も講義も無料で受けられます。音声は英語ですが有志が作った日本語字幕が公式で見れます。各講義の後にあるミニテストは英語ですが、Google翻訳使ってがんばりましょう。

ただこの動画は若干古くなっていて、「なにか機械学習をやるときにNumpyよりもOctaveを使ったほうが結果的に時間短縮できるよ」って言っているのは、現在は嘘なので注意してください。今ではNumpyが相当使いやすくなっているので、このときのOctaveとほぼ同じ感覚で使えます。ただNumpyとOctaveでは挙動が微妙に違うので、PythonでやるのならNumpyベースからやるのが一番速いです。自分も複雑なテンソル操作のときにNumpyでよく確認します。課題がOctaveですがまあそこは我慢しましょう。自分はこれ以来Octaveは使っていません。

ロジスティック回帰から始まり、ニューラルネットワーク、Bias vs Variance、サポートベクターマシン、クラスタリング、主成分分析、協調フィルタリングなどを抑えています。動画は古いですがどれも今でも十分使えるアルゴリズムで、PythonならScikit-learnでほとんどカバーされている内容です。特に「**Bias vs Variance**」はディープラーニングやKaggleでも普遍的に使える内容なので、やるのならここは重点的に抑えておいたほうがいいと思います。多分自分が知っている中で一番丁寧に解説しています。主成分分析は内容の割に若干駆け足なので、よくわからないかもしれません（自分もちゃんと理解したのは半年ぐらい後なのでそれでいいと思います）。

ニューラルネットワークは2回にわけて丁寧に解説していますが、ロジスティック回帰の後に出てきてここが難しいという声が多いので、がんばってついていってください。逆にここ乗り越えられたら完走できると思います。

## 3. Coursera Deep Learning(deeplearning.ai)
![ml_02.png](https://qiita-image-store.s3.amazonaws.com/0/232088/197e8419-1d6f-1fe8-6efa-d6d11253aae2.png)

[Deeplearning.ai](https://www.deeplearning.ai/)より。Machine Learningと同じくAndrew Ng先生による丁寧な解説。あくまで自分の意見ですが、**ディープラーニングの基礎覚えたいならここ一択**だと思います。この講座については[こちらの記事](https://qiita.com/koshian2/items/116ebd6ae5dcb73e655c)で書いたのでよろしければどうぞ。最近見返したら相当日本語字幕が整備されていました。ありがたいことです。

この講座は難しい式を使わないで理論的な説明をしっかりしているので、「オープンソースの実装をやったらできました」以上の理解ができます。なぜこれが大事かというと、ディープラーニング、もとい機械学習はアルゴリズム1個できればそれで完成というわけではなくて、複数のアイディアや要素を組み合わせて適用していくというケースがよくあるからです。Kaggleを見ているとそれはよくわかります。

例えばゲームのモンハンなんかで考えるとわかりやすいのではないでしょうか。閃光玉投げればモンスターを倒せるというわけではなく、閃光玉投げてそのすきに殴る、しかし閃光玉が効かないモンスターみたいなのもいますよね。ディープラーニングの個々のアルゴリズムは閃光玉のように強力なものも多くあります。しかし、実際の問題に適用するにはこれらの組み合わせが大事になるからです。

それを裏付けるように、ディープラーニングのアルゴリズム自体が画像認識から自然言語処理に応用されたり、あるいは逆だったり、ドメイン間の転用が頻繁に行われています。例えば、今年自然言語処理で出た革新的手法である『[BERT](https://qiita.com/Kosuke-Szk/items/4b74b5cce84f423b7125)』は、画像認識で強力な手法であった転移学習を、自然言語処理のドメインに転用するというのが大きなキモになっています。BERT自体は講義で触れられていませんが、ドメイン間の転用については、講義の中で何度も述べられています。

実際は「BERTみたいなドメイン間の転用をしろ」とまではいかなくても、アルゴリズムでの組み合わせ上での転用をするということはそれとなく意識することはあります。例えば、二値分類の損失関数であるbinary_crossentropyが、画像の生成に使われたりするのです。画像の生成の発想が、物体認識であるSemantic Segmentationに応用されたりします。つまり、同じ画像認識というドメイン内でもアイディアの転用というのが日常的に行われています。それをするには「やったらできた」だけではなくて、もっと本質の部分から理解する必要があるのではないでしょうか。その点では**この講義は非常に有用です**。実際、自分が書いていた記事はこの講義から「あれ、ここやったらどうなるんだろう？」というのが多いです。

## 4.その他読んだ論文
軽くグーグル検索感覚で読んだものから、じっくり読んだものまであって正直何読んだか忘れてしまいましたが、多分読んだと思うものをリストアップしておきます。

* Kaiming He, Xiangyu Zhang, Shaoqing Ren, Jian Sun. *Deep Residual Learning for Image Recognition*. 2015. https://arxiv.org/abs/1512.03385
言わずとしれたResNetの論文。ResNet自体はKerasやPyTorchで割と簡単に作れるので試しにサイズを変えて作ってみると面白いと思う。

* Gao Huang, Zhuang Liu, Laurens van der Maaten, Kilian Q. Weinberger. *Densely Connected Convolutional Networks*. 2016. https://arxiv.org/abs/1608.06993
CVPR 2017でBest Paper Awardを受賞したDenseNetの論文。「知識の累積」というものに着目して、層を積み重ねてブロック同士を大量のSkipConnectionでつなげていくのが面白い。

* Christian Szegedy, Wei Liu, Yangqing Jia, Pierre Sermanet, Scott Reed, Dragomir Anguelov, Dumitru Erhan, Vincent Vanhoucke, Andrew Rabinovich. *Going Deeper with Convolutions*. 2014. https://arxiv.org/abs/1409.4842
Inception Networkの論文。Inceptionブロックの構成や、1x1畳み込みによるチャンネル圧縮の構成や理由付けが知りたくて読んだ。極端な話、計算リソースの暴力で全部試したらうまく行ったの話だった。ただGoogleが新しく出した強化学習のアプローチのNASNetは、もっと大量の計算リソースで殴っているのでそういうスタンスかも。

* Barret Zoph, Vijay Vasudevan, Jonathon Shlens, Quoc V. Le. *Learning Transferable Architectures for Scalable Image Recognition*. 2017. https://arxiv.org/abs/1707.07012
Googleが本気出して強化学習で作ったNASNetの論文。ColabのTPU環境で再現しようとしたらあまりに深すぎてコンパイル失敗した唯一のネットワーク。Googleが作った最強のネットワークを、Googleが作った最強のチップで使ったらどうかという現代の矛盾案件。構成が深すぎて笑っちゃうから一度眺めてみても面白いかもしれない。

* Sergey Zagoruyko, Nikos Komodakis. *Wide Residual Networks*. 2016. https://arxiv.org/abs/1605.07146
地味に人気がある（気がする）WideResNetの論文。ResNetが深さを取るなら、こっちは幅を大きくして深さを小さくしたネットワーク。構成がわかりやすくて、かつ簡単に精度が出て強力なのが人気の秘訣かもしれない。作ってみると面白いですよ。

* Alex Krizhevsky, Ilya Sutskever, Geoffrey E. Hinton. *ImageNet Classification with Deep Convolutional Neural Networks*. 2012. https://papers.nips.cc/paper/4824-imagenet-classification-with-deep-convolutional-neural-networks
ディープラーニングの火付け役、AlexNetの論文。個人的にこれはおすすめ。AlexNet自体は簡単すぎて他のネットワークに取って代わられたものの、ここに出てくるData Augmentationの議論が面白くて、例えばPCA Color Augmentationなんかは場合によってはまだ有効なんてケースがある。古い論文ながらここの発想は何年も先を行っている面白い論文。この論文自体がわかりやすいし、AlexNet自体は貧弱なGPUでも訓練できる（はず）なので、一度作ってみるのをおすすめ。一番最初にAlexNetの論文を読んでもいいと思う。ただ、Local Response NormalizationのところはBatch Normalizationに置き換えて実装したほうが楽だし、むしろ精度は良くなる（AlexNetのときにBatch Normalizationはなかったのでこれは仕方ない）。

* Xiangnan He, Lizi Liao, Hanwang Zhang, Liqiang Nie, Xia Hu, Tat-Seng Chua. *Neural Collaborative Filtering*. 2017. https://arxiv.org/abs/1708.05031
協調フィルタリングをニューラルネットワークで再現した論文。MLPを使っているが、ニューラルネットワークをレコメンドシステムに応用できるのが面白い。実装できればいいやだから完全には読んでいない。自分の実装が悪くて今振り返ればもう少し賢い実装ができたと思う。

* Laurens van der Maate. *Learning a Parametric Embedding by Preserving Local Structure*. 2009. https://lvdmaaten.github.io/publications/papers/AISTATS_2009.pdf
次元削減の（Parametric）t-SNEの論文。クラスタリングに近いことをする次元削減で、AlexNetよりも古い論文だが、ディープラーニングで再現することもできてまだまだ全然使える内容。ちょっと難しいけど、使いこなしたらいろいろ道が広がる。

* I.Loshchilov, and F.Hutter, *SGDR: Stochastic Gradient Descent with Warm Restarts*, 2016. https://arxiv.org/abs/1608.03983
ディープラーニングにおける学習率をコサインカーブで変化させるという大胆な発想ながら、精度は出る（らしい）。一度下げた学習率をまた上げるというのは自分はちょっとどうかなと思うが、コサインカーブで下げるというのが良いというのはへーっとなる。Cosine Decay自体はかなり有用で、息をするように使われていることもある。

* 加藤裕, 大谷真也, 黒木修隆, 廣瀬哲也, 沼昌宏. *4出力の畳み込みニューラルネットワークを用いた超解像*. 2016. http://www.ipsj.or.jp/10jigyo/fit/fit2016/RI-005.pdf
神戸大学の方が書いた日本語論文。CNNを使った超解像技術。理屈はかなりわかりやすくて、画像拡大におけるNearest Neighbor法をCNNを使ってより強力に綺麗になるように再現している。読んでそのままだけど、機会があったら実装してみたい。

* Olaf Ronneberger, Philipp Fischer, Thomas Brox. *U-Net: Convolutional Networks for Biomedical Image Segmentation*. 2015. https://arxiv.org/abs/1505.04597
U-Netの論文。あんまちゃんとよく読んでなくて図を見て実装したら満足してしまった。Semantic Segmentationの独特の要素がありそうなので、機会があったら見返すと思う。

* Hongyi Zhang, Moustapha Cisse, Yann N. Dauphin, David Lopez-Paz. *mixup: Beyond Empirical Risk Minimization*. 2017. https://arxiv.org/abs/1710.09412
Data Augmenationの手法「Mixup」の論文。実装自体はとても簡単なので実装だけが広がっている感はある。これも実装できたら満足してしまったので、ちゃんと読んでいないが「経験損失最小化」のアプローチから導入しているのが面白い。分類問題の汎化性能を上げるだけではなく、GANの安定化に寄与するという内容もあるので、GANをやることになったらまた読み返すと思う。

* Xavier Gastaldi. *Shake-Shake regularization*. 2017. https://arxiv.org/abs/1705.07485
論文内では触れられていないが、直感的にはData AugmentationのMixupをネットワーク内でやらせるという発想のもの。直感的にはわかりやすい。これの応用で[ShakeDrop](https://arxiv.org/abs/1802.02375)というのを日本人が作ったらしい。これはまだ読んでいない。

* Golnaz Ghiasi, Tsung-Yi Lin, Quoc V. Le. *DropBlock: A regularization method for convolutional networks*. 2018. https://arxiv.org/abs/1810.12890
Dropoutはランダムにドロップするせいで、周囲のピクセルとの関係性を見るCNNではあまり効かないから、ランダムに点を選んで四角形の形でドロップしましょうという発想。Data AugmentationのRandom ErasingやCutoutをネットワーク内でやっているようなイメージ。なんか転がっている実装を試したような気がするけどちゃんと試していない。

* Ryo Takahashi, Takashi Matsubara, Kuniaki Uehara. *Data Augmentation using Random Image Cropping and Patching for Deep CNNs*. 2018. https://arxiv.org/abs/1811.09030
「RICAP」と呼ばれるData Augmentation手法。これも作ったのは日本人。Mixupがpixel-wiseで2つの画像を合成するのなら、RICAPはランダムにクロップした4枚の画像をつなぎ合わせて合成するというなかなか変態的な手法。でも好き。

* Jie Hu, Li Shen, Samuel Albanie, Gang Sun, Enhua Wu. *Squeeze-and-Excitation Networks*. 2017. https://arxiv.org/abs/1709.01507
 ILSVRC2017の画像分類手法で優勝した論文の「SENet」と呼ばれるもの。既存のネットワークにチャンネル方向の特徴量の増強を加えるというのが面白い。自分が適当に実装したらあんまりうまくはいかなかったけど、多分実装が悪かったんでしょう。

* Yotam Hechtlinger, Purvasha Chakravarti, Jining Qin. *A Generalization of Convolutional Neural Networks to Graph-Structured Data*. 2017. https://arxiv.org/abs/1704.08165
個人的に面白いなーと思っているやつで、GraphCNNというテーブルデータの相関に注目してグラフ構造のデータを作り出して、それに対してGraph Convolutionという畳込み操作を加えるネットワーク。はじめはただのCNNかと思ったらちょっと違うらしい。ただ、構造化データに対してCNNに近いアプローチでできるのは楽しそう。試しにやってみたらReutersのニュースデータセットに対して、普通のCNNはMLPよりもかなり悪い性能だったのに対して、GraphCNNはMLPに匹敵するぐらいの精度は出るのは確認できた。GraphConvはいろんな論文が出ていて、論文によって定義が全然違うので難しい。

リストアップしたら意外と読んでいたことがわかりました。こんな読むつもりはなかったんだけど面白いのあるなーって見てると読んじゃうんですよね。無料で論文が読めるarXiv素晴らしい。

## 5.おまけ：他に読んだ本
実は本はほとんど読んでないのです。立ち読みしたものはいくつかありましたが、本読むよりも自分で実装したほうがはるかに得るものが大きかったからです。本は無難なことは書いてあっても、論文みたいに尖った内容書いていないこと多いですからね。

その中で2つほど買ったものをリストアップしておきます。

* Francois Chollet. 『PythonとKerasによるディープラーニング』. マイナビ出版. 2018. https://www.amazon.co.jp/dp/4839964262
Kerasの作者が書いている本で、これはとても良いです。Grad-CAMやらDeepDreamなんかも触れられていて、なにせ「Kerasでそう書くんだ」っていうようなのが適所に見られて参考になります。「エンジニアには数式よりもコードで説明するほうが伝わる」という発想が面白いし、実際機械学習の論文を読んでいても、えらい複雑な式で書かれている割にはコードを見たらそこまで難しくなかったというケースがよくあります。逆にコードを見ないとよくわからないというケースも非常によくあります（コード見てもよくわからないというケースも稀にありますが）。そこのツボがよくわかっているのはさすがだなーという感じはします。

* 山岡忠夫. 『将棋AIで学ぶディープラーニング』. マイナビ出版. 2018. https://www.amazon.co.jp/dp/4839965412
実はまだ読み途中なのですが、深層強化学習の具体的なアプリケーションとしての実践例というのが尖っていて面白いかなと思いました。自分は強化学習全然よくわからないので、Chainerで書かれているけど余裕があったら勉強がてらにKerasに移植できたら楽しいなと。

こんなところです。ディープラーニングの論文が読んで実装できるようになって十分な成果はありました。Courseraやって大正解でした。それでは皆さんよいお年を。