オートエンコーディングで失敗する。カラー画像のautoencoderを作るのは以外と難しい。

人工知能に関する断創録さんの多層パーセプトロンで手書き数字認識

http://aidiary.hatenablog.com/entry/20140201/1391218771

を参考にして、手書き数字のデータセット、digits(8×8)とmnist(28×28)に対応した手書き数字認識の実装をしたところ、まずまずの成功。


続いて、digitsとmnistに対応したオートエンコーダーの実装をしたところ、結構簡単にそれっぽいのが表示された。


【cifar10】

 GOOGLEの「DEEP DREAM」に憧れる私としては、
 調子に乗って、cifar10(32×32×3 カラー)に挑戦したところ、見事に失敗。

 最初にやったら、なんどか学習させたらなぜか同じ絵が表示される。
 いや〜挙動が、全然違うぞ。
 mnist(28×28)に比べて、出力層のユニット数や入力層のユニット数がカラーになったため、4倍近くになったけど・・・・
 まさか、こんなことになるとは。


【なにが起きた】
 隠れ層の出力が、どんな入力に対しても同じになっている。
 初期状態において隠れ層への入力が、かなり大きな値になっているの原因みたい。
 −30〜30とかになっている。そのため、出力は-0.99とか0.99とかそんな感じ。
 −30〜30とかになっている原因は、「ユニット数の増加」と「カラー写真はどのピクセル?にも数値が入っている」ため合計の値が増加しているみたい。


 初期状態だと、ウエイトの値はプラス、マイナスである程度、相殺され、ゼロに近くなるんだけど。
 ユニットの数が多くなると、さすがに相殺しきれなくなり、プラス側、マイナス側に大きく振れる。

 さらに、カラー写真は、手書き数字入力に比べて、0値の領域が少ないため、隠れ層に入る数値は、大きくなる。


 学習が進むと、重みが変化して、さらにゼロの値から離れていく。
 その結果、隠れ層に入る値の絶対値も大きくなる。毎回大きく−1〜1の間を振れるならいいのですが、−1〜1から遠く離れたころで、10〜30で触れられても、出力が1近くで変化がない。
 結果、出力が実質固定的になってしまった。


【単純な対処法】
 しょうがないので、関数に数値を入力する段階で、20分の1、50分の1にした。
 活性化関数も、ソフトサインに変えたところ・・・・まぁ、ノイズだらけだけど、物体らしき影が表示されるようになりました。

 ニューロの数を1024ではノイズだらけ、2048だとノイズが多いけどそれなり。
 4096にしても、2048とたいして変わらない。
 特徴を抽出しているのか、単に入力から出力にデータを流しているだけなのか、なぞだけど・・・・

□1024

□2048

□オリジナル



【結論】
 GOOGLEは凄い。