External Memory

プログラミング周辺知識の備忘録メイン

Network in NetworkでCIFAR-10分類

畳み込みニューラルネットワークにはいろいろなバリエーションがある。
その一つとしてNetwork in Networkを用いてCIFAR-10の分類を行った。
元文献ではerror率8.8%ほどまで達成している。
Network in Networkは以前書き下した以下のようなものである。
畳み込みネットワーク(CNN)の構造例2-Network in NetworkとMaxout networks - External Memory

元文献は
http://arxiv.org/abs/1312.4400


Network in Networkはmaxoutの派生のようなものである。
conv層の後にパーセプトロン層を複数、次いでpooling層からなるmlplayerと呼ばれる単位の構造からなっている。
今回実際に分類に用いる構造はmlplayer 3層である。
ネットワークの構成は論文中にはmaxoutに従ったとあるので、maxoutコードを参考にした。
https://github.com/lisa-lab/pylearn2/tree/master/pylearn2/scripts/papers/maxout

mlplayer中身の構成はパーセプトロン2層にpooling層(max_pooling window size 3 stride 2)、パーセプトロン層はカーネルサイズ1*1のconv層に等価である(文献ではパーセプトロン3層)。

最後のmlplayerはpooling層の代わりにglobal average poolingを用いた。
global average poolingはカーネルサイズが特徴マップサイズのaverage poolingと等価である。

data augmentationを行って、画像サイズは32から24に変わっているので結局構成は

conv6*6 - (conv1*1)*2 - max_pooling - (dropout) -
conv4*4 - (conv1*1)*2 - max_pooling - (dropout) -
conv3*3 - (conv1*1)*2 - global_ave_pool

conv x*x のx*xはカーネルサイズである。チャンネル数はmlplayerごとにそれぞれ96,192,192。

optimizerはadamで学習率は基本は0.001固定、weight decayの正則化による重み自由度制限は行っていない(元文献では行っている)。
また、ハイパーパラメータの最適化も行っていない。
dropoutはmlplayer層間に挿入しているが、今回はdropoutなしの方が分類精度は良かった。

構造構築の部分だけコードを抜粋すれば以下のようになる。

def inference(data,istrain):
    
    model = Conv_net(0.001,10,istrain)
    model.conv2d(6,6,3,96,"conv1-1",inpt=data)
    model.conv2d(1,1,96,96,"conv1-2")
    model.conv2d(1,1,96,96,"conv1-3")
    model.max_pool(ksize=[1,3,3,1])
    #model.drop_out(0.5)
    model.conv2d(4,4,96,192,"conv2-1")
    model.conv2d(1,1,192,192,"conv2-2")
    model.conv2d(1,1,192,192,"conv2-3")
    model.max_pool(ksize=[1,3,3,1])
    #model.drop_out(0.5)
    model.conv2d(3,3,192,192,"conv3-1")
    model.conv2d(1,1,192,192,"conv3-2")
    model.conv2d(1,1,192,10,"conv3-3")
    
    model.avg_pool(ksize=[1,6,6,1],strides=[1,6,6,1])
    model.reshape([-1,10])

    return model

当初、出力のほとんどがゼロで学習が進まなかったので、
・二つ目のpooling層はmax→averageに変更
・学習率変更
・バイアス初期値ゼロから少しずらし
をそれぞれ行うことでゼロ勾配を避けることができた。
結局バイアス初期値をずらすやり方が安定でハイパーパラメータ選択を自由に行えたので特別なことがなければ今後はこれを利用する。

以下の出力は10 epoch刻み100 epochまでで正答率が最大のものである。

  epoch         loss     accuracy
------------------------------------
second pooling layer "average pooling"
    100       1.6152       0.7947

learning rate 0.0001 
    100       1.4743       0.5413

bias init 0.1
     90       0.5381       0.8157

dropoutなし + bias init 0.1
     50       0.5829       0.8067
     90       0.5251       0.8306

前回行ったCIFAR-10サンプルコードで正答率は50 epochで正答率80%弱なので最適化なしでも若干学習速度が速い。
とはいえ期待したような性能を引き出すことはできなかったが。
空いた時間があるときにプログラムを動かして、90%辺りを目指して最適化を試みることにする。

あとは学習時間がかなり長いので(100epochで12h)、訓練データをきちんと分けて再学習が出来るようにしたほうが良かったということと、1-5 epoch程度の学習でハイパーパラメータのある程度狙いをつけられるようにしたい。