Я пытаюсь использовать этот подход в Tensorflow 2.X для загрузки большого набора данных, который не помещается в памяти.
У меня есть папка с подпапками X, которая содержит изображения. Каждая подпапка является классом.
\dataset
-\class1
-img1_1.jpg
-img1_2.jpg
-...
-\classe2
-img2_1.jpg
-img2_2.jpg
-...
Я создаю свой генератор данных из своей папки следующим образом:
train_data_gen = image_generator.flow_from_directory(directory="path\\to\\dataset",
batch_size=100,
shuffle=True,
target_size=(100, 100), # Image H x W
classes=list(CLASS_NAMES)) # list of folder/class names ["class1", "class2", ...., "classX"]
Найдено 629 изображений, принадлежащих 2 классам.
Я сделал меньший набор данных для тестирования конвейера. Всего 629 изображений в 2 классах. Теперь я могу создать фиктивную модель следующим образом:
model = tf.keras.Sequential()
model.add(Dense(1, activation=activation, input_shape=(100, 100, 3))) # only 1 layer of 1 neuron
model.add(Dense(2)) # 2classes
model.compile(optimizer="adam", loss="categorical_crossentropy", metrics=['categorical_accuracy'])
После компиляции я пытаюсь подогнать эту фиктивную модель:
STEPS_PER_EPOCH = np.ceil(image_count / batch_size) # 629 / 100
model.fit_generator(generator=train_data_gen , steps_per_epoch=STEPS_PER_EPOCH, epochs=2, verbose=1)
1/7 [===>..........................] - ETA: 2s - loss: 1.1921e-07 - categorical_accuracy: 0.9948
2/7 [=======>......................] - ETA: 1s - loss: 1.1921e-07 - categorical_accuracy: 0.5124
3/7 [===========>..................] - ETA: 0s - loss: 1.1921e-07 - categorical_accuracy: 0.3449
4/7 [================>.............] - ETA: 0s - loss: 1.1921e-07 - categorical_accuracy: 0.2662
5/7 [====================>.........] - ETA: 0s - loss: 1.1921e-07 - categorical_accuracy: 0.2130
6/7 [========================>.....] - ETA: 0s - loss: 1.1921e-07 - categorical_accuracy: 0.1808
2020-04-14 20:39: 48.629203: W tenorflow / core / framework / op_kernel. cc: 1610] Недопустимый аргумент: ValueError: generator
дает элемент формы (29, 100, 100, 3), где элемент формы (100, 100, 100) , 3) ожидалось.
Из того, что я понимаю, последняя партия не имеет ту же форму, что и предыдущие партии. Так что вылетает. Я попытался указать batch_input_shape
.
model.add(Dense(1, activation=activation, batch_input_shape=(None, 100, 100, 3)))
Я нашел здесь , что я должен поставить None
, чтобы не указывать количество элементов в пакете, так что может быть динамическим c. Но безуспешно.
Редактировать: Из комментария у меня было 2 ошибки:
- Форма вывода была плохой. Я упустил уплощенный слой в модели.
- Предыдущая ссылка работает с исправлением выровненного слоя
- Отсутствует некоторый код, на самом деле я кормлю
fit_generator
tf.data.Dataset.from_generator
, но Я дал здесь image_generator.flow_from_directory
.
Вот окончательный код:
train_data_gen = image_generator.flow_from_directory(directory="path\\to\\dataset",
batch_size=1000,
shuffle=True,
target_size=(100, 100),
classes=list(CLASS_NAMES))
train_dataset = tf.data.Dataset.from_generator(
lambda: train_data_gen,
output_types=(tf.float32, tf.float32),
output_shapes=([None, x, y, 3],
[None, len(CLASS_NAMES)]))
model = tf.keras.Sequential()
model.add(Flatten(batch_input_shape=(None, 100, 100, 3)))
model.add(Dense(1, activation=activation))
model.add(Dense(2))
model.compile(optimizer="adam", loss="categorical_crossentropy", metrics=['categorical_accuracy'])
STEPS_PER_EPOCH = np.ceil(image_count / batch_size) # 629 / 100
model.fit_generator(generator=train_data_gen , steps_per_epoch=STEPS_PER_EPOCH, epochs=2, verbose=1)