Установленный способ использования TF Dataset API в Keras - это кормить `model.fit` с помощью` make_one_shot_iterator () `, но этот итератор годен только для одной эпохи

Редактировать:

Чтобы прояснить, почему этот вопрос отличается от предложенных дубликатов, этот вопрос SO является продолжением предложенных дубликатов, о том, что именно делает Керас с методами, описанными в этих вопросах SO. Предлагаемые дубликаты указываются с использованием API набора данных make_one_shot_iterator() в model.fit, я продолжаю, что make_one_shot_iterator() может пройти через набор данных только один раз, однако в данных решениях указано несколько эпох.


Это продолжение этих вопросов SO

Как правильно объединить API набора данных TensorFlow и Keras?

Tensorflow keras с вводом набора данных tf

Использование tf.data.Dataset в качестве обучения ввод в модель Keras НЕ работает

Где «Начиная с Tensorflow 1.9, можно передать объект tf.data.Dataset непосредственно в keras.Model.fit (), и он будет действовать аналогично fit_generator». В каждом примере есть итератор с одним выстрелом из набора данных TF, загруженный в файл Kera model.fit.

Пример приведен ниже

# Load mnist training data
(x_train, y_train), _ = tf.keras.datasets.mnist.load_data()
training_set = tfdata_generator(x_train, y_train,is_training=True)

model = # your keras model here              
model.fit(
    training_set.make_one_shot_iterator(),
    steps_per_epoch=len(x_train) // 128,
    epochs=5,
    verbose = 1)

Однако, согласно руководству по API Tensorflow Dataset (здесь https://www.tensorflow.org/guide/datasets):

Одноразовый итератор - это простейшая форма итератора, которая поддерживает только однократную итерацию по набору данных.

Так что это годится только для 1 эпохи. Однако коды в вопросах SO определяют несколько эпох, а в приведенном выше примере кода указано 5 эпох.

Есть ли объяснение этому противоречию? Знает ли Керас каким-то образом, что, когда итератор с одним выстрелом прошел через набор данных, он может повторно инициализировать и перетасовать данные?


person SantoshGupta7    schedule 31.03.2019    source источник
comment
@Sharky Это продолжение ссылок, которые вы включили в свои комментарии, о том, как именно Keras обрабатывает методы, описанные в этих ссылках. Также для вашей второй ссылки решения также используют итераторы из API набора данных.   -  person SantoshGupta7    schedule 31.03.2019
comment
См. Ответ Дат Нгуен. В нем четко указан текущий рекомендуемый способ использования api набора данных с keras.   -  person Sharky    schedule 31.03.2019
comment
Я прочитал ответ Дата Нгуена, мой вопрос на самом деле является продолжением предоставленного ответа; мой вопрос - продолжение текущего рекомендуемого способа использования api набора данных с keras. Я обновил текст в своем исходном вопросе, чтобы еще больше прояснить это.   -  person SantoshGupta7    schedule 31.03.2019
comment
Окей, прости. не упомянул об этом.   -  person Sharky    schedule 31.03.2019


Ответы (1)


Вы можете просто передать объект набора данных в model.fit, Keras выполнит итерацию. Учитывая один из готовых наборов данных:

train, test = tf.keras.datasets.cifar10.load_data()
dataset = tf.data.Dataset.from_tensor_slices((train[0], train[1]))

Это создаст объект набора данных из обучающих данных набора данных cifar10. В этом случае функция синтаксического анализа не нужна. Если вы создаете набор данных из пути, содержащего изображения списка массивов numpy, вам он понадобится.

dataset = tf.data.Dataset.from_tensor_slices((image_path, labels_path)) 

Если вам понадобится функция для загрузки фактических данных из файла. Массив Numpy можно обрабатывать таким же образом, только без tf.read_file

def parse_func(filename):
    f = tf.read_file(filename)
    image = tf.image.decode_image(f)
    label = #get label from filename
    return image, label

Затем вы можете перемешивать, группировать и сопоставлять любую функцию синтаксического анализа с этим набором данных. Вы можете контролировать, сколько примеров будет предварительно загружено с помощью буфера перемешивания. Повторить контролирует количество эпох, и лучше оставить «Нет», так что это будет повторяться бесконечно. Вы можете использовать обычную пакетную функцию или комбинировать с

dataset = dataset.shuffle().repeat()
dataset.apply(tf.data.experimental.map_and_batch(map_func=parse_func, batch_size,num_parallel_batches))

Затем объект набора данных можно передать в model.fit model.fit (набор данных, эпохи, шаги_за_эпоху). Обратите внимание, что steps_per_epoch является необходимым параметром в этом случае, он определит, когда начинать новую эпоху. Так что вам нужно знать размер эпохи заранее.

person Sharky    schedule 31.03.2019
comment
Спасибо! Итак, есть ошибка в ответах, данных в трех связанных вопросах stackoverflow, где они вызывают функцию итератора в объекте набора данных, переданном в model.fit. Например, в ответе Дат Нгуен model.fit( training_set.make_one_shot_iterator() , ..... Это ошибка, и .make_one_shot_iterator() нельзя было называть? Так что только model.fit( training_set , .... - person SantoshGupta7; 01.04.2019
comment
Это не ошибка, просто с тех пор был изменен api. Теперь итератор не нужен - person Sharky; 01.04.2019
comment
Скажем, я указываю размер пакета в наборе данных с помощью пакетной функции dataset.batch(batch_size), нужно ли мне указывать steps_per_epoch? Или мне просто нужно убедиться, что любой размер партии, который я укажу, должен соответствовать полученному steps_per_epoch? Я спрашиваю об этом, потому что на самом деле мне нужно будет использовать dataset.padded_batch, поскольку количество точек в строке меняется? ИЛИ, может ли Керас как-то с этим справиться? - person SantoshGupta7; 01.04.2019
comment
Размер пакета будет контролироваться api набора данных, и необходимы шаги для каждой эпохи, чтобы сообщить ему, когда начинать новую эпоху. вы также можете установить повтор с помощью None и указать эпохи внутри fit - person Sharky; 01.04.2019