だれかの備忘録

主に自分用。

CNNモデルの最適化(処理時間の短縮)

Deep Learningで分類するときに正答率が0.1%でも高くなるよう努力することも多いと思いますが、正答率を少し犠牲にしてもいいので処理時間を削減したいこともあります。高性能サーバーではなく組み込みで処理するときは計算のための性能がしょぼいことが多いです。
今回はそこそこの精度でいいので処理時間が短くなるようにCNNモデルを最適化します。

やること

  • CNNモデルのパラメータ1つずつに着目し、パラメータを前後に振って正答率と処理時間の変化を確認する。
  • 複数のパラメータを変更し、正答率の合格点(0.95以上)になるまでパラメータを調整する。

結果

正答率を1.6%犠牲にすると、処理時間を約3分の1にできました。

使ったCNNモデル

今回もこのサンプルを使います。
MNIST分類のCNNサンプルプログラム - だれかの備忘録
今回は複数のパラメータを変化させるので分かりやすいようにモデルを図にしました。
f:id:positive_bedridden:20190131205550p:plain
※この図の作成にはConvNet Drawerを使いました。
GitHub - yu4u/convnet-drawer: Python script for illustrating Convolutional Neural Networks (CNN) using Keras-like model definitions

調整するパラメータ

パラメータ 変化させた範囲
畳み込み層(1) フィルタサイズ 5x5 1x1, 3x3, 5x5, 7x7
畳み込み層(1) フィルタ数 32 1, 8, 16, 24, 32, 40
畳み込み層(2) フィルタサイズ 5x5 1x1, 3x3, 5x5, 7x7
畳み込み層(2) フィルタ数 64 1, 16, 32, 48, 64, 80
全結合層 ノード数 1024 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 768, 1024, 1280

それでは各パラメータを1つずつ変化させてグラフで比較します。処理時間は秒数で比較しても環境によって大きく異なるので比率で比較します。Defaultの処理時間の比率が1.0になります。

畳み込み層(1) フィルタサイズ

f:id:positive_bedridden:20190131212528p:plain
横軸はフィルタの一辺のサイズです。
Defaultは5x5で正答率は0.966。3x3に減らしても正答率0.960・処理時間0.92、そこそこの性能で処理時間を少しだけ短縮できています。
こんな感じで他のパラメータでも見ていきます。

畳み込み層(1) フィルタ数

f:id:positive_bedridden:20190131212604p:plain
Defaultは32。1の正答率はさすがに悪いですが8以上は0.95をクリアしています。
注目すべきは8だと処理時間は約半分で正答率もそこそこ良い。処理時間削減に貢献できそうなパラメータとして期待できそうです。

畳み込み層(2) フィルタサイズ

f:id:positive_bedridden:20190131212625p:plain
Defaultは5x5。正答率は畳み込み層(1)の結果と似ていますが、処理時間への影響は大きくなっています。3x3で処理時間は3割削減できています。

畳み込み層(2) フィルタ数

f:id:positive_bedridden:20190131212648p:plain
Defaultは64。16以上は正答率0.96以上あります。処理時間は畳み込み層(1)ほど削減できていません。

全結合層 ノード数

f:id:positive_bedridden:20190131212714p:plain
Defaultは1024。1~1280まで変化させるのでこのグラフだけ片対数です。
1の正答率は論外ですが、処理時間も大きくは減らせていません。やはり畳み込み層の方の処理が多く、全結合層をいじっても大して変わらないみたいです。
f:id:positive_bedridden:20190131212725p:plain
続いて正答率0.93以上の拡大図。128以上で正答率0.95、512以上で正答率0.96を超えました。

処理時間削減に効果のあったパラメータを複数組み合わせる

正答率0.95を超えたパラメータの組み合わせ

これまでの結果で正答率0.95以上を超えたパラメータのなかで一番小さな値の組み合わせを選択しました。

  • 畳み込み層(1) フィルタサイズ:5x5 → 3x3
  • 畳み込み層(1) フィルタ数:32 → 8
  • 畳み込み層(2) フィルタサイズ:5x5 → 3x3
  • 畳み込み層(2) フィルタ数:64 → 16
  • 全結合層 ノード数:1024 → 128

結果 → 正答率:0.906、処理時間:0.16

処理時間は爆速です。ただ正答率は良くないので調整します。

正答率0.96を超えたパラメータの組み合わせ

正答率の条件を少し上げました。

  • 畳み込み層(1) フィルタサイズ:5x5 → 3x35x5
  • 畳み込み層(1) フィルタ数:32 → 8 → 16
  • 畳み込み層(2) フィルタサイズ:5x5 → 3x3
  • 畳み込み層(2) フィルタ数:64 → 16
  • 全結合層 ノード数:1024 → 128 → 512

結果 → 正答率:0.947、処理時間:0.33

目標の正答率0.95までもう少し。何か1つのパラメータを変えれば目標クリアできそうな気がする。

処理時間への影響が小さかったパラメータの変更

全結合層のノード数の変化は処理時間への影響が小さかったので、この値を1段多くしてみます。

  • 全結合層 ノード数:1024 → 128 → 512 → 768

結果 → 正答率:0.950、処理時間:0.34

目標の正答率0.95をぎりぎり達成しました。
元の正答率(0.966)から1.6%を犠牲にすることで処理時間は約3分の1になりました。

こうして出来たモデルを描画すると以下のようになります。
f:id:positive_bedridden:20190131223517p:plain

まとめ

正答率を少し犠牲にして処理時間を削減するという観点でCNNモデルのパラメータを手作業で最適化しました。28x28pixのMNIST画像を使った場合にモデルをどれぐらい簡略化できるのかといったのを感覚的に知ることができました。何か新しいモデルを作るときの参考になるといいなと思います。

課題

実は同じモデルを使って処理しても、処理ごとに結果が少し変わります。例えばDefaultのパラメータでも5回試行した正答率は、4回は0.966~0.967でしたが1回だけ0.869とかなり低い結果になりました。他のパラメータでも同様にたまに低い値となることがありました。今回はとりあえず5回の中央値を結果として採用しました。
重みの初期値とデータの学習順がランダムになっているので毎回異なる結果になるのだと思いますが、これの改善ができないか気が向いたら検討したいです。