まんぼう日記

takataka's diary

Dropout を実装する (2)

おとといの夜に腰をぎっくりやってまいました.昨日の朝なんて,しばらくソファに座ってたら立ち上がれへんようんなって,しばらく四つん這いでうろうろ…痛み止め飲んで半日ベッドでうなってました (-_-;   原因はさっぱり不明.毎日のようにてくてく歩いて体動かしてんのにこの体たらく,やぱし歳には勝てへんのですかねぇ.で,今日はだいぶましやったんで,大学行ってちょっとだけ仕事.帰りはリハビリのためてくてく遠回りしてみました.

 

というわけで,ちょこっとだけそん時撮った洗堰の写真,それから Dropout を実装する - まんぼう日記 のつづきの話です.

 

 

 

 

洗堰全開放流中

先日の台風のためか,ここ数日の瀬田川洗堰は全開放流中です.いつもの場所は…

f:id:takatakamanbou:20150913171421j:plain f:id:takatakamanbou:20150913171424j:plain

こんなんなってました.たとえば X登校プチ15km 波穂神社 源内道 - まんぼう日記 の同じ場所の写真と見比べると増水っぷりがわかります.

 

それから,橋の工事現場の方はこんなん.

f:id:takatakamanbou:20150913171423j:plain

左岸の橋台(?)らしきところは工事が進んでますが,橋の上部工は今年度第4四半期からという話やし( cf.  大石東バイパスとTheanoでGPGPU - まんぼう日記 )まだ動きはないですね.そのうち両岸に巨大な塔が建ちワイアが張られて…てなことになるみたいです.わくわく.

 

f:id:takatakamanbou:20150913171426j:plain f:id:takatakamanbou:20150913171427j:plain

f:id:takatakamanbou:20150913171428j:plain

そして,全開放流中の洗堰.もじゃさんもいました.全開 法隆寺 放流時の写真をもっと見たいという 変なひと 好奇心旺盛なひとはこちらもどうぞ:Denoising Autoencoder の実験をしてみる - まんぼう日記全開放流をとるか授業をとるか - まんぼう日記

 

 

Convolutional Neural Network で dropout

Convolutional Neural Net で CIFAR-10 を識別してみる - まんぼう日記 と Dropout を実装する - まんぼう日記 のつづきです.Convolutional Neural Net(以下CNN) でも dropout できるようにして,CIFAR-10 を使って実験してみました.以下にその結果を示しますが,実験手順がいいかげんなので,鵜呑みにしてはいけません.ちゃんとしたことは,上記「Dropoutを〜」のリンク先の論文みたいにちゃんと査読を経て出版されてる学術論文で確認してね.

 

実験条件

データについては,上記「Convolutional Neural Net で〜」参照.32 x 32 の画像からランダムに 24 x 24 の領域を切り出して使います.CNNの構造は次の通り.L0とかL1とかいうのは各層に適当につけた名前です.

  • L0: 入力層.3 x 24 x 24
  • L1: Convolution + Max Pooling
    • Conv層のカーネルサイズは 3 x 5 x 5, チャンネル(マップ)数は 128.
    • Poolingのサイズは 2 x 2. overlap なし.
  • L2: Convolution + Max Pooling.L1 と同様.
  • L3: Full Connection Layer.ニューロン数 1000,活性化関数は Rectified Linear.
  • L4: Full Connection Layer.L3 と同様.
  • L5: Softmax.  10クラス識別なので出力は10個.

 もっと詳しい条件は以下のリンク先のプログラムソースを参照してください.

https://gist.github.com/takatakamanbou/d43a8cff1840ab118f4f

 

そうそう,これまでのプログラムでは,Conv層につづいて Pool層がある場合,Conv層には活性化関数を適用せず,Pool層の出力をReLuに通すようにしてました(Pool層には max-pooling しか使ってないからそれで等価やったし,そっちの方が計算コスト的に有利と考えたので).でも,今回は dropout の適用の仕方次第で振る舞いが違っちゃうので,世間で一般的なように,Conv層出力を ReLu に通してから max-pooling するようにしてます.

 

学習は慣性項つき Stochastic Gradient Descent.weight decay(重みの L2-norm 正則化)や dropout の効果を調べるため,weight decay のみ適用,dropoutのみ適用,どちらもなし,の3通りで試してみました.

 

実験結果

まずは dropout も weight decay もなしの場合.

Using gpu device 0: Tesla K20c
### ID:  20150912-172131
##### CIFAR-10 #####
# label_names = ['airplane', 'automobile', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck']
# num_vis =  3072
### Conv-Pool-Conv-Pool-ReLu-ReLu-Softmax
# T4InputLayer:  (3, 24, 24)  dropout =  1.0
# ConvLayer:     (128, 3, 5, 5)  bmode =  full  dropout =  1.0
# PoolLayer:     (128, 14, 14)  ds =  (2, 2)  st =  None  dropout =  1.0
# ConvLayer:     (128, 128, 5, 5)  bmode =  full  dropout =  1.0
# PoolLayer:     (128, 9, 9)  ds =  (2, 2)  st =  None  dropout =  1.0
# FullLayer:     10368 1000 ReLu 1.0
# FullLayer:     1000 1000 ReLu 1.0
# FullLayer:     1000 10 linear 1.0
# eta =  0.01  mu =  0.95  lam =  0.0
# ZCAwhitening =  True  tfunc =  translate2  dstshape =  (24, 24)
### training:   NL =  40000  NV =  10000  K =  10  batchsize =  100
:
50 | 0.0790 97.42 | 0.6149 83.34 | 0.6480 82.89  |  [ 0.0148371   0.00211165  0.0003524   0.00057952  0.00660201]
100 | 0.0262 99.12 | 0.7764 83.45 | 0.8078 83.26  |  [ 0.02083785  0.00345156  0.00058295  0.00119557  0.00884546]
150 | 0.0199 99.35 | 0.8911 83.57 | 0.9465 82.97  |  [ 0.02439553  0.00449025  0.00077586  0.001761    0.00948193]
200 | 0.0173 99.46 | 0.9380 83.39 | 1.0750 83.03
epoch        rr(L)          rr(V)          rr(T)

real    164m2.976s
user    144m7.975s
sys    27m28.293s

rrが正識別率(Lは学習データ,Vは検査データ,Tはテストデータに対するもの)です.右の方の [] 内の値は,L1 から L5 までの層毎の \( \sum||\mathbf{w}||^2 \) の値(バイアス項除く).テスト識別率は約 83% という結果になりました.

 

次は,上記と同じ条件で weight decay を適用した場合.

### ID:  20150913-082243
# eta =  0.01  mu =  0.95  lam =  0.001
50 | 0.2624 91.42 | 0.5271 82.29 | 0.5558 81.19  |  [  5.94817102e-03   4.98104375e-04   5.39046268e-05   6.28500493e-05   3.33240232e-03]
100 | 0.2247 92.66 | 0.5328 81.96 | 0.5666 81.73  |  [  6.50912290e-03   5.22333838e-04   6.09863964e-05   6.87078282e-05   3.80479079e-03]
150 | 0.2044 93.31 | 0.5163 82.53 | 0.5269 82.43  |  [  6.72965217e-03   5.31386351e-04   6.27811678e-05   7.02735124e-05   3.91292525e-03]
200 | 0.1870 93.84 | 0.5129 82.92 | 0.5276 83.03
### ID:  20150913-110837
# eta =  0.01  mu =  0.95  lam =  0.0001
50 | 0.1054 96.45 | 0.6010 82.66 | 0.6376 82.16  |  [ 0.01270547  0.00158029  0.00023854  0.00035376  0.00533099]
100 | 0.0350 98.89 | 0.6607 84.39 | 0.7276 82.61  |  [ 0.01575197  0.00195524  0.00029775  0.0005022   0.00669031]
150 | 0.0287 99.10 | 0.6791 83.89 | 0.7080 83.44  |  [ 0.01677389  0.00197238  0.00030139  0.00053334  0.00732648]
200 | 0.0216 99.31 | 0.6991 84.45 | 0.7259 83.59

IDってのは自分の管理用につけてるだけなので気にしないでください.上の方( lam = 0.001 )は正則化強すぎ.下の方はちょっとだけテスト識別率が上昇してます(83.59%).

 

最後に,dropout を適用した場合.dropout の詳しい条件は後述します.

### ID:  20150912-200820
# eta =  0.01  mu =  0.95  lam =  0.0
50 | 0.3460 88.32 | 0.4960 82.92 | 0.5145 82.45  |  [ 0.0153383   0.00189471  0.00028935  0.00049283  0.00982334]
100 | 0.1956 94.36 | 0.4257 85.47 | 0.4445 85.26  |  [ 0.02261197  0.00355836  0.00052768  0.00090855  0.01174919]
150 | 0.1476 96.47 | 0.4125 85.74 | 0.4330 85.51  |  [ 0.02742649  0.00501165  0.00075703  0.0013123   0.01207088]
200 | 0.1181 97.38 | 0.4152 86.39 | 0.4318 85.72

何通りか試して一番良かったのだけ示してるのでずるいんですが,85% を超える結果となりました.

 

dropout の条件あれこれ

上記の結果を得た dropout の条件は次の通りです(条件「ほげ」と呼びます).

  • Conv-Pool 層では Pool 層の出力を dropout
  • 各層の出力ニューロンが生き残る確率は次の通り: L0 = L1 = L2 = 0.8, L3 = L4 = 0.5 

Conv-Pool の層では,Conv 側の出力を dropout させてそれに対して pooling,ってのもやってみましたが,上記のように pooling してから dropout するのと変わらないようでした.dropout の確率については,あれこれ試してみるとこんな感じでした.

  • L0 = 0.8, L1 = L2 = L3 = L4 = 0.5 だと学習の進みが「ほげ」よりもさらに遅く,テスト識別率は少し悪くなって 85% 前後
  • L0 = 0.8, L1 = L2 = 1.0, L3 = L4 = 0.5  (Conv-Poolでは dropout なし)は「ほげ」とほぼ同じ結果
  • L0 = L1 = L2 = 1.0, L3 = L4 = 0.5 (全結合層のみ dropout)だと 84.5% ほど
  • L0 = 0.8, L1 = L2 = L3 = L4 = 1.0 (入力のみ dropout,つまり入力にノイズを入れるのと同じ)だと dropout なしとほぼ同じ 

確率 P で dropout させると実効的なパラメータ数がおよそ P 倍になるわけで,この結果は,全結合層は冗長度が高いので P = 0.5 でよいが,Conv 層はそれほどでもないので P を少し大きめにした方が良い結果となった,と解釈したらよいのかもしれません.

 

さて,ひととおり技を身につけたので,次は ILSVRC 2010(画像認識の大規模データセット,1000カテゴリで学習画像120万枚)とかで実験やってみますかね.