10
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

機械学習におけるGPU memory error の呪いを解く方法 with Chainer

Last updated at Posted at 2018-11-12

※初投稿なのでご了承ください


「よーし完璧なプログラムが完成した!!」
「実行するぞーー!!!」


スクリーンショット 2018-07-09 16.18.11.png

OutOfMemoryError


「うぎゃっぱー!」(憤死)

はじめに

あなたが、画像や音楽を対象にしたデータを元に機械学習をしているならば、
時に大量のデータを使うこともあるでしょう。

使うのがCPUであれば、多少ビックなデータを使っていたって問題はありませんが、
それでは学習時間も非常に長くなってしまうことでしょう。

今回は、Chainerを用いて、莫大なデータを用いていてもGPUメモリーエラーになり難くなる秘策について説明いたします。

※私はそこまで強くないので、強い人たちの役には立ちません。


使用している環境

Chainer 5.0.0
Cupy 5.0.0

考え方

どの様にすれば、メモリーエラーにならないのでしょうか。

例えば、以下の様に、大量のデータを全て一度Cupyに変換すると、
メモリーエラーになりやすいのは自明です。

# dataをどっかから取ってき、説明変数Xと目的変数yに分ける。

# numpyの配列に変換する。
X_np = np.array(X,dtype='float32').reshape(-1,1,28,28)
y_np = np.array(y,dtype='int32').reshape(-1,1)

# cupyの配列に変換する
X_cp = cp.array(X,dtype='float32').reshape(-1,1,28,28)
y_cp = cp.array(y,dtype='int32').reshape(-1,1)

dataset=datasets.TupleDataset(X_cp, y_cp)
iterater = iterators.SerialIterator(dataset, batchsize)
classifier = L.Classifier(model)
# 最適化手法の選択
optimizer = optimizers.SGD(lr=0.01).setup(classifier)

# UpdaterにIteratorとOptimizerを渡す
updater = training.StandardUpdater(iterater, optimizer, device=-1)
max_epoch = 10
# TrainerにUpdaterを渡す
trainer = training.Trainer(
    updater, (max_epoch, 'epoch'), out='mnist_result')
trainer.run()

解決の糸口としては、一度に全てcupyに変換してから用いず、
処理中に部分的にcupyに変換させることです。

しかし、trainerを用いながらそれを行う方法はあるのでしょうか?

Updaterの力を使う方法

Updaterの引数を調節すれば、バッチサイズごとにnumpyをcupyに変換するのはとても簡単にできます。

Updaterの内部では、
chainer.dataset.concat_example(batch, device=None, padding=None)

が呼ばれますが,ここで、device >= 0とすればnumpyがGPUに送られ、自動的にcupyへ変換されます。
Updaterの引数の device とUpdater内で呼ばれる device には同じ値が入るので、

numpyでデータセットを作り
Updaterで device によりGPUを指定する

これをすればバッチサイズごとにcupyへ変換することができます。

# dataをどっかから取ってき、説明変数Xと目的変数yに分ける。

# numpyの配列に変換する。
X_np = np.array(X,dtype='float32').reshape(-1,1,28,28)
y_np = np.array(y,dtype='int32').reshape(-1,1)

'''#cupyの配列に変換しない'''
dataset=datasets.TupleDataset(X_np, y_np)
iterater = iterators.SerialIterator(dataset, batchsize)
classifier = L.Classifier(model)
# 最適化手法の選択
optimizer = optimizers.SGD(lr=0.01).setup(classifier)

# UpdaterにIteratorとOptimizerを渡す
''' diviceに使用するGPUを入れる。                                   ↓  ( ≠ -1)   '''
updater = training.StandardUpdater(iterater, optimizer, device = 1)
max_epoch = 10
# TrainerにUpdaterを渡す
trainer = training.Trainer(
    updater, (max_epoch, 'epoch'), out='mnist_result')
trainer.run()
10
13
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?