読者です 読者をやめる 読者になる 読者になる

クーの自由研究

かえるのクーが素朴な疑問を実験して報告します。

自己符号化器の自由研究(その8)バイアスbの学習率を独立させてみます

はじめに

最近、ゲームもそんなにしてないし、アニメもあまりみてません。「ボクもおとなになりました。」ではなく、思いのほかブログを書くのは時間がかかります。他の遊べる時間がないのです。この2ヶ月ほ思い返すとほとんどブログばっかりやってた気がします。本題の実験やプログラムは早くできても、それをまとめたり推敲(といえるものでもないですが)したりするのは不慣れもあってたいへんです。それ以外でもブログのちょっとした調整をするためだけに、HTMLやJavaScriptCSSの勉強もしました。ナマケモノのボクががんばって実験や調査を続けていられるのは、このブログのおかげです。(これがブロクを始めた理由なので、思いのほかうまく機能していることになります。)
とても熱しやすく冷めやすいほうで、よく「1かゼロで真ん中がないデジタルなヒト蛙」といわれます。あと1ヶ月も興味が続けば本物の「趣味」のひとつになるかもしれません。

系素材を扱うための調査・準備がひと段落したのですが、本実験でやりたいことが結構たまっているので、それから片付けていきます。いきなり音素材の実験ではすすまなそうなので、たまっている実験はもうすこしだけ「画像:MNIST」で行おうと思います。

おおまかな内容

自己符号化器(AutoEncoder)で重要なハイパーパラメータである学習率に関する実験をします。
学習するバイアスbは、重さWと同時に更新されていきます。この「バイアスb」の学習率は、通常「隠れ層:重さW」の学習率と同じものが使われます。そして(ボクのプログラムではいまのところ)事前に設定しておく定数です。(そのうちプログラム内で係数を更新(最適化)しながら学習できるようにするつもりです。実験課題です)
ボクの参照にした入門的な自己符号化器のサンプルは全部「重さWとバイアスbは同じ学習係数」を使用して学習していました。いろいろな技術説明でもそのようになっています。
本当にバイアスbの学習率は重さWの学習率と同じであることが最適なのでしょうか

「ボク、とっても気になります。」

なぜやるのか・どうなると思うか

実験(その2)で予め準備したガボールフイルタセットを初期値として学習開始することは、有効な方法であることがわかりました。(一般用途としては反則技ですが、入力が「縦横の分かっている画像」であれば「あり」だと思います)ランダムな基底から学習していくよりも、とても速い段階で元画像の再現ができていました。その実験の過程で、初期学習値を用いる場合には、(あるいは用いなくても)「バイアスbの学習率は重さWの学習率(これも結局は経験値でしかない)と別であってもよいのではないか。いや、『全体』のフィルタのかかり具合や合成強度を調整するバイアスであればこそ、積極的に別であるべきである。」と感じました。いままで動かしてきた感触から、「調整により初盤から中盤にかけけての状況がよくなる」ような予感がします。

準備と実験のやり方

最初のプログラムでに各活性化関するごとの学習率を決めた方法は「特定の活性化関数において、ひたすら実験ごとに学習率をかえながら、1024Epochになったときに一番学習の値がよいもの(元画像と復元画像の差異指標(Img-diff))で判断して決定しました。0.01ずつ値を変えながらの地道な作業でした。
Alpha Ratioが当実験プログラムの活性化関数毎に準備する学習率です。今回、補正係数Alpha-Bias Ratioを準備し、バイアスbを学習させるときに掛けます。Alpha-Bias Ratio=1.0 ならば元とかわない計算となります。
ランダムな初期値から始める通常の学習と、実験(その2)のガボールフィルタセットを初期値に使った実験(確認用)の2種類で実験してみます。ソース変更のコアな部分は以下です。


self.W1 -= self.alpha * gradW1
self.W2 -= self.alpha * gradW2
self.b1 -= self.alpha * self.alphaBias * gradb1
self.b2 -= self.alpha * self.alphaBias * gradb2

このBias学習率補正係数(self.alphaBias)を導入し、適した値を実験により求めます。

実験の結果

通常学習でのバイアスb学習率の検討

まずは、通常の実験で、今回追加したパラメータであるAlpha-Bias Ratioの適した値を導出(試行錯誤)しました。たえず値がふらふらしながら学習していくので、ある瞬間の値を用いてどのパラメータが優れているのか判断することは、結構難しいことです。すこしテスト範囲を広めにとって、ほぼ中央値のパラメータで、それがよさげであれば、採用しようと思います。厳密には統計計算をして条件を変えて求めていくべきでしょうが、正直「ハイパーパラメータ」はかなりいいかげんな設定でもそれなりに動き、データによってもフィットする、しないがぶれる感じがします。

活性化関数がSigmoid関数で、ボクのオートエンコーダロジック、かつMNISTで学習する場合は、バイアスbの学習係数はWの学習係数の2~4倍程度の値のほうがよりよい結果となりました。(結局は中盤から終盤の精度のよさを優先)

