Я использую глубокую сеть CNN + LSTM для выполнения классификации на наборе данных 1D сигналов. Я использую keras 2.2.4
при поддержке tensorflow 1.12.0
. Поскольку у меня большой набор данных и ограниченные ресурсы, я использую генератор для загрузки данных в память на этапе обучения. Сначала я попробовал этот генератор:
def data_generator(batch_size, preproc, type, x, y):
num_examples = len(x)
examples = zip(x, y)
examples = sorted(examples, key = lambda x: x[0].shape[0])
end = num_examples - batch_size + 1
batches = [examples[i:i + batch_size] for i in range(0, end, batch_size)]
random.shuffle(batches)
while True:
for batch in batches:
x, y = zip(*batch)
yield preproc.process(x, y)
Используя вышеописанный метод, я могу начать тренировку с размером мини-партии до 30 образцов за раз. Однако этот вид методов не гарантирует, что сеть будет обучаться только один раз для каждой выборки за эпоху. Учитывая этот комментарий с сайта Кераса:
Sequence
- более безопасный способ многопроцессорной обработки. Эта структура
гарантирует, что сеть будет обучаться только один раз для каждого образца
эпоха, которая не относится к генераторам.
Я пробовал другой способ загрузки данных, используя следующий класс:
class Data_Gen(Sequence):
def __init__(self, batch_size, preproc, type, x_set, y_set):
self.x, self.y = np.array(x_set), np.array(y_set)
self.batch_size = batch_size
self.indices = np.arange(self.x.shape[0])
np.random.shuffle(self.indices)
self.type = type
self.preproc = preproc
def __len__(self):
# print(self.type + ' - len : ' + str(int(np.ceil(self.x.shape[0] / self.batch_size))))
return int(np.ceil(self.x.shape[0] / self.batch_size))
def __getitem__(self, idx):
inds = self.indices[idx * self.batch_size:(idx + 1) * self.batch_size]
batch_x = self.x[inds]
batch_y = self.y[inds]
return self.preproc.process(batch_x, batch_y)
def on_epoch_end(self):
np.random.shuffle(self.indices)
Я могу подтвердить, что при использовании этого метода сеть обучается один раз для каждой выборки за эпоху, но на этот раз, когда я поместил более 7 выборок в мини-пакет, я обнаружил ошибку нехватки памяти:
Ошибка OP_REQUIRES в random_op.cc: 202: Ресурс исчерпан: OOM, когда
выделение тензора с формой ...............
Я могу подтвердить, что для этого теста я использую ту же архитектуру, конфигурацию и машину модели. Мне интересно, почему будет разница между этими двумя способами загрузки данных?
Пожалуйста, не стесняйтесь спрашивать более подробную информацию в случае необходимости.
Спасибо заранее.
РЕДАКТИРОВАНИЕ:
Вот код, который я использую для соответствия модели:
reduce_lr = keras.callbacks.ReduceLROnPlateau(
factor=0.1,
patience=2,
min_lr=params["learning_rate"])
checkpointer = keras.callbacks.ModelCheckpoint(
filepath=str(get_filename_for_saving(save_dir)),
save_best_only=False)
batch_size = params.get("batch_size", 32)
path = './logs/run-{0}'.format(datetime.now().strftime("%b %d %Y %H:%M:%S"))
tensorboard = keras.callbacks.TensorBoard(log_dir=path, histogram_freq=0,
write_graph=True, write_images=False)
if index == 0:
print(model.summary())
print("Model memory needed for batchsize {0} : {1} Gb".format(batch_size, get_model_memory_usage(batch_size, model)))
if params.get("generator", False):
train_gen = load.data_generator(batch_size, preproc, 'Train', *train)
dev_gen = load.data_generator(batch_size, preproc, 'Dev', *dev)
valid_metrics = Metrics(dev_gen, len(dev[0]) // batch_size, batch_size)
model.fit_generator(
train_gen,
steps_per_epoch=len(train[0]) / batch_size + 1 if len(train[0]) % batch_size != 0 else len(train[0]) // batch_size,
epochs=MAX_EPOCHS,
validation_data=dev_gen,
validation_steps=len(dev[0]) / batch_size + 1 if len(dev[0]) % batch_size != 0 else len(dev[0]) // batch_size,
callbacks=[valid_metrics, MyCallback(), checkpointer, reduce_lr, tensorboard])
# train_gen = load.Data_Gen(batch_size, preproc, 'Train', *train)
# dev_gen = load.Data_Gen(batch_size, preproc, 'Dev', *dev)
# model.fit_generator(
# train_gen,
# epochs=MAX_EPOCHS,
# validation_data=dev_gen,
# callbacks=[valid_metrics, MyCallback(), checkpointer, reduce_lr, tensorboard])