終点枕崎

にゃーんo(^・x・^)o

畳み込みニューラルネットで手書き文字認識をやってみる(MNIST)

ここ最近やったことを書き留めておきます。

前回からニューラルネットの実装にいくつか昨日の追加や変更を行ないました。

追加点

  • レイヤー
    • 畳み込みレイヤー
    • プーリングレイヤー
      • max pooling layer
      • average pooling layer
    • 多変数関数用活性化レイヤー(中間層にsoftmaxなどが利用できるようにするため)
    • ドロップアウトレイヤー
    • 誤差関数レイヤー
  • Optimizer
    • 確率的勾配法
    • モメンタム付き確率的勾配法
    • AdaGrad
    • RMSprop
    • AdaDelta
    • Adam
  • 重み減衰

RMSpropは、有名な手法ですが論文化されておらず、大学の講義で発表したのみだそうです。面白いですね。

変更点

前回の設計が適当すぎたので、設計を大幅に見直しました。最終的には、ゼロから作るDeepLearningの実装に似たものになりました。実はゼロ作の実装はChainerの実装と似ていて、今回はChainerも参考に設計しています。

  • 線形変換層と活性化層の分離
  • 各層をクラス化
  • レイヤー間を流れるデータの次元の順番を変更

実装で突っかかったところ

畳み込み層はim2colで実装しました。im2colは、出力層の各ピクセルについて、フィルターの適用範囲のピクセルを重複ありで一覧のように並べ換える変換です。

f:id:uchifuji:20180219015316p:plain

その逆伝播の実装で、im2colの逆のようなことをするcol2imを使うのですが、ここで重要なのは、実はcol2imはim2colの逆写像ではないということです。col2imは偏微分を伝播するのだから当たり前ですけどね。はじめこれに気づかずに実装しましたが、im2colは1変数対1変数の変換ではないので、偏微分の連鎖律を適用しなければいけません。(実際は、間違った方法でもなぜか上手く動きました。不思議です。)

f:id:uchifuji:20180219021020p:plain
正しくはこう。

まだやってないこと

BatchNormalizationの逆伝播の計算が途中なので、計算が完了し次第実装するつもりです.

MNISTに再チャレンジ

CNNが構築できるようになったので、再度MNIST(手書き文字認識)に挑戦してみます。
ネットワークの構成はTensorFlowのMNISTチュートリアルとほぼ同じです。OptimizerはAdamを選択、学習率は0.001、{\beta_1}{\beta_2}{\epsilon}は推奨値ををそのまま設定しました。バッチサイズを50とし、5epoch分学習させます。

f:id:uchifuji:20180219050120p:plain

学習結果は以下になります。

  • 正解率(全データ)
テストデータ 訓練データ
99.14% 99.55%
  • 正解率の推移(先頭1000データ)

f:id:uchifuji:20180219050402p:plain

さすがAdamといった感じで、学習速度も正確性も良好でした。ちなみにMNIST世界一位は99.79%で、DropConnectというドロップアウトを重みに適応した手法を用いてるそうです。

最後に、MNISTの学習に使用したソースコードを載せておきます。作ったライブラリの実装はgithubに上げておいたのでそちらをご覧ください。

github.com


参考文献

  • 深層学習 - 岡谷貴之
  • ゼロから作るDeepLearning - 斎藤 康毅