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

ResourceExhaustedErrorの原因

TensorFlowで学習していると、訓練データ数が大きい場合、たまにResourceExhaustedErrorが出る。 Windows 10では、以下の内容が表示される。

ResourceExhaustedError (see above for traceback): OOM when allocating tensor with shape[37800,32,28,28] 
[[Node: Conv2D = Conv2D[T=DT_FLOAT, data_format="NHWC", padding="SAME", strides=[1, 1, 1, 1], 
use_cudnn_on_gpu=true, _device="/job:localhost/replica:0/task:0/gpu:0"](Reshape, Variable/read)]]

注目すべきは[37800,32,28,28]の部分。 順にバッチ数、チャンネル数、画像の縦のピクセル数、画像の横のピクセル数を表している。 これらの積(37800x32x28x28=948326400、単位はbyteではない)がメモリーの許容サイズを超えたためエラーが起きてるのだが、 今回はバッチ数(37800)が大き過ぎることにより、ResourceExhaustedErrorが発生している。

以下のように、僕の環境では、バッチ数(n_batch)は、訓練データ数(n_record)とバッチ率(batch_rate)をかけて決定している。 そのため、訓練データ数が大きい場合は、バッチ率を小さくする必要があったのにしていなかったため、エラーが発生していた。 もしくはバッチ数をエラーが出ない固定値に設定する必要があった。

n_batch = int(n_record*batch_rate)
for start in range(0, n_record, n_batch):
    end = start + n_batch
    sess.run(train_step, feed_dict={X: train_data[start:end], Y_: train_label[start:end]})

TensorFlowのMNISTのチュートリアルでは、 以下のようにバッチ数を50に固定している。 ただし、訓練データ数が少ないMNISTだから50で良いが、訓練データ数が非常に大きいデータの場合は、 学習に時間がかかりすぎる場合がある。 そのため、やはりバッチ率を指定するなどにより、訓練データ数に合わせてバッチ数の調整が必要である。 また、run()だけでなくeval()に渡すバッチ数も調整する必要がある。

for i in range(20000):
    batch = mnist.train.next_batch(50)
    if i % 100 == 0:
        train_accuracy = accuracy.eval(feed_dict={x: batch[0], y_: batch[1], keep_prob: 1.0})
        print("step %d, training accuracy %g" % (i, train_accuracy))
    train_step.run(feed_dict={x: batch[0], y_: batch[1], keep_prob: 0.5})

参考文献