Почему вызов соответствия Tensorflow с генератором проверки использует те же образцы? - PullRequest
1 голос
/ 04 мая 2020

Я пытаюсь установить NN для некоторых данных, которые я передаю в мою модель с генераторами. Я использую генераторы как для поезда, так и для проверочных образцов. Я ожидал, что метод fit будет повторять и наборы данных и набор данных проверки, однако я видел, что модель использует одни и те же образцы проверки снова и снова. То есть генератор валидации сбрасывает каждую эпоху.

Вот воспроизводимый пример:

import numpy as np
import tensorflow as tf
from tensorflow.keras.layers import Dense

def gen(use):
  while True:
    for i in range(10):
      print(use + f' using mat of {i}')
      X = (np.ones(40)*i).reshape(10,4)
      y = np.ones(10).reshape(-1,1)
      yield (X,y)

dataset_train = tf.data.Dataset.from_generator(generator = lambda:gen('train'),
                                               output_types = (tf.float32, tf.float32),
                                               output_shapes = ((10,4), (10,1)))

dataset_val = tf.data.Dataset.from_generator(generator = lambda:gen('validation'),
                                             output_types = (tf.float32, tf.float32),
                                             output_shapes = ((10,4), (10,1)))
dataset_train.batch(2)
dataset_val.batch(2)

model = tf.keras.models.Sequential()
model.add(Dense(units = 10))

model.compile(loss = 'mse')

history = model.fit(dataset_train,
                    steps_per_epoch = 1,
                    epochs = 5,
                    shuffle = False,
                    verbose = 2,
                    validation_data = dataset_val,
                    validation_steps = 1)

Обратите внимание, что я использую tennorflow 2.2.0-rc3 (версия по умолчанию для Google Colab).

В этом коде мой генератор генерирует мартикс 10 на 4 некоторого числа n , которое меняется в каждой итерации. Эта матрица представляет мои входные функции. Метки здесь - просто вектор единиц (10 на 1). Что я хотел бы получить в этом игрушечном примере, так это то, что для каждой эпохи i матрица признаков будет представлять собой матрицу i с. Вывод, который я получаю:

Epoch 1/5
train using mat of 0
validation using mat of 0
1/1 - 0s - loss: 1.0000 - val_loss: 0.9937
Epoch 2/5
train using mat of 1
validation using mat of 0
1/1 - 0s - loss: 1.5841 - val_loss: 0.9909
Epoch 3/5
train using mat of 2
validation using mat of 0
1/1 - 0s - loss: 3.8616 - val_loss: 0.9902
Epoch 4/5
train using mat of 3
validation using mat of 0
1/1 - 0s - loss: 7.7457 - val_loss: 0.9906
Epoch 5/5
train using mat of 4
validation using mat of 0
1/1 - 0s - loss: 13.1401 - val_loss: 0.9915

Таким образом, тренировочный генератор работает, как я ожидал, но проверка застряла на 0.

Есть ли способ выполнить итерации по набору данных проверки?

1 Ответ

0 голосов
/ 04 мая 2020

Внутренне Tensorflow извлекает данные проверки сразу и использует их для всех эпох. См. здесь . Следовательно, это и есть причина вашего вывода.

Я думаю, что даже в документации это отражено в этом, то есть нет никаких упоминаний о генераторах в validation_data.

Из документации:

validation_data: Данные для оценки потерь и любые метрики модели в конце каждой эпохи. Модель не будет обучаться на этих данных. validation_data переопределит validation_split. Допустимые данные:

  • кортеж (x_val, y_val) из Numpy массивов или тензоров
  • кортеж (x_val, y_val, val_sample_weights) из Numpy набор данных массивов

Для первых двух случаев необходимо указать batch_size. В последнем случае могут быть предоставлены validation_steps.

...