2017年12月26日火曜日

Batch Normalizationとスケーリングの影響を可視化して遊んでみた

Batch Normalizationとスケーリングが性能に与える影響を可視化してみました。 たぶん大多数の人にとっては誰得感のある情報ですが、 世の中のデータはスケーリングが簡単なデータばかりではないので、私は一度で良いから可視化してみたかった。

全体のコードは出すまでもないかなと思ったので省略しますが、Kerasの一番わかりやすいサンプルであるmnist_mlp.pyをベースにして調査してみました。 まずはBatch Normalizationを付けない状態で、スケーリングを行っている部分を以下のように変化させてみました。
# x_train /= 255  # 1e1 (baseline)
# x_test /= 255  # 1e1 (baseline)
# x_train = x_train / 255 / 100   # 1e-2
# x_test = x_test / 255 / 100  # 1e-2
x_train = x_train / 255 * 10000   # 1e4
x_test = x_test / 255 * 10000  # 1e4
結果は以下。mnistのコードをそのまま利用した場合、適切なスケーリングである1e1から離れると顕著に性能が下がる事がわかります。 特に特徴量の平均が大きくなるとまったく学習できていません。 いかにスケーリングが重要かよくわかる結果と思います。




次にBatch Normalization (BN)を付けた場合も検証してみます。 モデルに以下のようにBNを追加し、同じようにスケーリングを変化させてみました。
model = Sequential()
model.add(Dense(512, input_shape=(784,)))
model.add(BatchNormalization())
model.add(Activation('relu'))
model.add(Dropout(0.2))
model.add(Dense(512))
model.add(BatchNormalization())
model.add(Activation('relu'))
model.add(Dropout(0.2))
model.add(Dense(num_classes, activation='softmax'))
特徴量の平均を小さくすると性能低下しています。 [0,1e-2]のスケーリングでも若干の収束遅れが見られ、[0,1e-4]では悲惨な事になる事がわかりました。 逆に平均を大きくしても性能にはまったく影響なし。BNも割とあっさり死ぬんだなあ。



特徴量の平均を小さくした時にBNが死ぬのはなぜでしょう。 BNの標準化式に含まれるepsilonの影響かと考え、epsilonをより小さな値(1e-8)にしてみました。 しかしこれは失敗で、先ほどと大差ないグラフになりました。 epochを増やしたり、epsilonをさらに小さくしたり、最適化関数を変えたりしてみましたが駄目駄目。 となると更新幅の係数の影響のほうが大きいのかも。 まあよくわからないので、BNを使う時は特徴量は小さくするよりを大きくしたほうが良さそうと、お茶を濁しておきます。 ちなみに[0,1e-4]などの分布のデータを事前に標準化すれば問題は起きません。 この特性は多層で大丈夫なのかなあとちょっと心配になる結果。



まとめ

  • 特徴量はスケーリングしないと駄目、絶対
  • スケーリングが面倒臭いならBatch Normalizationしよう
  • ただし特徴量の平均が小さ過ぎるとBatch Normalizationは死ぬ
  • Batch Normalizationが死んだ時は特徴量の平均を大きく
  • 緩募: 特徴量の平均が小さい時でもBatch Normalizationを動かす方法

誰得感のある情報ですが、Batch Normalizationは凄いものの特徴量の平均が小さい時に起きる突然の死に注意という事がわかりました。

2017年12月6日水曜日

フリゲ紹介: ひよこ侍

ひよこ侍は結構昔の有名な作品なのですが、 名前が適当な感じ(失礼)に感じてスルーしていたゲームでした。 ただ実際にプレイしてみると、評判通り面白かった。 もっと早くプレイすれば良かったなあ。やはり食わず嫌いは良くないですね。



最初はかわいいひよこが主人公のほのぼのRPGなのかと思っていましたが、 ひよこのぬいぐるみを被った目つきの悪い主人公(左下)の、割とシリアスなRPGでした。 なぜ主人公はひよこのぬいぐるみを被るのか…それはプレイして確かめてみてください。



ひよこ侍は1vs1のシンプルな剣術アクションRPGなのですが、これがなかなかどうして面白い(右上)。 必殺技などももちろんあります。 気を抜くとあっさり負けますが、難し過ぎる訳でもなく、手頃な難易度で爽快感もある。 絶賛も頷ける作品でした。

フリゲ紹介: Trustia 〜トラスティア〜 Last Reincarnation

Trustia 〜トラスティア〜 Last Reincarnationウディコン2016で5位だった作品。 なぜかプレイしていなかったのですが、凄い作品でした。



ストーリーは王道的なRPGなのですが、とにかくバトルシステムが凄い。 まさに「俺の考えた最強のバトルシステム」を地で行くゲームで、ただただ凄いとしか言いようがない。

戦闘はリアルタイムに進行し、ド派手に攻撃が駆け巡ります(左下)。 4人の仲間のポジションは戦闘中に変更して攻守を調整でき(右下)、 敵の攻撃をアクションでブロックする事もでき、 連携ゲージを溜める事で連携必殺技を使う事ができ、 操作キャラ以外は自動で戦ってくれる。 ………凄過ぎる。



一応イメージは上記の通りなのですが、この凄さは画像だとまったくわからないかも (私も上の紹介画像を見てもスルーしていました)。 そこで作者様の動画も合わせて貼ってみます(下)。 これを見ると凄さがよくわかると思う。



今までプレイしたRPGの中で一番凄いバトルシステムだったと思います。 是非一度は体験してみて欲しい作品でした。

フリゲ紹介: ニルダ物語

ニルダ物語はVIPRPG 2007紅白で1位だった作品。 VIPRPG 2007紅白はリンク切れでプレイした事がない作品ばかりなのですが、評判が良かったのでプレイしてみました。 どことなく○ルダの伝説に名前が似ている作品ですが、そっくりという訳でもない。



ニルダ物語は左下の主人公を操り、剣と魔法を駆使して世界を探索するシンプルなアクション2Dローグライクです(右下)。 ローグライクらしく物語の意味はあまり語られませんが、徐々に目的が見えてくるようになっています。



武器や防具はすべて敵がドロップするので、とにかく敵を倒すのみです。 敵を攻撃する場合は隣接してひたすらキーを連打するという方式になっています。 魔法も色々あるのですが、基本はキー連打でタコ殴りにしていく事になると思います。

長編RPGではないのでサクッとクリアできました。 さほどレベル上げも必要とせず、難易度も手頃で爽快感があり、シンプルに面白かった作品でした。 後継作品にニルダ戦記というものもあるようなので、いつかプレイしてみたいです。