Keras & Tensorflow GPU не хватает памяти для больших данных изображения - PullRequest
0 голосов
/ 20 мая 2018

Я создаю систему классификации изображений с использованием Keras, серверной части Tensorflow GPU и CUDA 9.1, работающей на Ubuntu 18.04.

Я использую очень большой набор данных изображений с 1,2 миллионами изображений, 15k классов,и имеет размер 335 ГБ.

Я могу обучить свою сеть на 90 000 изображений без проблем.Однако, когда я масштабирую и использую весь набор данных из 1,2 миллиона изображений, я получаю ошибку, показанную ниже, которая, я думаю, связана с нехваткой памяти.

Я использую GeForce GTX 1080 с 11 ГБпамяти, и у меня 128 ГБ ОЗУ, 300 ГБ файла подкачки и AMD Threadripper 1950X с 16 ядрами.

Я следовал советам, данным для решения подобных проблем.Сейчас я использую меньший размер пакета 10 или , даже меньший , и меньший плотный внутренний слой из 256, и я все еще получаю ту же ошибкупоказано ниже до начала первой эпохи обучения.

[Обновление]: Я обнаружил, что ошибка памяти происходит во время вызова VGG16 predict_generator, даже до того, как моя сеть построена или обучена.См. Код ниже.

Сначала предупреждения и ошибки:

2018-05-19 20:24:01.255788: E tensorflow/stream_executor/cuda/cuda_driver.cc:967] failed to alloc 5635855360 bytes on host: CUresult(304)
2018-05-19 20:24:01.255850: W ./tensorflow/core/common_runtime/gpu/pool_allocator.h:195] could not allocate pinned host memory of size: 5635855360

Тогда исключения:

2018-05-19 13:56:40.472404: I tensorflow/core/common_runtime/bfc_allocator.cc:680] Stats: 
Limit:                 68719476736
InUse:                 15548829696
MaxInUse:              15548829696
NumAllocs:                   15542
MaxAllocSize:             16777216

2018-05-19 13:56:40.472563: W tensorflow/core/common_runtime/bfc_allocator.cc:279] ****************************************************************************************************
Traceback (most recent call last):
  File "/home/welshamy/tools/anaconda/3/lib/python3.6/site-packages/tensorflow/python/client/session.py", line 1322, in _do_call
    return fn(*args)
  File "/home/welshamy/tools/anaconda/3/lib/python3.6/site-packages/tensorflow/python/client/session.py", line 1307, in _run_fn
    options, feed_dict, fetch_list, target_list, run_metadata)
  File "/home/welshamy/tools/anaconda/3/lib/python3.6/site-packages/tensorflow/python/client/session.py", line 1409, in _call_tf_sessionrun
    run_metadata)
tensorflow.python.framework.errors_impl.InternalError: Dst tensor is not initialized.
     [[Node: block5_pool/MaxPool/_159 = _Recv[client_terminated=false, recv_device="/job:localhost/replica:0/task:0/device:CPU:0", send_device="/job:localhost/replica:0/task:0/device:GPU:0", send_device_incarnation=1, tensor_name="edge_133_block5_pool/MaxPool", tensor_type=DT_FLOAT, _device="/job:localhost/replica:0/task:0/device:CPU:0"]()]]

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "bottleneck.py", line 37, in <module>
    bottleneck_features_train = model_vgg.predict_generator(train_generator_bottleneck)
  File "/home/welshamy/tools/anaconda/3/lib/python3.6/site-packages/keras/legacy/interfaces.py", line 91, in wrapper
    return func(*args, **kwargs)
  File "/home/welshamy/tools/anaconda/3/lib/python3.6/site-packages/keras/engine/training.py", line 2510, in predict_generator
    outs = self.predict_on_batch(x)
  File "/home/welshamy/tools/anaconda/3/lib/python3.6/site-packages/keras/engine/training.py", line 1945, in predict_on_batch
    outputs = self.predict_function(ins)
  File "/home/welshamy/tools/anaconda/3/lib/python3.6/site-packages/keras/backend/tensorflow_backend.py", line 2478, in __call__
    **self.session_kwargs)
  File "/home/welshamy/tools/anaconda/3/lib/python3.6/site-packages/tensorflow/python/client/session.py", line 900, in run
    run_metadata_ptr)
  File "/home/welshamy/tools/anaconda/3/lib/python3.6/site-packages/tensorflow/python/client/session.py", line 1135, in _run
    feed_dict_tensor, options, run_metadata)
  File "/home/welshamy/tools/anaconda/3/lib/python3.6/site-packages/tensorflow/python/client/session.py", line 1316, in _do_run
    run_metadata)
  File "/home/welshamy/tools/anaconda/3/lib/python3.6/site-packages/tensorflow/python/client/session.py", line 1335, in _do_call
    raise type(e)(node_def, op, message)
