機械学習の理論と実装はどう学んでいくと良いのだろうか


TL;DR

  • 機械学習エンジニアは理論と実装の両方が求められる場合が少なくない
  • この二つは割と異なる学びの過程がある気がしているが、自分を例にとってそれを考えてみる
  • かなり強引に言うなら、理論は要素を積み重ねて全体を理解するやり方で、実装は全体から必要な要素を削り出していくやり方、な気がする
  • 自分は実装に関してはどうトレーニングを積んでいくのが良いかいまいち分かっていない

知人と話していてタイトルにあるような話題になった。 機械学習が流行るようになって、これまではサービスを開発するような仕事ではそこまで要求されなかったであろう、数学的な理論とプログラミングによる実装の両方を兼ね備えることの重要性が増している。

これは自分が興味あるような機械学習エンジニアの仕事において、という前提条件の下での話だ。 そんなのなくても仕事ができるとかもっと大事なことがあるとか、意見は色々あるかもしれないけど、ここでは自分が興味のある範囲のみを話したい。

自分の感覚ではこの二つを高い水準で兼ね備えている人はかなり稀な気がしている。 まずもって自分は兼ね備えていないと思っている。 人と比べてどうとかにはあまり興味がないが、自分が何かを実現しようと思った時にコードの読み書きとか実装面において能力不足だなと感じることが少なくない。 例えば TensorFlow のコードを理解したいと思ってるけど全然できてない。 これまでに必要になった部分はいくらか読んで理解してるけど、全体像がどういう構造になっていてどう実装されているのかとか、他人に説明できるようなレベルではない。

それは自分の勉強不足であるというのは全くその通りでもっと頑張れということではあるのだが、頑張るにしてもどう頑張ればいいのかを考えたときに、自分が比較的得意としている分野と同じように頑張ればいいというものでもない気がしてきたのでちょっと考えを整理したい。

以下では理論面と実装面で自分が物事をどう理解しようとしていて、それが良さそうな方向なのかそうではなさそうなのか、みたいなことを考えてみたい。 具体的な話はそれぞれがかなり長くなりそうなのでいつか来る時まで温めておくとして、今回は自分が抱いているイメージみたいな割とふんわりした話に留めておく。 ちなみに最初に言っておくと特にハッキリした結論が出ているわけではない。

理論面

機械学習エンジニアの仕事をする上で理論を理解するのは重要だと思っている。 もう少し正確に言うと、職名は何でもいいけどこれが重要になるような領域で自分は働きたいと思っている。

何と言うか、タスクが決まりきっていれば別に理論がどうとかいらない気もするが、自分が真に興味ある問題の場合はどう解くべきか分かってないものも多い。 こういう場合は理論的な基礎がないと扱える範囲の問題がかなり限定されてしまうと思っている。 解くためには問題を正しく理解しないといけないし、正しく理解するためにはどうしても理論的なアプローチが必要になる。 もちろん解法を考案する上でも理論的なアプローチが必要で、そういうアプローチができないと過去に誰かが解いたものと同じパターンのものしか解けないと思う。 そして多くの場合、実問題で直面するのは過去に誰も解いていないようなものだったりする。 それはパッと見では似てるかもしれないが、よくよく考えると同じパターンでは解けない、これは実務で機械学習をやっているとよく遭遇すると思うのですがどうでしょうか。

じゃあ理論的な理解をどう深めればいいのかという話だけど、これは本を読んだり論文を読んだり自分で問題を定式化したり、ということの積み重ねだと思う。 そしてその積み重ねのあり方だが、これは色んな要素を理解していって全体観を培うという感じな気がしている。 例えば、論文を読む時に全体は何言ってるかよく分からんけどそのうちのある要素については理解を深める、ということは実際にあるしそれでも役に立つ。 本も、ある要素を理解するために別の要素が必須ということはよくあるが、ともかく全体のつながりとかはよく分かってなくても各章ごとの理解が別個に役に立つことは珍しくない。

こういう要素を一つ一つ自分の中に蓄積してそれらを使いまわすことで、各要素の類似性が見えたりして理解が抽象的なレベルに引き上がって、ある領域の全体観が形作られる。 学問の世界では、これを地図を作ることになぞらえることが多い。 自分の居場所を点で明らかにしていって、その点を増やし、周りをよく観察したり点を行き来することで、大域的な地図を作っていくイメージである。

自分はこういうのは機械学習エンジニアの中では得意な方だと思ってるが、別に自分が優れてるとかそんなことは思ってなくて、単にそういうトレーニングを積んできたからだろう。 本当によくできる人は、要素を理解するスピードが猛烈だったり、他の人では気づけない要素間の共通性を簡単に見抜いたり、何かから学ばなくても自分で地図を描いていけたり、そんな感じだ。

ともかく、理論に関しては要素を積み重ねて大局観が身についていくというステップが基本だと思っている。

実装面

では実装を理解する(ここではコードを読んだり書いたりを指す)ことはどうだろうか。 これが仕事をする上で欠かせないスキルであることはそんなに異論がないと思うが、どうやって理解するのかはかなり違った能力が要求されるのではないかと思う。

もちろんこちらも個別の要素の理解は必要なんだけど、特にコードベースが大きくなってくると、そういうやり方では自分にとって必要なところまでたどり着くのが困難だったりする。 細かいところはよく分からないけど、とりあえず動作を確認したり、大まかにそのコードベースの主たる骨格を推定する。 そうやって全体観にあたりをつけてから、自分に必要そうな要素を明らかにしていって詳細を明らかにしたり、その要素の情報を元に全体観を修正したりする。 抽象的なんだけど、自分より能力のある人はこういうことがとても上手い印象がある。 なので一部のコードを理解するとかだとそこまで差は感じないんだけど、全体、しかも完璧な全体像でなくていま自分が特定の目的を果たすために理解すべき主たる構造、を理解するという点では大きな差を感じることになる。

理論と同じようにこれもトレーニングの積み重ねだとは思うが、こちらは経験がないためかどういうトレーニングをしていくのが良いかいまいち自信が持ててない。 数年前とかに比べれば自分でも相当に理解力は高まっているとは思うけど、やっぱり「この要素が分かってないとこの先が理解できないんじゃないか」みたいな考えが根付いてるのかその段階では無駄に細かいところに気を遣ってしまっている気がする。 理論とは違って、こちらは「特に他人の助けがなくても一人で良さそうな道を歩んでいける感覚」がないなぁという感じ。

単純に読み書きの量が足りないってのは当然あるだろうしその通りだとも思うんだけど、何かもう少し具体的な指針というか方向性があったりするかなぁと考えたりする今日この頃。 全体観にあたりをつけてから要素を掘り進めていく、みたいなやり方をどう鍛えていくかに一家言ある人の意見は色々聞いてみたい(それかこの感覚がそもそも間違っていたりするのか)。

まとめ

機械学習エンジニアに要求される、理論と実装に関する理解のためのアプローチの違いについて自分のイメージのようなものを書いた。 この手の話は人の意見を聞くのが結構面白いので、色んな人と議論してみたいなという気持ちです。