何から勉強始めたらいい?(非情報系が機械学習を使う研究をしたいとき)

以前、「非情報系が機械学習を使う研究をしたいとき」という記事を書きましたが、内容の半分はサイボウズ・ラボユースの宣伝だったんで、今回はタイトル詐欺じゃあないことも書きます。

いままで機械学習や深層学習に縁のなかった人が、それを使った研究を始めたいとなったとき、共通して直面する大きな課題は「何を優先的に勉強したらいいか」と「実験用の環境(PC)をどのように整えたらいいか」でしょう。
今回は何から勉強する? という話。
機械学習そのもの(特に自分が使おうとしているモデル)を学ぶのは必須に決まっているので、機械学習を使う上で必要となる前提知識を学ぶ優先順位について考えてみます。

機械学習(深層学習を含む)を使う上でキーになる前提知識は、数学(特に解析・線形代数・統計)とプログラミングを含む情報科学であることは意見の一致するところだと思います。
情報系の人なら、情報科学はさすがにやってます。プログラミングもやってるでしょう(始めたばかりかもしれませんが)。解析と線形代数はカリキュラムに入っていたはず。最近はデータサイエンス流行りで、統計も必修だったりするかも。
「テストが終わったら忘れた。まさか数学使う日が来るとは夢にも思わなかった」という人には厳しい日々が待ってます……。

非情報系の人だと、それらを修めている可能性はやっぱり高くはないですよね。「いわゆる文系」だと、解析・線形代数すら怪しい。それらを学び終わるまで待っていたら研究が始まりませんから、走りながら学ぶしかありません。
しかし自身の専門分野の勉強もある中で、数学と情報科学を学ぶ時間を作るのは大変ですし、モチベーションの維持も難しい。となると優先順位をつけるしかありません。
あくまで個人的な見解ですが、それらに学ぶ優先順位をつけるとすれば、「プログラミング > 情報科学 > 統計 > 線形代数・解析」だろうと考えています(先に書いたものほど優先順位が高い)。
これは、機械学習を使った研究をする上で、それを学ばなかった場合に生じるかもしれない支障の大きさの順で並べました。

プログラミング

今は深層学習系のライブラリがとても充実していて、数学の知識が足りなくても、モデルとその学習を実装するくらいならそこそこなんとかなります。
もちろん、数学を勉強する必要が全くなくなった、というわけではありません。モデルを理解し、データに合わせて改良するときなどは、数学の知識は間違いなく役立ちますし、自分が最終的に選んだ手法を(後付でも)理屈をつけて説明したいときに数学ほど頼りになるものはありません。

ただ、深層学習を使った研究をするときにネックになりやすいのは、設定(ハイパーパラメータやモデルの構造)を変えながら試行錯誤を繰り返す部分です。深層学習では同じモデルですら、ハイパーパラメータだけではなく初期値や学習順序の乱数で性能が大きく変わるので、様々な設定で実験を繰り返し、計測した性能を比較する必要があります。
これを手作業でやっていては実験できる回数が限られてしまい、最終的に到達できる性能が(本来届いたかもしれない性能よりも)低くなってしまいます。したがって、放っておいても自動的に実験を繰り返してくれるようにシステムを作り上げることがとても有効です。
もちろんそれを助けてくれるライブラリもありますが、それを使いこなして、自動的にモデルを組み替えて性能を計測してくれる仕組みを作るにはやっぱりある程度以上のプログラミング能力がないとうまくいきません。つまり、プログラミング能力が結果(論文に書く性能値)に直結するわけです。

また、非情報系の人がわざわざ機械学習に手を出すということは、機械学習用に整備されたデータセットを使うのではなく、おそらく独自のデータを使って研究するのでしょう。そういうデータを機械学習のモデルで扱えるように変換したり、ラベルをつけたりするだけで結構な手間がかかります。経験のない人がなんとなく想像するのより、10倍以上大変だと思っておいてください。
さらに、機械学習では性能を出すためにオーグメンテーション(データにランダムなノイズを乗せたり変換したりして訓練データを増やすこと)などの工夫を行うことが望ましいです。独自データで量が少なかったら、そのあたりの工夫がとりわけ重要になります。
これらを解決するのにも、とにかくプログラミング能力が要求されます。ほら、プログラミングが最優先な気分になってきたでしょう?

情報科学