tensorflow.python.framework.errors_impl.InternalError: Dst tensor is not initialized.
     [[Node: block5_pool/MaxPool/_159 = _Recv[client_terminated=false, recv_device="/job:localhost/replica:0/task:0/device:CPU:0", send_device="/job:localhost/replica:0/task:0/device:GPU:0", send_device_incarnation=1, tensor_name="edge_133_block5_pool/MaxPool", tensor_type=DT_FLOAT, _device="/job:localhost/replica:0/task:0/device:CPU:0"]()]]

Вот мой код:

import numpy as np
from keras.callbacks import EarlyStopping, ModelCheckpoint
from keras.layers import Dropout, Flatten, Dense
from keras.models import Sequential
from keras.preprocessing.image import ImageDataGenerator
from keras import applications
from keras.utils.np_utils import to_categorical
import matplotlib.pyplot as plt

# Dimensions of our images.
img_width, img_height = 224, 224

train_data_dir = './train_sample'

epochs = 100
batch_size = 10

# Data preprocessing
# Pixel values rescaling from [0, 255] to [0, 1] interval
datagen = ImageDataGenerator(rescale=1. / 255)

# Retrieve images and their classes for training set.
train_generator_bottleneck = datagen.flow_from_directory(
    train_data_dir,
    target_size=(img_width, img_height),
    batch_size=batch_size,
    class_mode=None,
    shuffle=False)


num_classes = len(train_generator_bottleneck.class_indices)

model_vgg = applications.VGG16(include_top=False, weights='imagenet')

bottleneck_features_train = model_vgg.predict_generator(train_generator_bottleneck)
np.save('../models/bottleneck_features_train.npy', bottleneck_features_train)

train_data = np.load('../models/bottleneck_features_train.npy')
train_labels = to_categorical(train_generator_bottleneck.classes, num_classes=num_classes)


model_top = Sequential()
model_top.add(Flatten(input_shape=train_data.shape[1:]))
model_top.add(Dense(256, activation='relu'))
model_top.add(Dropout(0.5))
model_top.add(Dense(num_classes, activation='softmax'))

model_top.compile(loss='categorical_crossentropy',
                  optimizer='rmsprop',
                  metrics=['accuracy'])

# Model saving callback
checkpointer = ModelCheckpoint(filepath='../models/bottleneck_features.h5', monitor='val_acc', verbose=1,
                               save_best_only=True)

# Early stopping
early_stopping = EarlyStopping(monitor='val_acc', verbose=1, patience=5)

history = model_top.fit(
    train_data,
    train_labels,
    verbose=2,
    epochs=epochs,
    batch_size=batch_size,
    callbacks=[checkpointer, early_stopping],
    validation_split=0.3)

1 Ответ

0 голосов
/ 20 мая 2018

Я не верю, что проблема здесь в batch_size, как вы уже упоминали, она настолько мала.Кроме того, поскольку вы сказали, что он работает с изображениями размером 90 тыс., Проблема, вероятно, заключается в том, что train_data не может уместиться на GPU в памяти (что необходимо в начале каждой эпохи подгонки).Чтобы решить эту проблему, вам нужно снабдить свой model_top generator, так же как вы получаете свои функции от predict_generator.Один из способов сделать это - обернуть класс генератора вокруг train_data, но вместо этого я бы просто соединил две модели (заметьте, я не смог проверить это, но я думаю, что это правильно):

model_vgg = applications.VGG16(include_top=False, weights='imagenet')

model_top = Flatten()(model_vgg)
model_top = Dense(256, activation='relu')(model_top)
model_top = Dropout(0.3)(model_top)
model_top = Dense(num_classes, activation='softmax')(model_top)

model = Model(inputs=model_vgg.inputs, outputs=model_top)

model.compile(loss='sparse_categorical_crossentropy',
                  optimizer='rmsprop',
                  metrics=['accuracy'])

# Model saving callback
checkpointer = ModelCheckpoint(filepath='../models/bottleneck_features.h5', monitor='val_acc', verbose=1,
                               save_best_only=True)

# Early stopping
early_stopping = EarlyStopping(monitor='val_acc', verbose=1, patience=5)

history = model.fit_generator(
    train_data,
    train_labels,
    verbose=2,
    steps_per_epoch=steps_per_epoch,
    batch_size=batch_size,
    callbacks=[checkpointer, early_stopping],
    ...)

Я изменил categorical_crossentropy на sparse_categorical_crossentropy, чтобы в качестве меток можно было отправлять только индексы, в противном случае то же самое.Вам нужно будет указать steps_per_epoch как длину обучающих данных / размер пакета.Или просто введите любой номер для проверки.Я также использовал функциональный API-интерфейс keras, чтобы сделать это более ясным.

Это также позволило бы изменить вес вершины VGG, чтобы помочь вам лучше классифицировать.Если по какой-то причине это не то, что вам нужно, вы можете заморозить его, пройдя по всем слоям vgg и установив для trainable значение false.

lmk, если это работает.

...