ややプログラム紀行

博士2年のプログラムに関する日記

自動微分

自分はtensorflowみたいなフレームワークがどうしても苦手で、このままでは仮に理論系をやるにしても歩き方を知らないで最適な走り方の研究をするようなものなので、まずはそのブラックボックスな部分を理解することにしました

 

github.com

 

ネーミングセンスがなさすぎる

README.mdの通り、リバースモードかつDefine-by-Runの自動微分ライブラリ?です*1

途中まではそれなりに工夫を凝らしたものを作ろうと思ってたんですが、肝心の自動微分アルゴリズムが分かってからは余り時間をかけたくなくなってしまったので方向転換して至極単純な実装になりました

 

 

実装にはこの論文を参考にさせてもらいました

arxiv.org

自動微分アルゴリズムは感動するほど単純で、連鎖律をどう計算するかに尽きます

上の論文曰く自動微分アルゴリズムには大きく分けてフォワードモードとリバースモードというものがあり、機械学習のような入力数多めかつ出力数少なめ(損失関数なら基本的に1次元)という関数に対してはリバースモードのほうに分があるっぽい*2

 

これで動いてんのか?!ってぐらい単純ですが、線形回帰をあえて自動微分でやってみるサンプルが動いてるっぽいから多分今のところ大丈夫

余裕あったらせっかくだしニューラルネットでMNISTとかやってみたいです

自分で実装してみると、例えば線形回帰とかは学習しやすそうなイメージがあるのに、それでも最急降下法で学習率を少し大きくしただけですぐ発散して不安定なんだな~っていうのが実感できて結構ためになった*3

*1:正直Define-by-Runって言うのも憚られるレベル

*2:誤差逆伝播法はリバースモードの一例にすぎないっていうのがへぇ~ってなった、ADerだとリバースモードの計算関数をbackpropって名前にしちゃってるけど

*3:実際線形回帰なんてそうそう発散しなさそうだけど何が起こってるんだろ?