まんぼう日記

takataka's diary

Theano で MLP & CNN (3)

先週末の暴挙のせいでまだ体のあちこちが痛いんですが (^^;

のつづき.Multi-Layer Perceptron と Convolutional Neural Network で CIFAR-10 の画像識別をやってみます.

 

3層MLPでの実験 

プログラムと実験条件

次のプログラムを使いました.

実験条件は次の通り.

  • データの前処理は,ZCA whitening ありなしの二通り.なしの場合は,画素値を255で割って平均を0にするだけ.ありの場合,\( \varepsilon = 0.001 \) で正則化.
  • 入力-ReLu-ReLu-softmax の3層MLP,素子数は 3072 - 1000 - 500 - 10
  • 学習はSGD.慣性項 + weight decay あり.
  • マシンは Mac Pro (Late 2013), Intel Xeon E5 3.5GHz(6コア),メモリ64GB

MLPのパラメータ数は,( 3072 + 1 ) x 1000 + ( 1000 + 1 ) x 500 + ( 500 + 1 ) x 10 = 3578510. 

ZCA whitening なしの場合

こんなんなりました.まずは weight decay なし(lam = 0).

### 3-layer MLP: D = 3072 H1 = 1000 H2 = 500 K = 10
# eta = 0.01 mu = 0.9 lam = 0.0
# ZCAwhitening = False
### training: NL = 40000 NV = 10000 D = 3072 K = 10 batchsize = 100
0 | 2.3027 9.36 | 2.3027 9.41
1 | 1.7967 34.66 | 1.7972 34.04
2 | 1.5622 44.24 | 1.5862 42.62
3 | 1.4257 49.08 | 1.4857 47.06
4 | 1.3225 53.42 | 1.4292 49.09
5 | 1.2435 56.37 | 1.3900 51.28
10 | 0.9221 67.77 | 1.3732 53.59
20 | 0.4385 85.47 | 1.7446 53.17
30 | 0.1619 94.90 | 2.3985 53.69
40 | 0.0261 99.47 | 2.9823 54.96
50 | 0.0035 99.99 | 3.2838 55.50
60 | 0.0012 100.00 | 3.4778 55.63
70 | 0.0008 100.00 | 3.5901 55.55
80 | 0.0006 100.00 | 3.6705 55.63
90 | 0.0005 100.00 | 3.7348 55.67
100 | 0.0004 100.00 | 3.7928 55.68
# NT = 10000
100 | 0.0004 100.00 | 3.7928 55.68 | 3.7611 55.54

次は,weight decay あり(lam = 0.0001).

### 3-layer MLP: D = 3072 H1 = 1000 H2 = 500 K = 10
# eta = 0.01 mu = 0.9 lam = 0.0001
# ZCAwhitening = False
### training: NL = 40000 NV = 10000 D = 3072 K = 10 batchsize = 100
0 | 2.3027 9.36 | 2.3027 9.41
1 | 1.7974 34.60 | 1.7978 33.95
中略
90 | 0.0033 100.00 | 2.7006 55.86 100 | 0.0036 100.00 | 2.6680 55.75 # NT = 10000 100 | 0.0036 100.00 | 2.6680 55.75 | 2.6537 55.13

いずれもテストデータの識別率は 55% 程度.学習データの識別率は100%なので,明らかに過学習してますが,weight decay では改善できてません(lamを変えてもこれ以上よくならない).実行時間はこんな感じでした.

CPU times: user 57min 13s, sys: 1min 7s, total: 58min 21s
Wall time: 21min 28s

 

ZCA whitening ありの場合

## 3-layer MLP: D = 3072 H1 = 1000 H2 = 500 K = 10
# eta = 0.01 mu = 0.9 lam = 0.0
# ZCAwhitening = True
### training: NL = 40000 NV = 10000 D = 3072 K = 10 batchsize = 100
0 | 2.3031 9.94 | 2.3032 10.19
1 | 2.1869 25.70 | 2.2011 23.24
2 | 1.5107 48.72 | 1.7654 36.41
3 | 1.0585 64.44 | 1.6888 40.36
4 | 0.6105 82.54 | 1.8075 41.78
5 | 0.3166 91.19 | 2.1498 40.88
10 | 0.0530 98.65 | 3.3889 42.66
20 | 0.0008 100.00 | 3.7021 44.85
30 | 0.0004 100.00 | 3.8197 44.95
40 | 0.0003 100.00 | 3.8976 45.03
50 | 0.0002 100.00 | 3.9565 45.13
# NT = 10000
50 | 0.0002 100.00 | 3.9565 45.13 | 4.0324 45.21
### 3-layer MLP: D = 3072 H1 = 1000 H2 = 500 K = 10
# eta = 0.01 mu = 0.9 lam = 0.001
# ZCAwhitening = True
### training: NL = 40000 NV = 10000 D = 3072 K = 10 batchsize = 100
0 | 2.3031 9.94 | 2.3032 10.19
1 | 2.1957 24.76 | 2.2084 22.69
中略
40 | 0.0119 100.00 | 1.7912 48.39
50 | 0.0117 100.00 | 1.7642 48.25
# NT = 10000
50 | 0.0117 100.00 | 1.7642 48.25 | 1.7858 48.44

テスト識別率は 45% と 48%.ZCA whitening したら下がりました.

 

CNNでの実験

プログラムと実験条件

MLP の方にリンクを載せた cifar10.py と nnet0211.py に加えて,以下のプログラムを用いました.

実験条件は次の通り.

  • データの前処理,学習アルゴリズム,使用マシンについてはMLPの場合と同様.
  • CNNの構造は,入力-conv-pool-softmax と,入力-conv-pool-ReLu-softmax の二通り.
  • conv層は,3 x 32 x 32 の入力画像に対して,3 x 5 x 5 の大きさのカーネル16通りを用いて1画素ずつずらしながら畳み込み.出力は 16 x 28 x 28.活性化関数なし(恒等写像).
  • pool層は,max-pooling で縦横1/4ずつにサブサンプリングしてから ReLu.したがって,出力は 16 x 7 x 7.
  • pool層とsoftmax層の間に ReLu の層をはさむ場合,素子数は 400.全結合.

conv層-pool層のパラメータ数は 3 x 5 x 5 x 16 (conv層のカーネル)+ 16(pool層のReLuのしきい値) = 1216.したがって総パラメータ数は,

  • ReLu層なしの場合: 1216 + ( 16 x 7 x 7 + 1 ) x 10 = 9366
  • ReLu層ありの場合: 1216 + ( 16 x 7 x 7 + 1 ) x 400 + ( 400 + 1 ) x 10 = 13076

で,MLPの場合の数百分の一です.

 

入力-conv-pool-softmaxでの実験

MLPの実験と違い,weight decay ありの場合のみ示します.

### Conv-Pool-Softmax Xdim: (3, 32, 32)   ZCAwhitening = False
# W1dim: (16, 5, 5) ds1: (4, 4) H1: 784
# eta = 0.01 mu = 0.9 lam = 0.0001
### training: NL = 40000 NV = 10000 K = 10 batchsize = 100
0 | 2.3023 10.75 | 2.3023 10.73
1 | 1.5455 44.96 | 1.5535 45.25
中略
40 | 0.8878 68.97 | 1.0497 64.03
50 | 0.8809 69.32 | 1.0507 64.35
# NT = 10000
50 | 0.8809 69.32 | 1.0507 64.35 | 1.0576 63.96
### Conv-Pool-Softmax Xdim: (3, 32, 32)   ZCAwhitening = True
# W1dim: (16, 5, 5) ds1: (4, 4) H1: 784
# eta = 0.01 mu = 0.9 lam = 0.0001
### training: NL = 40000 NV = 10000 K = 10 batchsize = 100
0 | 2.3028 11.13 | 2.3029 11.27
1 | 1.2043 58.70 | 1.2461 57.55
中略
40 | 0.9053 69.26 | 1.1542 62.94
50 | 1.0432 66.20 | 1.2988 60.62
# NT = 10000
50 | 1.0432 66.20 | 1.2988 60.62 | 1.3321 60.35

学習が十分進んでない感じもしますが,時間がかかるので 50epoch で打ち切り.テスト識別率は60%前後.実行時間はこんな感じでした.

CPU times: user 1h 12min 40s, sys: 36.7 s, total: 1h 13min 16s
Wall time: 1h 11min 4s

CPU時間はMLPとおんなじくらいですが,以前も書いたように( Theano で Convolutional Neural Net - まんぼう日記 ),こちらは十分に並列計算できてません.そのせいで経過時間はずっと長くなってます.

 

入力-conv-pool-ReLu-softmaxでの実験

conv-pool層とsoftmax層の間に全結合のReLuの層を入れた場合.

### Conv-Pool-ReLu-Softmax Xdim: (3, 32, 32)   ZCAwhitening = False
# W1dim: (16, 5, 5) ds1: (4, 4) H1: 784
# H2: 400
# eta = 0.01 mu = 0.9 lam = 0.0001
### training: NL = 40000 NV = 10000 K = 10 batchsize = 100
0 | 2.3025 11.33 | 2.3025 10.87
1 | 1.8802 32.93 | 1.8785 32.64
2 | 1.4387 48.20 | 1.4554 47.75
3 | 1.3337 52.68 | 1.3583 51.25
4 | 1.2240 57.11 | 1.2665 55.33
5 | 1.1067 60.98 | 1.1688 59.32
10 | 0.7608 74.08 | 0.9680 66.30
20 | 0.3172 89.88 | 1.0812 67.93
30 | 0.0804 97.97 | 1.5256 68.38
40 | 0.0088 99.99 | 1.7002 69.25
50 | 0.0057 100.00 | 1.7633 69.36
# NT = 10000
50 | 0.0057 100.00 | 1.7633 69.36 | 1.7982 68.48
### Conv-Pool-ReLu-Softmax Xdim: (3, 32, 32)   ZCAwhitening =  True
# W1dim: (16, 5, 5) ds1: (4, 4) H1: 784
# H2: 400
# eta = 0.01 mu = 0.9 lam = 0.0001
### training: NL = 40000 NV = 10000 K = 10 batchsize = 100
0 | 2.3025 10.59 | 2.3025 10.91
1 | 1.6765 40.39 | 1.6914 40.48
中略
40 | 0.0019 100.00 | 1.7071 72.66
50 | 0.0018 100.00 | 1.6871 72.60
# NT = 10000
50 | 0.0018 100.00 | 1.6871 72.60 | 1.6953 72.29

テスト識別率は 68% と 72%.はじめて ZCA whitening ありの方がよくなりました.ReLu層を追加したにもかかわらず,所要時間は上記とかわらず.ほとんどconv-poolに費やしてるようです.

 

conv層を16チャンネルから64チャンネルにしてみる

上記は convolution カーネルが16種類の場合ですが,これを64種類に増やした場合も実験してみました.

### Conv-Pool-ReLu-Softmax Xdim: (3, 32, 32)
# W1dim: (64, 5, 5) ds1: (4, 4) H1: 3136
# H2: 400
# eta = 0.01 mu = 0.9 lam = 0.0001
# ZCAwhitening = False
### training: NL = 40000 NV = 10000 K = 10 batchsize = 100
0 | 2.3027 9.11 | 2.3027 9.14
1 | 1.7717 36.13 | 1.7709 35.87
中略
40 | 0.0059 100.00 | 1.4539 71.91
50 | 0.0046 100.00 | 1.4735 71.89
# NT = 10000
50 | 0.0046 100.00 | 1.4735 71.89 | 1.4518 71.86
### Conv-Pool-ReLu-Softmax Xdim: (3, 32, 32)
# W1dim: (64, 5, 5) ds1: (4, 4) H1: 3136
# H2: 400
# eta = 0.01 mu = 0.9 lam = 0.0001
# ZCAwhitening = True
### training: NL = 40000 NV = 10000 K = 10 batchsize = 100
0 | 2.3029 9.76 | 2.3029 9.59
1 | 1.4065 49.72 | 1.4206 49.19
中略
40 | 0.0016 100.00 | 1.3620 76.19
50 | 0.0015 100.00 | 1.3461 76.32
# NT = 10000
50 | 0.0015 100.00 | 1.3461 76.32 | 1.4353 74.97

テスト識別率 72% と 75% に上昇.conv-poolに実行時間を費やしてるだけあって,チャンネル数に比例して実行時間も4倍,4時間40分ほど.

 

上記がどの程度の性能なのかは以下でわかります.

 

convolution層の重みを可視化してみる

2015-02-20 追記: 以下の画像は,可視化の際にRGBとBGRの変換をできてなかったので,色味が変です.プログラムの方は正しく直してありますが,画像の方はおかしいままです.

 

まずは,conv層16チャンネルの場合.

(1) f:id:takatakamanbou:20150217221929p:plain

(2) f:id:takatakamanbou:20150217221931p:plain

(3) f:id:takatakamanbou:20150217221930p:plain

(4) f:id:takatakamanbou:20150217221932p:plain

(1) ReLu層なしZCAなし,(2) ReLu層なしZCAあり,(3) ありなし,(4) ありあり,です.ReLu層なしの場合は,「なんか無理してる」って感じがします(どんな考察や (^^;).ZCA whitening ありだと,入力の高周波成分が強調されてるせいでフィルタもより細かくなってるようです.

 

次は,conv層64チャンネルの場合.

(5) f:id:takatakamanbou:20150217221933p:plain

(6) f:id:takatakamanbou:20150217221934p:plain

(5) はZCAなし,(6) はあり.本質的には16チャンネルと変わらないようです.