Несовместимые формы (None, 1) и (None, 5) с тонкой настройкой Keras VGGFace

Вопрос или проблема

Категории для учебы и предсказания:

df.race.unique()
array(['0', '1', '3', '2', '4'], dtype=object)

Данные:

train_generator = image_gen.flow_from_dataframe(
    df_train,
    x_col="img_name",
    y_col="race",
    directory=str(data_folder),
    class_mode="sparse",
    target_size=(IMAGE_SIZE, IMAGE_SIZE),
    batch_size=BATCH_SIZE,
    shuffle=True,
)

val_generator = image_gen.flow_from_dataframe(
    df_val,
    x_col="img_name",
    y_col="race",
    directory=str(data_folder),
    class_mode="sparse",
    target_size=(IMAGE_SIZE, IMAGE_SIZE),
    batch_size=BATCH_SIZE,
    shuffle=False,
)

Загрузка и настройка модели:

vggface_model = load_model("resnet50face.h5")
base_model = tf.keras.Model([vggface_model.input], vggface_model.get_layer("flatten_1").output)
base_model.trainable = False

last_layer = base_model.get_layer('avg_pool').output
hidden_layer = Flatten(name="flatten")(last_layer)
out_layer = Dense(5, activation='softmax', name="gender_classifier")(hidden_layer)
custom_base_model = tf.keras.Model(base_model.input, out_layer)

custom_base_model.compile(
              optimizer=tf.keras.optimizers.Adam(learning_rate=0.0001),
              loss="categorical_crossentropy",
              metrics=['accuracy'])

history = custom_base_model.fit(
    x=train_generator, 
    validation_data=val_generator, 
    steps_per_epoch=20, 
    epochs=40)

Сообщение об ошибке:

ValueError: in user code:

    /usr/local/lib/python3.7/dist-packages/tensorflow/python/keras/engine/training.py:855 train_function  *
        return step_function(self, iterator)
    /usr/local/lib/python3.7/dist-packages/tensorflow/python/keras/engine/training.py:845 step_function  **
        outputs = model.distribute_strategy.run(run_step, args=(data,))
    /usr/local/lib/python3.7/dist-packages/tensorflow/python/distribute/distribute_lib.py:1285 run
        return self._extended.call_for_each_replica(fn, args=args, kwargs=kwargs)
    /usr/local/lib/python3.7/dist-packages/tensorflow/python/distribute/distribute_lib.py:2833 call_for_each_replica
        return self._call_for_each_replica(fn, args, kwargs)
    /usr/local/lib/python3.7/dist-packages/tensorflow/python/distribute/distribute_lib.py:3608 _call_for_each_replica
        return fn(*args, **kwargs)
    /usr/local/lib/python3.7/dist-packages/tensorflow/python/keras/engine/training.py:838 run_step  **
        outputs = model.train_step(data)
    /usr/local/lib/python3.7/dist-packages/tensorflow/python/keras/engine/training.py:797 train_step
        y, y_pred, sample_weight, regularization_losses=self.losses)
    /usr/local/lib/python3.7/dist-packages/tensorflow/python/keras/engine/compile_utils.py:204 __call__
        loss_value = loss_obj(y_t, y_p, sample_weight=sw)
    /usr/local/lib/python3.7/dist-packages/tensorflow/python/keras/losses.py:155 __call__
        losses = call_fn(y_true, y_pred)
    /usr/local/lib/python3.7/dist-packages/tensorflow/python/keras/losses.py:259 call  **
        return ag_fn(y_true, y_pred, **self._fn_kwargs)
    /usr/local/lib/python3.7/dist-packages/tensorflow/python/util/dispatch.py:206 wrapper
        return target(*args, **kwargs)
    /usr/local/lib/python3.7/dist-packages/tensorflow/python/keras/losses.py:1644 categorical_crossentropy
        y_true, y_pred, from_logits=from_logits)
    /usr/local/lib/python3.7/dist-packages/tensorflow/python/util/dispatch.py:206 wrapper
        return target(*args, **kwargs)
    /usr/local/lib/python3.7/dist-packages/tensorflow/python/keras/backend.py:4862 categorical_crossentropy
        target.shape.assert_is_compatible_with(output.shape)
    /usr/local/lib/python3.7/dist-packages/tensorflow/python/framework/tensor_shape.py:1161 assert_is_compatible_with
        raise ValueError("Shapes %s and %s are incompatible" % (self, other))

    ValueError: Shapes (None, 1) and (None, 5) are incompatible

Проблема была решена, когда я изменил:

class_mode="sparse"

на:

class_mode="categorical"

для обоих источников данных в image_gen.flow_from_dataframe(..)

Ответ или решение

В вашем проекте по тонкой настройке модели VGGFace с использованием Keras возникла проблема, связанная с несовместимыми формами тензоров, которые привели к ошибке во время обучения. Давайте подробно разберем ситуацию и найдем оптимальное решение.

Проблема с несовместимостью форм

Ошибка, с которой вы столкнулись, звучит так:

ValueError: Shapes (None, 1) and (None, 5) are incompatible

Эта ошибка указывает на то, что выходные данные вашего слоя Dense не соответствуют формату целевых меток, используемых в модели. Ваша модель настроена на вывод 5 классов, так как вы применяете Dense(5, activation='softmax'). Это значит, что модель ожидает, что целевые метки (y) будут представлены в формате one-hot encoding (размерность (None, 5)).

Однако, когда вы используете class_mode="sparse" в flow_from_dataframe, Keras подготавливает целевые метки в виде целых чисел (размерность (None, 1)). Это и вызывает конфликт форм, так как размерность выходных данных модели (5) не соответствует размерности меток (1).

Решение проблемы

Для устранения этой проблемы, вы правильно изменили class_mode на "categorical" в методе flow_from_dataframe. Это обеспечивает, что ваши метки будут одним горячим вектором (one-hot encoded), где каждый класс представлен в виде массива из 5 элементов, из которых один равен 1 (помечая класс), а остальные равны 0.

Пример изменения:

train_generator = image_gen.flow_from_dataframe(
    df_train,
    x_col="img_name",
    y_col="race",
    directory=str(data_folder),
    class_mode="categorical",  # Изменено с "sparse" на "categorical"
    target_size=(IMAGE_SIZE, IMAGE_SIZE),
    batch_size=BATCH_SIZE,
    shuffle=True,
)

val_generator = image_gen.flow_from_dataframe(
    df_val,
    x_col="img_name",
    y_col="race",
    directory=str(data_folder),
    class_mode="categorical",  # Изменено с "sparse" на "categorical"
    target_size=(IMAGE_SIZE, IMAGE_SIZE),
    batch_size=BATCH_SIZE,
    shuffle=False,
)

Дополнительные аспекты для настройки модели

  1. Проверка на выходные размеры: Обязательно проверяйте выходные размеры модели перед началом обучения, чтобы избежать подобных ошибок.

  2. Соответствие меток и классов: Убедитесь, что количество классов, которое вы хотите предсказать, совпадает с размерностью выходного слоя вашей модели и определением меток.

  3. Обработка ошибок: В будущем, если вы столкнётесь с подобными ошибками несовместимости форм, полезно использовать отладчик или вывод детализированных форм данных на каждом этапе, чтобы быстро локализовать источник проблемы.

Заключение

Изменение class_mode на "categorical" является адекватным и правильным решением вашей проблемы. Это позволяет вашей модели корректно обрабатывать многоклассовую классификацию. Удачи в дальнейшем обучении вашей модели!

Оцените материал
Добавить комментарий

Капча загружается...