情報科学のうち、プログラミングに関わりが深い範囲は同じくらいの必要度があると考えてます。例えば、基本的なアルゴリズムと計算量の考え方、疑似乱数、そしてできれば浮動小数点の精度と演算誤差についても押さえておきたいです。
アルゴリズムはデータの前処理の部分で必要になりがちですし、計算量は処理時間の見積もり(データやパラメータを増やしたときの変化)や、先行研究との速度比較において重要です。
機械学習の実験では、初期値や学習データの順番などさまざまなランダム性が用いられますが、ランダムな値を使っていると毎回結果が異なってしまい、実験結果を再現できないという問題があります。コンピュータが使っている通常の乱数は、実際は疑似乱数と呼ばれるもので、乱数の初期化に用いられる値(シードといいます)を固定することで、毎回同じ乱数列を生成してくれるようになります。

コンピュータで実数を表現するのは浮動小数点数というデータ形式です。これは任意の実数を扱えるわけではありません。「浮動小数点数で扱えない実数」が出てきたときは、誤差が生じたり、オーバーフロー(扱える範囲を超えた)というエラーになったりします。
というと、滅多にない事のように聞こえるかもしれませんが、実は残念なことに、浮動小数点数で表現できる実数は、実数全体からしたらほんのわずかでしかなく、誤差は常に付きまとう問題なのです*1
例えば 0.1 という、人間にはごく普通に見える値ですら、コンピュータ上では「0.1 に一番近い浮動小数点数」として表現されているに過ぎません。

In [1]: format(0.1, ".18g") # 0.1 を小数点以下18桁まで表示
Out[1]: '0.100000000000000006'

数学では 1-(1-x)=x は常に成り立ちますが、浮動小数点数の計算誤差のためコンピュータ上では必ずしも成り立ちません*2

In [2]: 1-(1-0.0001) # 0.0001 が出力されることを期待
Out[2]: 9.999999999998899e-05

こうした誤差を考慮して、機械学習でもよく使われるライブラリの numpy や torch には、isclose という「同じ値とみなせるほど十分近い」を判定する関数があり、イコールの代わりにそちらを使わなければならないケースも多いです。
また、機械学習では指数関数 exp が大活躍しますが、この関数はとてもオーバーフローしやすいです。GPU で主に使われる float32(32ビットの浮動小数点数) では exp(89) がオーバーフローして inf(無限大) になります。無限大よりはるかにはるかに小さいんですけどね(笑)。

浮動小数点数の計算誤差は普段はあまり気にしなくていいですが、たまにそれに起因する問題が生じます(長く機械学習の研究をしている人なら、少なからず経験してるはず)。そのとき、それを知ってるか知らないかで対処できるかどうかが変わってくるでしょう。

数学

数学はプログラミングたちより低い優先順位にしちゃいましたが、機械学習にとって数学は引き続き重要です。ただ、学習コストと即効性がね……。
上にも書いた通り、深層学習の流行と環境の整備のおかげで、「数学を避けたら研究できない」という状況でもなくなったという事情もあります。

ただそれでもやっぱり数学をやるしか! となったとき、機械学習に直接関係してくる数学トリオ(解析・線形代数・統計)の中で優先するものを1つ選ぶなら、統計です。
特に、母集団、標本、分布、各種統計量などの基本と、検定の初歩(統計で何がわかって、何がわからないか)あたりが重要です。ついでに大数の法則中心極限定理も是非押さえておきたい*3
統計の本で結構なページ数で紹介されていることの多い「いろんな種類の検定(z検定とかカイ二乗検定とかとか)」はひとまず不要です(仮に必要になったらその時学べばいい)。

というのも、(統計的)機械学習がやっていることは「与えられた標本から母集団の分布を推定する」ことにほかならないからです。
深層学習の時代になっても、いやむしろ、現実のデータをそのまま食わせる深層学習だからこそ、その統計の基本を理解していることは大きなアドバンテージになります。
即効性のある話に限っても、標準化やオーグメンテーションなどのデータ前処理では統計の知識が役立ちます。統計がわかっていれば、トンチンカンな標準化をしてしまう可能性を小さくできるでしょう。


最初にも書いた通り、この優先順位はあくまで個人的な意見です。機械学習(深層学習)をどのように使いたいかという個々の事情によって優先度が変わってくる可能性もあるでしょうから、もし身近に聞ける人がいるなら自分が何を優先したらいいか聞いてみるといいでしょう。
そういう人がいるなら、こんなブログ記事を読む必要もないんですけどね(笑)。

*1:浮動小数点数の問題ではなく、そもそもコンピュータは有限通りの値しか扱えないので、任意の実数など当然扱えません

*2:float32 で 1-(1-0.0001) を計算すると、もっと無視できない大きさの誤差になります。

*3:チェビシェフ不等式とイェンセン不等式も重要でしょ……みたいなツッコミも出るでしょうが、キリがないので、大数の法則中心極限定理で勘弁してあげてください。