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

クーの自由研究

かえるのクーが素朴な疑問を実験して報告します。(冬眠から目覚めました!)

自己符号化器の自由研究(その3)学習済情報を再利用する

自己符号化器 自己符号化器-実験

おおまかな内容

自己符号化器(AutoEncoder)において、学習済の重み情報を用いるとどのように学習がすすむのかやってみました。

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

深層学習(DeepLearning)では自己符号化器(AutoEncoder)をつかった事前学習の結果を使うことがよくあるとのことです。それくらいなので、自己符号化器どうしでは問題なく学習済結果を初期状態として使用できると思います。

興味があるのは、ある活性化関数を用いた学習済結果を、全く別の活性化関数を用いた自己符号化器の初期状態としたときにどうなるかです。とっても予想できるのですが、本当のところはやってみなければわかりません。ボク、とっても気になります。

準備と実験のやり方 

重みWの特徴(フィルタ)が局所化されやすいSigmoid関数を活性化関数として使用し、学習をさせます。

次にその学習結果(重み)を別の活性化関数(ReLUを使います)の自己符号化器の初期値として使用します。

実験の結果

比較のために、まずは同じSigmoid関数で、自己符号化器の初期値として別の学習結果を使用します。下の前半部分です。

f:id:np2LKoo:20160820101536p:plain

次に同じ学習結果を今度は別の活性化関数(LeRU)の自己符号化器の初期値にして学習してみました。結果は上の図の後半です。

まとめ

Sigmoidどうしでは同じ活性化関数なので、引き続き学習しているといった感じです。バイアス bはゼロから学習しなおしですが、それによって重みWの形が崩れることはありませんでした。重みWがある程度定まっているので、バイアスbはそれにあわせて比較的早期に立ち上がると予想していたのですが、案外ゆっくりと立ち上がりました。当然のことながら、ランダム状態から学習するより、学習済の結果を初期値とした方がよい結果が得られました。習得した学習結果(重みW)がよりはっきりとしたものになった感じがします。これはまったく予想のとおりです。

初期状態が強い(山谷がはっきりしている)ので、習得した学習結果(重みW)の特徴が大きく崩れることはありませんでしたが、より強まるのではなく、LeRUのよくある特徴傾向へ「薄まっていく」感じでした。いままでの実験から活性化関数の違いとして以下の傾向があるように思います。あくまで、ボクの自己符号化器プログラムでの傾向で関数自体の特性ではありません。ただ、SDG(確率的勾配降下法)を使っているプログラムは同じような傾向がある「はず」です。

SigmoidReLU
局所的な特徴抽出がおこなわれやすい。生成の基底とした場合、特定部分を少ない要素で表現する 分散的全体的な特徴抽出がおこなわれやすい。多くの基底の重ねあわせで表現する
比較的スパースとなる傾向がある 比較的全体で表現する傾向がある
重みWの山や谷のピークは高い、もしくは高低差がある 全体的に重みWの高低差は少ない
比較的分散が少ないものに適している気がする。分散が多くなればノード数をふやせば対処できそう 分散が大きくても重ね合わせで表現できる気がする。分散のバリエーションが多くなれば山と谷とのコントラストを失っていくので再現性が低下しそう。これもノード数をふやせば対処できるはず

の傾向があります。ReLUとしての学習が進むとSigmoidの傾向からReLUの傾向へシフトしてくように思われます。最終的な数値としてはわるくないので「十分使える初期値」であると思いますが、精度をあげるというより、特定のフィルタを使用して自己符号化器を(再)構成したい場合に有効だと思います。

感想・思ったこと・考えたこと

活性化関数のSigmoidは最近でこそ深層学習の勾配消失問題によりきらわれる重要視されない傾向がありますが、テストした中では最も「局所的な特徴抽出」「スパース性」「(一定精度への到達する)学習速度」「符号化・復元化の精度」のどれもがバランスがいい優等生である感じがします。単層だと活性化関数で最強である感じすらします。なぜSigmoid関数を使用すると上の表のような傾向になるのか、数式からもアルゴリズムからもまだ読み解けていません。バイアス b が重要な鍵であるにおいはするのですが、どうしてSigmoidのときに特出してバイアスbがそのように(特徴分離を促すような)調整をするように動くのか謎です。とっても気になる部分です。肝心のテスト結果については「初期設定値」として有効ではあるが、劇的に値を改善したり、学習の傾向を変化させるものでもないと思います。また、別の活性化関数の初期値とした場合、値のレンジ(山谷の強さ)によってはすぐに発散してしまったケースも多数ありました。初期値として使う場合は、薄めて(たとえば値を1/10にするなど)使用するなどが必要でした。

空をとぶ蛇(Python)もいたらしい

ボクの中では謎が謎を呼ぶ展開となってきています。実験したいこともどんどん増え続けています。ソースはどんどん(かっこ悪く)ふくれあがりHatenaに貼り付けるのをためらっています。ソフトでの実験なのにソースもはならいなんて!といわれそうですが、いましばらくお待ちください(ていうか、予想とおりボクのページ超人気「ない」ので、期待している人いないのですが)。もし複数回ボクのページを見て頂いた方がいらっしゃれば超感謝申し上げます。

ソース貼り付けのためGitHubを使えるよう、英語の勉強がんばります!やっぱりソースはGitHubがよさげですね。