備忘録とか日常とか

機械学習を勉強中。ベース日々練習中。

theanoでGPU使ったときに出るMemoryErrorを回避

thenaoでDeep learningを勉強中。Tutorialを読みつつ色々いじっている。
今回はGPUを使用しているときにMemoryErrorに遭遇したので、それの回避方法をメモしておく。参考元はここ
【追記】
データセットgpuのメモリに載せる時点でのエラーを回避するだけで、ネットワーク構造が大きすぎることによるエラーは解決できないのであしからず


そもそもtutorialで用意されているmnistとか手軽に使えるcifar10とかのデータセットならMemoryErrorは起きにくい(batch_sizeを大きくしすぎるとなるかも)。cifar10でも32*32のRGB画像がtraining用で5万枚とかなので、学習とテストを別々に行えばGPUメモリ容量は足りるはずである。しかし少し大きい画像サイズのデータセット使おうとするとすぐメモリ不足になり学習すらできなくなる。これではさっぱり役に立たない。。GPUには仮想メモリがないことが原因とかなんとか(詳しいことはわからないので調べてみてください)。


実際にやってみるとこんな感じになる。
適当にtheano.sharedにtrainingデータを入れる。

import theano
import numpy as np
train_set = theano.shared(data, borrow=True)  # dataを共有変数にいれる

で、実行すると

Error allocating 2998320000 bytes of device memory (out of memory). Driver report 2247553024 bytes free and 3212603392 bytes total
....
MemoryError: ('Error allocating 2998320000 bytes of device memory (out of memory).', "you might consider using 'theano.shared(..., borrow=True)'")

みたいなのが出る。当然数字は環境によって違う。共有変数をborrow=Trueとしてメモリを節約するように促してくるが、そもそもメモリ量が足りてないので意味がない。


そこで以下のように書き換えることで解決する。

train_set = theano.tensor._shared(data, borrow=True)

こうすることで変数を強制的にCPUのメモリに格納できるようになるらしい。となると速度が遅くなると思われるが、比較してないのでどれくらい速さが変わるかはわからない...。しかし畳みこみ等の計算部分をGPUに任せていれば劇的に遅くなることはない。これによって大容量のデータセットでも問題なく学習させることができる。


余談ですが、theano.sharedに代入した後の部分のバグによってプログラムが止まると、共有変数分のメモリ容量が食われたままっぽい? コンソール開いて一回目だと実行できるのに二回目以降にMemoryErrorが出たりすることが多々あったので。プログラムが最後まで実行できるとこの現象は起きない。デバッグ中にMemoryErrorが出てどうしてもエラーが消えないときは新しいコンソールで実行したら直るかも。


そのうち速度比較の実験でもしてみます。