seri::diary

プログラミングのこととかポエムとか

こんな私でもニューラルネットワークをスクラッチで実装できました(30歳 男性)

この記事はトレタ Advent Calendar 2016の22日目です。
21日目はswdhActiveRecordオブジェクトを関連ごとシリアライズしてデシリアライズするでした。

スナップショット的にその時点のモデルを関連モデル含めて保存したい、っていう要望はBtoBやってると結構遭遇しますね。テーブルをちゃんと正規化すればするほど難しくなるやつなのでgem化されてるとありがたいです。

f:id:serihiro:20161221233653j:plain

さて、この記事ではゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装を読んでpythonに入門するところから初めてニューラルネットワークを実際に実装して見た所感を記述します。平たく言えば読書感想文です。


書籍「ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装」の概要

本の内容としては

という流れ。

なお、本文中に出てくるサンプルコードはすべてgithub公開されているので、写経するのがだるいという人でも安心だ。

読んで実装してみた所感

前提条件として、自分は機械学習は多少かじった程度の知識しかなく、ニューラルネットワークについてはパーセプトロンとの違いとバックプロパゲーションのぼんやりとした概念、ぐらいしか知らないレベルでこの本を手に取ってみた。あともちろんpythonも書いたことがなかった。

TensorFlowやChainerのMNISTサンプルを動かしてみたりもしたのだが、フレームワークを使うといまいち抽象度が高くて具体的に何をやってるかわからないと感じていた。(余談だが結構そういう声をよくネットで見かける)

そういう状態で読んで一通り実装してみたのだが、今までふわっとしていた「ニューラルネットワークとはこういうものか」というイメージがかなり明確になった。それが何によるものかということを以下述べていきたい。

なぜこの本が良いと思ったのか

この本の最大の特徴は、機械学習系の本だと省略されがちな数学の前提知識について1つ1つ丁寧に説明されている点と、それらが全て動く「コード」を持って説明されている点にあると感じた。

文字通り「ゼロから作る」ための本である。pythonを手元で動かせる環境さえあれば数学の知識がなくても問題ない、という機械学習系の入門書にしては非常にめずらしい位置づけの本である。

どのくらい「ゼロ」でも大丈夫か?体を張って試してみた

結論から言えば、高校数学なんて忘却の彼方という人でも全然問題無いと言える。

例えば、ニューラルネットワークでは結果を求めるまでに途中で行われる計算の流れを行列を使うとスッキリ書けるのだが、いきなり行列の積だけ書いて放置するようなことはしない。 まずは行列の積の計算の仕方(行列の掛け算ではどの要素とどの要素を乗じるのかという所から)から説明してくれる。NumPy特有の話もあるが、基本的には遠い昔高校時代に習ったような説明を受けることができる。

また、勾配降下法の説明をしている章では、微分の定義から始まり数値微分の計算方法を説明している。至れり尽くせりである。

しかも、それらは数式だけでなく、すべてpythonの実装がセットになっている。例えば数値微分を行う関数もサンプルコード上で下記のように実装されている。 *1

def numerical_diff(f, x):
    h = 1e-4 # 0.0001
    return (f(x+h) - f(x-h)) / (2*h)

そのため、説明がよく理解できずとも、pythonの実装を読んで、写経して手元で動かしていじっているうちに計算手順のイメージを掴むことができる。

数値微分の実装は、引数をあれこれ変えて近似された値を計算で求められると、解析微分の公式だけを丸暗記していただけの微分がまた違うものに見えてきて非常に面白い。

コードを書いて動かして学ぶというアプローチについて

こういうアプローチは、数式よりもコードに馴染みがあるプログラマならではの方法かも知れないが、少なくとも自分はもともとコードを書いて動かした方が理解しやすい派なのでこの本のアプローチはかなりマッチしていた。

数学が得意な人にとっては、わざわざシンプルに表現された数式をプログラムに変換して動かして理解するという面倒なことをよくやるもんだという感想を抱くかもしれない。しかし、実際に自分でコードを書いて動かした結果を確認する学習方法は、プログラマにとって一番理解し易いアプローチではないかと思う。*2

一方で、説明がかなり細かいので、既知の知識と重複するところが多い人には本書は少々冗長に感じるかも知れない。 しかし、大学時代に数学を勉強していない筆者のような人間にとってはこういう基礎知識こそがありがたい。

まとめ

  • 「プログラミングは普通にできるけど機械学習とかニューラルネットワークってなんか難しそうだな~」と思ってる人にこそ読んでほしい一冊。
  • まだちゃんと理解できていない部分もあるので年末年始に改めて読み直したい。
  • トレタ Advent Calendar 201623日目は私とよく昼食を一緒に食べに行くサーバーサイドエンジニアの出番です。

*1:https://github.com/oreilly-japan/deep-learning-from-scratch/blob/471ff64c25d27eaad58d8b5a9e787249db974d44/ch04/gradient_1d.py#L6-L8

*2:余談だが自分も統計モデルについての本を読んでいた時はポアソン分布の定義にしたがって確率を計算するクラスを実装してみたりしていた。 bitbucket.org