Вопрос или проблема
Итак, я пытаюсь построить модель для классификатора изображений, используя набор данных oxford flower 102, и сталкиваюсь с проблемами при попытке обучить модель. Ошибка гласит:
InvalidArgumentError: Cannot batch tensors with different shapes in component 0. First element had shape [500,667,3] and element 1 had shape [500,528,3].
[[node IteratorGetNext (defined at <ipython-input-23-4e2ec1874986>:7) ]] [Op:__inference_train_function_36111]
Стек вызовов функций:
train_function
Я борюсь с этим уже довольно долгое время, но так и не могу это исправить. Я выложу код и соответствующую информацию ниже, так что это будет немного длинно, но вопрос касается только этой ошибки, вы можете пропустить до конца, если проблема очевидна. Пожалуйста, любая помощь будет полезна.
Примечание: в конце есть правка —-
Код, который я пытаюсь запустить, выглядит следующим образом:
num_training_examples = dataset_info.splits['train'].num_examples
num_val_examples = dataset_info.splits['validation'].num_examples
num_test_examples = dataset_info.splits['test'].num_examples
num_classes = dataset_info.features['label'].num_classes
print('There are {:,} images in the training set'.format(num_training_examples))
print('There are {:,} images in the validation set'.format(num_val_examples))
print('There are {:,} images in the test set'.format(num_test_examples))
print('\nThere are {:,} classes in our dataset'.format(num_classes))
Выводит:
There are 1,020 images in the training set
There are 1,020 images in the validation set
There are 6,149 images in the test set
There are 102 classes in our dataset
Примеры 3 изображений:
print('Taking 3 images from the training set:')
for image, label in training_set.take(3):
print('\n\u2022 dtype:', image.dtype, '\n\u2022 shape:', image.shape, '\n\u2022 label:', label)
с выводом (показывает только один):
• dtype: <dtype: 'uint8'>
• shape: (500, 667, 3)
• label: tf.Tensor(72, shape=(), dtype=int64)
Я создал конвейер:
image_size = (224, 224)
def normalize(image, label):
normalized_image = tf.image.resize(image, image_size)
normalized_image /= 255
return normalized_image, label
batch_size = 32
training_batches = training_set.cache().shuffle(num_training_examples//4).batch(batch_size).map(normalize).prefetch(1)
validation_batches = validation_set.cache().shuffle(num_training_examples//4).batch(batch_size).map(normalize).prefetch(1)
testing_batches = test_set.cache().shuffle(num_training_examples//4).batch(batch_size).map(normalize).prefetch(1)
Теперь я строю классификатор:
mobilenet_url = "https://tfhub.dev/google/tf2-preview/mobilenet_v2/feature_vector/4"
feature_extractor = hub.KerasLayer(mobilenet_url, input_shape= image_size + (3,), trainable=False)
layer_neurons = [512, 256, 256, 128, 100, 64, 32, 32]
dropout_rate = 0.3
model = tf.keras.Sequential([
feature_extractor,
])
model.add(tf.keras.layers.Flatten(input_shape=(224,224,3)))
for neurons in layer_neurons:
model.add(tf.keras.layers.Dense(neurons, activation = 'relu'))
model.add(tf.keras.layers.Dropout(dropout_rate))
model.add(tf.keras.layers.Dense(10, activation = 'softmax'))
model.summary()
model.compile(optimizer="adam",
loss="sparse_categorical_crossentropy",
metrics=['accuracy'])
early_stopping = tf.keras.callbacks.EarlyStopping(monitor="val_loss", patience=10)
save_best = tf.keras.callbacks.ModelCheckpoint('./best_model.h5',
monitor="val_loss",
save_best_only=True)
history = model.fit(training_batches,
epochs = 100,
validation_data=validation_batches,
callbacks=[early_stopping, save_best])
И ОШИБКА:
Epoch 1/100
InvalidArgumentError Traceback (most recent call last)
<ipython-input-23-4e2ec1874986> in <module>
5 epochs = 100,
6 validation_data=validation_batches,
----> 7 callbacks=[early_stopping, save_best])
И после нескольких строк говорится:
InvalidArgumentError: Cannot batch tensors with different shapes in component 0.
First element had shape [500,667,3] and element 1 had shape [500,528,3].
[[node IteratorGetNext (defined at <ipython-input-23-4e2ec1874986>:7) ]]
[Op:__inference_train_function_36111]
Function call stack:
train_function
ИЗМЕНЕНИЕ:
После изменения порядка конвейера:
batch_size = 32
training_batches = training_set.shuffle(num_training_examples//4).map(normalize).cache().batch(batch_size).prefetch(1)
validation_batches = validation_set.shuffle(num_training_examples//4).map(normalize).batch(batch_size).cache().prefetch(1)
testing_batches = test_set.shuffle(num_training_examples//4).map(normalize).batch(batch_size).cache().prefetch(1)
И оставив все остальное неизменным, я больше не получил эту ошибку, но возникла новая ошибка:
InvalidArgumentError Traceback (most recent call last)
<ipython-input-19-4e2ec1874986> in <module>
5 epochs = 100,
6 validation_data=validation_batches,
----> 7 callbacks=[early_stopping, save_best])
...
...
...
InvalidArgumentError: Received a label value of 95 which is outside the valid range of [0, 10). Label values: 42 25 94 18 9 87 54 75 65 32 90 83 26 79 12 3 56 21 34 38 43 28 61 95 1 22 87 50 56 52 40 32
[[node sparse_categorical_crossentropy/SparseSoftmaxCrossEntropyWithLogits/SparseSoftmaxCrossEntropyWithLogits (defined at <ipython-input-19-4e2ec1874986>:7) ]] [Op:__inference_train_function_18131]
Function call stack:
train_function
Проблема решена.
Это была глупая и нелепая ошибка в конце концов. Я был наивен – может, мне нужно поспать, не знаю.
Проблема была только в последнем слое сети:
model.add(tf.keras.layers.Dense(10, activation = 'softmax'))
Это должно было быть
model.add(tf.keras.layers.Dense(num_classes, activation = 'softmax'))
Я не мог построить сеть с аргументом 10, ограничивающим ее 10 выходами: у меня 101 возможный выход!!!
В любом случае, это все. Извините!
Ответ или решение
Проблемы с батчингом тензоров: InvalidArgumentError
Фор
Ваш коллега в сфере информационных технологий столкнулся с проблемой, связанной с обучением модели классификации изображений с использованием датасета Oxford Flower 102. Он получил ошибку InvalidArgumentError
при попытке обработать батч данных с разными размерами компонентов. Рассмотрим, как решить эту проблему и избежать новых.
Ориентирование
Контекст проблемы: разработчик пытается обучить модель, используя набор изображений, которые имеют различные размеры. Код для нормализации и изменения размера изображений реализован и предлагается использовать TensorFlow. Однако возникла ошибка в результате несоответствия размеров входных изображений.
Ошибка батчинга
Начальная ошибка в коде связана с тем, что попытки создать батчи из изображений, размеры которых не согласованы, приводят к сбою. В этом случае изображения имеют разные размеры, например, [500,667,3] и [500,528,3].
Эффективное решение
Устранение ошибки: порядок операций в пайплайне был скорректирован. Сначала изображения нормализуются и изменяется их размер, только после этого они кэшируются и объединяются в батчи. Такой порядок позволяет избежать ошибки батчинга.
Новая ошибка
Согласно изменениям, его следующий шаг привёл к появлению другой ошибки — неправильной конфигурации конечного слоя нейронной сети. Модель пыталась классифицировать изображения на всего 10 классов при наличии 102 классов в датасете.
Рассвет решений
Решение проблемы с батчингом
Изменение порядка в пайплайне операций решило проблему с несовпадением размеров батчей.
Решение проблемы классификации
Коллега нашел и исправил ошибку в конечной конфигурации модели:
model.add(tf.keras.layers.Dense(num_classes, activation='softmax'))
где num_classes
— это количество классов в датасете (102), что позволяет модели правильно классифицировать входные изображения.
Заключение
Ошибки в машинном обучении, особенно связанные с преобразованием данных и структурой модели, часто сводятся к незначительным пропускам или ошибкам. Важно уделять внимание каждому аспекту реализации и не забывать о нюансах датасета, чтобы успешно обучать и применять модель. Корректирование размеров тензоров и адаптация конечного слоя модели оказались ключом к решению.
В случае возникновения таких проблем рекомендуется тщательно проверить всю цепочку подготовки данных и конфигурации модели с учётом задач и параметров датасета.