Форма входа полносвязного слоя в Keras

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

Я пытаюсь построить новую модель

batchnorm_model = Sequential()
batchnorm_model.add(Dense(50, input_shape=(28,28,5), activation='relu', kernel_initializer="normal")) 
batchnorm_model.add(BatchNormalization())
batchnorm_model.add(Dense(50, activation='relu', kernel_initializer="normal")) 
batchnorm_model.add(BatchNormalization())
batchnorm_model.add(Dense(2))
# Компилируйте вашу модель с помощью sgd
batchnorm_model.compile(optimizer="sgd", loss="categorical_crossentropy", metrics=['accuracy'])

И мой набор входных данных имеет следующую информацию

print(X_train.shape)
(7000, 28, 28, 5)

Но я получил сообщение об ошибке:

ValueError: in user code:

    File "/usr/local/lib/python3.8/dist-packages/keras/engine/training.py", line 1051, in train_function  *
        return step_function(self, iterator)
    File "/usr/local/lib/python3.8/dist-packages/keras/engine/training.py", line 1040, in step_function  **
        outputs = model.distribute_strategy.run(run_step, args=(data,))
    File "/usr/local/lib/python3.8/dist-packages/keras/engine/training.py", line 1030, in run_step  **
        outputs = model.train_step(data)
    File "/usr/local/lib/python3.8/dist-packages/keras/engine/training.py", line 890, in train_step
        loss = self.compute_loss(x, y, y_pred, sample_weight)
    File "/usr/local/lib/python3.8/dist-packages/keras/engine/training.py", line 948, in compute_loss
        return self.compiled_loss(
    File "/usr/local/lib/python3.8/dist-packages/keras/engine/compile_utils.py", line 201, in __call__
        loss_value = loss_obj(y_t, y_p, sample_weight=sw)
    File "/usr/local/lib/python3.8/dist-packages/keras/losses.py", line 139, in __call__
        losses = call_fn(y_true, y_pred)
    File "/usr/local/lib/python3.8/dist-packages/keras/losses.py", line 243, in call  **
        return ag_fn(y_true, y_pred, **self._fn_kwargs)
    File "/usr/local/lib/python3.8/dist-packages/keras/losses.py", line 1787, in categorical_crossentropy
        return backend.categorical_crossentropy(
    File "/usr/local/lib/python3.8/dist-packages/keras/backend.py", line 5119, in categorical_crossentropy
        target.shape.assert_is_compatible_with(output.shape)

    ValueError: Shapes (None, 1) and (None, 28, 28, 2) are incompatible

Как определить форму входных данных для первого плотного слоя? Я знаю, что это должно быть количество пикселей в изображении, но я пытаюсь определить как (28285,), все равно не работает.

Работа с изображениями может быть трудной, так как они могут иметь разные каналы, форматы и размеры.

Я не вижу полного кода, но лучшая практика — это тщательно проверять разные размеры входных данных и типы данных, используя:

print(np.shape(image))
print(type(image))

А затем изменять его форму с помощью функции, которая могла бы выглядеть так:

image = np.reshape(image, (28, 28, 2))

Примечание: ранитесь на подобные проблемы, я проводил часы в тупике из-за этого. Лучшее решение, которое я знаю, — это прототипирование проблемы с использованием только необходимых элементов, чтобы учитывать каждую зависимость. Вы можете сэкономить много времени.

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

Чтобы правильно настроить входные данные для слоя Dense в Keras, необходимо понимать, как преобразовать многомерные данные в плоский формат, который требует слой Dense. Давайте подробнее рассмотрим вашу проблему и предложим возможные решения.

Понимание ошибки

Ваша ошибка:

ValueError: Shapes (None, 1) and (None, 28, 28, 2) are incompatible

указывает на то, что выходные данные модели и целевые метки (labels) имеют несовпадающие формы. Судя по вашему коду, вы пытаетесь использовать categorical_crossentropy как функцию потерь, но необходимы целевые метки в формате (число образцов, количество классов) для многоклассовой классификации.

Форма входных данных

  1. Входные данные для первого слоя Dense должны быть одномерными. У вас данные с формой (7000, 28, 28, 5). Это означает, что у вас 7000 изображений, каждое из которых имеет размер 28×28 и 5 каналов.

  2. Чтобы передать эти данные в Dense слой, вам нужно "разгладить" (flatten) каждое изображение в одномерный массив. Для этого можно использовать Flatten слой перед первым Dense слоем.

Исправленная версия вашего кода

Для корректного построения модели используйте следующую структуру:

from keras.models import Sequential
from keras.layers import Dense, Flatten, BatchNormalization

batchnorm_model = Sequential()
batchnorm_model.add(Flatten(input_shape=(28, 28, 5)))  # Преобразование изображения в одномерный массив
batchnorm_model.add(Dense(50, activation='relu', kernel_initializer="normal"))
batchnorm_model.add(BatchNormalization())
batchnorm_model.add(Dense(50, activation='relu', kernel_initializer="normal"))
batchnorm_model.add(BatchNormalization())
batchnorm_model.add(Dense(2, activation='softmax'))  # Убедитесь, что выходной слой соответствует количеству классов

# Компиляция модели с использованием SGD
batchnorm_model.compile(optimizer="sgd", loss="categorical_crossentropy", metrics=['accuracy'])

Предварительная подготовка данных

Помимо изменения структуры модели, убедитесь, что ваши метки корректно закодированы. Если у вас 2 класса, убедитесь, что целевые метки имеют форму (7000, 2) и закодированы в виде one-hot (например, для двух классов вы можете иметь [1, 0] и [0, 1]).

Если ваши метки представлены в виде целых чисел (например, 0 и 1), вы можете использовать to_categorical из keras.utils для преобразования:

from keras.utils import to_categorical

# Преобразуйте ваши метки
y_train = to_categorical(y_train, num_classes=2)

Заключение

Следуя этим шагам, вы должны устранить существующие проблемы с несовпадением форм и корректно настроить модель для обучения. Убедитесь, что все данные, которые вы подаете в модель, соответствуют ожидаемым размерам и форматам.

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

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