読者です 読者をやめる 読者になる 読者になる

まんぼう日記

takataka's diary

Theano 0.8.0rc1(または,ignore_border は True にしよう)

Theano 0.8.0rc1 が出てますね:

https://groups.google.com/forum/#!topic/theano-dev/gAu5NTrxr48

rc1 つまり release candidate その1ですから,まだ 0.8.0 の正式リリースではありませんが,待てないのでインストールして使ってみました.GPGPU用マシンに Ubuntu をインストールして Theano を使えるようにする - まんぼう日記 で Ubuntu + Theano 0.7 を使えるようにした PC が対象です.

 

変なタイトルの理由は後半で明らかになります.

 

 

Theano 0.8.0rc1 をインストール

Installing Theano — Theano 0.7 documentation を参考に.Theano 0.7 をインストールする際は,依存関係で諸々インストールしました.それらはそのままで大丈夫なようです.特に 0.8.0rc1 のために新たに追加するものはありませんでした.というわけで,インストール作業はこれだけ

$ git clone git://github.com/Theano/Theano.git
$ cd Theano
$ sudo python setup.py develop

インストールしたマシンの環境では,これで /usr/local/lib/python2.7/dist-packages 以下に必要なファイルがインストールされました.環境変数 PYTHONPATH を特に設定しなくても大丈夫.

$ python
Python 2.7.6 (default, Jun 22 2015, 17:58:13)
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import theano
>>> theano.version.full_version
'0.8.0rc1.dev-2fe88f363944cee9f189ab03c735a49795359005'

こんな感じです.

 

Theano 0.8.0rc1 を使う(または,ignore_border は True にしよう)

Theano のバージョンアップとくれば,たかたか的最大関心事は次の二点です.

  1. overlap ありの pooling は高速か?
  2. stride が 1 より大きい convolution は高速か?

ここでは 1. の方を確認してみます.先に結論を言うと,「yes,ただしちょっと条件がある」です.最後まで読むとわかりますが,「ignore_border は True にしよう」です.

 

問題は,Theano 0.7 の max_pool_2d

downsample – Down-Sampling — Theano 0.7 documentation

で st を指定して overlap ありの pooling をやろうとすると,GPUの使用率が極端に下がって実行が非常に遅くなってしまう,というものでした.

 

確認のため,さっそく ex150823.py & ex150823b.py · GitHub の ex150823b.py というプログラム(詳細は Convolutional Neural Net で CIFAR-10 を識別してみる - まんぼう日記 へどうぞ)を動かしてみたら,こうなりました…

 

(1) max_pool_2d で ds = 2, st = None とした場合(この場合,ds = st となって overlap なしの max-pooling をすることになります):

$ time THEANO_FLAGS='floatX=float32,device=gpu0' python ex150823b.py
/home/takataka/.../Theano/theano/tensor/signal/downsample.py:6: UserWarning: downsample module has been moved to the theano.tensor.signal.pool module.
  "downsample module has been moved to the theano.tensor.signal.pool module.")
Using gpu device 0: GeForce GTX TITAN X (CNMeM is disabled, CuDNN 3007)
### ID:  20160316-125758
##### CIFAR-10 #####
# label_names = ['airplane', 'automobile', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck']
# num_vis =  3072
### Conv-Pool-Conv-Pool-ReLu-Softmax   Xdim: (3, 24, 24)
#   W1dim: (64, 5, 5)  ds1: (2, 2)  st1: None  border_mode: full  H1: 12544
#   W2dim: (64, 5, 5)  ds2: (2, 2)  st2: None  border_mode: full  H2: 5184
#   H3: 1000
# eta =  0.01  mu =  0.9  lam =  0.0001
# ZCAwhitening =  True  tfunc =  translate2  dstshape =  (24, 24)
### training:   NL =  40000  NV =  10000  K =  10  batchsize =  100
0 | 2.3027 9.63 | 2.3027 9.55
(中略)
50 | 0.1546 94.86 | 0.5764 82.28 | 0.5942 81.96
### ID:  20160316-125758

real    8m20.088s
user    13m53.856s
sys    2m14.476s

この条件では,以前と同様 GPU をちゃんと使って高速に実行されてます.「theano.tensor.signal.downsample は theano.tensor.signal.pool に変わったよ」って警告が出てますが,今回の実験には実質的に影響ないようなので放置.後日直すことにします.また,「CNMeM is disabled, CuDNN 3007」も気になりますが,こちらもとりあえず調査は後回し.cuDNN のバージョン上げたらちょっと速くなったりするかもね.

 

 (2) ds = 3, st = 2 とした場合(overlap あり):

   :
### Conv-Pool-Conv-Pool-ReLu-Softmax   Xdim: (3, 24, 24)
#   W1dim: (64, 5, 5)  ds1: (3, 3)  st1: (2, 2)  border_mode: full  H1: 12544
#   W2dim: (64, 5, 5)  ds2: (3, 3)  st2: (2, 2)  border_mode: full  H2: 5184
   :
50 | 0.1665 94.49 | 0.6104 81.42 | 0.6392 81.14

real    35m25.760s
user    40m43.656s
sys    2m19.700s

GPUの稼働率は20%程度まで落ちました (;_;)

 

なんやあかんかぁ,と落ち込みかけましたが,上記の警告のことを調べるために Theano の該当部分のプログラム( Theano/pool.py at master · Theano/Theano · GitHub )を見てたら,こんな記述を発見.

"pool_2d() will have the parameter ignore_border"
" default value changed to True (currently"
" False). To have consistent behavior with all Theano"
" version, explicitly add the parameter ignore_border=True."
" On the GPU, using ignore_border=True is needed to use CuDNN."
" When using ignore_border=False and not using CuDNN, the only"
" GPU combination supported is when"
" `ds == st and padding == (0, 0) and mode == 'max'`."
" Otherwise, the convolution will be executed on CPU.", 

 自分のプログラム( convnet150821.py · GitHub )を確認したら,ignore_border = False にしてます.なるほど,その場合は ds != st やと GPU 使ってくれへんわけね.そら遅いわな.というわけで…

 

(3) ignore_border = True にして他は (2) と同条件:

### Conv-Pool-Conv-Pool-ReLu-Softmax   Xdim: (3, 24, 24)
#   W1dim: (64, 5, 5)  ds1: (3, 3)  st1: (2, 2)  border_mode: full  H1: 10816
#   W2dim: (64, 5, 5)  ds2: (3, 3)  st2: (2, 2)  border_mode: full  H2: 4096
   :
50 | 0.1656 94.33 | 0.6288 81.10 | 0.6742 80.39

real    7m53.385s
user    13m31.556s
sys    2m11.076s

おお,ちゃんと GPU がんがん使って高速に計算してくれました.ignore_border を切り替えたせいで(1),(2)と全く同じ実験条件にはなっていない(pool層の出力ユニットの数が少なくなってる)点に要注意ですが.

 

...(-_-;

 

ちゅーことは,Theano 0.8.0rc1 にしたおかげやのうて,前からから ignore_border = True にしといたらよかったってことかいな….

 

そんなこんなで,とりあえず Theano 0.8.0rc1 使えるようになりました.ついでに overlap ありの pooling も高速にできることがわかりました.…まあここは喜んでおこう \(^^)/