f:id:np2LKoo:20160925215506p:plain

水色が最優良の数値、黄色は隣接候補

下の実験は上よりSubscaleをかえて精度を上げて(=時間をかけて)確認しています

f:id:np2LKoo:20160925215738p:plain

いろいろ行った結果、補正係数Alpha-Bias Ratio=3.1を採用します。実際のバイアスbの学習率は [Alpha Ratio:]0.26 × [A*Bias Ratio:]3.1 =0.806 です。完全に独立させず Alpha Ratioへの補正としてパラメータを作成したのは単なるボクの「好み」です。Alpha Ratioが全体調整ということで考えたいです。(将来的な)自動調整などで完全に独立させたほうがよい状況になれば見直します。

他の活性化関数も随時パラメータを決めていきたいと思います。(リニアな直線区間の長い活性化関数では、感覚的に補正係数A*Bias Ratioはほぼ1に近くていいような「気」もしています)

事前準備したWから学習開始する場合での確認

学習係数はプログラム内でダイナミックにかえるのはありだと思いますが、手動でその都度変えるのはあまり実用的でない気がします。上記で確認した値が事前準備した重み情報をつかっても問題なく動作できることを確認するにとどめようと思います。

上側が従来とおりの動作、下側がBias学習率補正をくわえた場合の結果です。Bias学習率を補正すると重みWの学習内容も微妙にかわってくるのがとても興味深いです。

f:id:np2LKoo:20160925221832p:plain

結果は事前準備の場合でも今回の調整をしたほうが若干よい結果となりました。(従来:Img-diff=777.4 → 修正後:Img-diff=761.7) Sigmoid関数の場合は、この値を用いることで問題なさそうです。 

わかったこと・わからなかったこと

バイアスbの学習係数は重みWの学習係数と共用せず独立しても(実際には補正ですが)特に支障はありませんでした。

値によっては若干ですが、初盤及び終盤の学習がよりスムーズにできました。

最終結果はそれほど大きな変化がないのですが、わずかですが確実によい指標値になります。初盤から中盤までの学習が数値をみても変更前よりスムーズに進んでいる感じがするので、劇的な効果はないもの「有効」であると感じます。

本件はボクのオートエンコーダ(AutoEncoder)プログラムに「採用」することとします。(初盤、中盤の学習のすすみかたを結構実験するのでボクにとっては結構「ヒット」かなと思います。

I(ボク)'m a perfect Flog!

♪ I live in an old well...Koo!Koo!Koo!♪♪♪

余談ですが、この実験で使っているプログラムで参考にしたチュートリアルやサンプルPGは代表的な2、3個を除いてすべてどこにあったのかもわかりません。ちゃんとメモしておけばよかったと反省しています。さがしてもみつけられないので、2度とたどりつけない感じがしています。:ソースをまとめたとき、参考ソースのサイトリンクを張ろうと思って調べなおしたのですが、全くわかりませんでした。

有用なページはすぐブックマークするようにしようと思います。

(追記)洋楽やへんな個性的な音楽一辺倒のボクですが、そんなボクでも邦楽のポルカドットスティングレイはよかったです。「テレキャスター・ストライプ」最高です。

(追記2) ボクのつたないブログに初めて読者になっていただけました。どうも有難うございます。感激です!

(追記3+α+β)現在勾配降下のアルゴリズムで大人気のAdam実装でつまづき中です。全然思うような値になりません。ボクのAutoencoderプログラムのEpochはすぐ1000ぐらいいっちゃうので、べき乗に1000とか乗るとだいたいの数値がほぼゼロになるかほぼ発散しちゃいます。この調子だとその次に考えていたVAE(Variational Autoencoder)の実装実験もボクにはむりポかなぁ。そもそもつないでいる変数や関数を勘違いしているのかもしれません。参考にしているサンプルは結構抽象化・部品化されていて、そのサンプルを「具体的に」どのように使用すればいいのかを書いてないのが多いです。(自明なのかもしれませんが、ボクにはさっぱりです。フレームワークなどのソースを読んでも一層わかりません。)また、書いてあっても実装が多岐にわたり、(コアな計算式は同じものの)論文の解釈や実装方法に独自なものがあって、ボクのプログラムに何が適して何が適さないのか全くわかりません。ボク自身の実装では「それなり=学習が発散しない」には動くのですが、まったく期待した学習の曲線(もしくはコストの曲線)を描かないなのです。(十分学習するはるか前にパラメータ更新がほぼ収束してしまう)しばらくブログ更新は停滞となる見込みです。しています。八方ふさがりで、今はアダムを卵に還元して右手で培養できないか思案中です。  アダムを探しに南極へ行くことを検討しています。  アダム(の卵)がどうしても手にはいらないので、リリスのクローンで代用できないか研究中です。  研究がうまくいかないので本当の「****」のコピーで量産機をつくれないか試行錯誤です。