#tensorflow #keras #conv-neural-network #autoencoder
Вопрос:
Я реализовал автоэнкодер CNN, который не имеет входных данных квадратной формы. Я немного сбит с толку. Обязательно ли иметь ввод в квадратной форме для автоэнкодеров ? Каждое из 2D — изображений имеет форму 800×20. Я ввел данные в соответствии с формой. Но почему-то формы не совпадают при построении модели. Я поделился кодом модели и сообщением об ошибке ниже. Нужна ваша экспертная консультация. Спасибо.
x = Input(shape=(800, 20,1))
# Encoder
conv1_1 = Conv2D(16, (3, 3), activation='relu', padding='same')(x)
pool1 = MaxPooling2D((2, 2), padding='same')(conv1_1)
conv1_2 = Conv2D(8, (3, 3), activation='relu', padding='same')(pool1)
pool2 = MaxPooling2D((2, 2), padding='same')(conv1_2)
conv1_3 = Conv2D(8, (3, 3), activation='relu', padding='same')(pool2)
h = MaxPooling2D((2, 2), padding='same')(conv1_3)
# Decoder
conv2_1 = Conv2D(8, (3, 3), activation='relu', padding='same')(h)
up1 = UpSampling2D((2, 2))(conv2_1)
conv2_2 = Conv2D(8, (3, 3), activation='relu', padding='same')(up1)
up2 = UpSampling2D((2, 2))(conv2_2)
conv2_3 = Conv2D(16, (3, 3), activation='relu', padding='same')(up2)
up3 = UpSampling2D((2, 2))(conv2_3)
r = Conv2D(1, (3, 3), activation='sigmoid', padding='same')(up3)
model = Model(inputs=x, outputs=r)
model.compile(optimizer='adadelta', loss='binary_crossentropy', metrics=['accuracy'])
results = model.fit(x_train, x_train, epochs = 500, batch_size=16,validation_data= (x_test, x_test))
Вот ошибка:
ValueError: logits and labels must have the same shape ((16, 800, 24, 1) vs (16, 800, 20, 1))
Комментарии:
1. Не могли бы вы также поделиться полученным сообщением об ошибке? Как правило, автокодеры работают также с входами «неквадратичной» формы
2. Пожалуйста, не показывайте код/ошибки в виде изображений, включите текст в сам вопрос. И вы должны включить свой вызов model.fit.
3. @Dr. Snoopy Я обновил сообщение и добавил ошибку и подгонку. Пожалуйста, взгляните сейчас.
4. Что такое y_train здесь? Предполагается, что автокодеры восстанавливают входные данные, поэтому вы не предоставляете дополнительные метки для задачи.
5. @Доктор Снупи Спасибо, что выяснил это. Но все равно я получаю ту же ошибку после замены y_train на x_train. Я обновил код ошибки. Пожалуйста, взгляните.
Ответ №1:
Как показывает трассировка ошибок, проблема, с которой вы сталкиваетесь при попытке работать с этим автоэнкодером, заключается в том, что модель ожидает, что форма ввода будет (?, 800, 20, 1)
, но форма вывода будет (?, 796, 20, 1)
. В то время как он получает каждое входное и выходное изображение в виде
(800, 20, 1)
. (Проверьте форму ввода и вывода сводки вашей модели!)
Мои Рекомендации —
- Я исправил
padding = 'same'
и перенастроил формы так, чтобы форма входного тензора и выход были одинаковыми. Проверьте размеры ядра, которые я изменил, чтобы получить выходную форму по мере необходимости. - Кроме того, для многоуровневой архитектуры кодера-декодера conv (такой как автоматический кодер) рекомендуется преобразовать пространственную информацию в карты объектов/фильтры/каналы с последующими слоями. Прямо сейчас вы начинаете с 8 фильтров, затем переходите к 4 в кодере. Это должно быть больше похоже
4->8->16
. Проверьте эту диаграмму для ссылки на интуицию.
С учетом приведенных выше рекомендаций я внес здесь изменения.
x = Input(shape=(800, 20,1))
# Encoder
conv1_1 = Conv2D(4, (3, 3), activation='relu', padding='same')(x)
pool1 = MaxPooling2D((2, 2), padding='same')(conv1_1)
conv1_2 = Conv2D(8, (3, 3), activation='relu', padding='same')(pool1)
pool2 = MaxPooling2D((2, 2), padding='same')(conv1_2)
conv1_3 = Conv2D(16, (3, 3), activation='relu', padding='same')(pool2)
h = MaxPooling2D((2, 1), padding='same')(conv1_3) #<------
# # Decoder
conv2_1 = Conv2D(16, (3, 3), activation='relu', padding='same')(h)
up1 = UpSampling2D((2, 2))(conv2_1)
conv2_2 = Conv2D(8, (3, 3), activation='relu', padding='same')(up1)
up2 = UpSampling2D((2, 2))(conv2_2)
conv2_3 = Conv2D(4, (3, 3), activation='sigmoid', padding='same')(up2) #<--- ADD PADDING HERE
up3 = UpSampling2D((2, 1))(conv2_3)
r = Conv2D(1, (3, 3), activation='sigmoid', padding='same')(up3)
model = Model(inputs=x, outputs=r)
model.compile(optimizer='adadelta', loss='binary_crossentropy', metrics=['accuracy'])
model.summary()
Model: "model_13"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
input_16 (InputLayer) [(None, 800, 20, 1)] 0
_________________________________________________________________
conv2d_101 (Conv2D) (None, 800, 20, 4) 40
_________________________________________________________________
max_pooling2d_45 (MaxPooling (None, 400, 10, 4) 0
_________________________________________________________________
conv2d_102 (Conv2D) (None, 400, 10, 8) 296
_________________________________________________________________
max_pooling2d_46 (MaxPooling (None, 200, 5, 8) 0
_________________________________________________________________
conv2d_103 (Conv2D) (None, 200, 5, 16) 1168
_________________________________________________________________
max_pooling2d_47 (MaxPooling (None, 100, 5, 16) 0
_________________________________________________________________
conv2d_104 (Conv2D) (None, 100, 5, 16) 2320
_________________________________________________________________
up_sampling2d_43 (UpSampling (None, 200, 10, 16) 0
_________________________________________________________________
conv2d_105 (Conv2D) (None, 200, 10, 8) 1160
_________________________________________________________________
up_sampling2d_44 (UpSampling (None, 400, 20, 8) 0
_________________________________________________________________
conv2d_106 (Conv2D) (None, 400, 20, 4) 292
_________________________________________________________________
up_sampling2d_45 (UpSampling (None, 800, 20, 4) 0
_________________________________________________________________
conv2d_107 (Conv2D) (None, 800, 20, 1) 37
=================================================================
Total params: 5,313
Trainable params: 5,313
Non-trainable params: 0
_________________________________________________________________
Чтобы показать, что модель теперь работает, позвольте мне создать случайный набор данных с тем же, на который вы смотрите.
x_train = np.random.random((16,800,20,1))
model.fit(x_train, x_train, epochs=2)
Epoch 1/2
1/1 [==============================] - 0s 180ms/step - loss: 0.7526 - accuracy: 0.0000e 00
Epoch 2/2
1/1 [==============================] - 0s 189ms/step - loss: 0.7526 - accuracy: 0.0000e 00
<tensorflow.python.keras.callbacks.History at 0x7fa85a9896d0>
Комментарии:
1. Спасибо за ваш подробный ответ. Я изменил свою модель в соответствии с вашим предложением, и она работает только в течение одной эпохи, а затем снова та же ошибка. Ошибка значения: логины и метки должны иметь одинаковую форму ((Нет, 800, 20, 1) против (Нет, 3))
2. можете ли вы распечатать форму изображений X_train и y_train? Я думаю, что это связано с вашими формами данных для обучения. Я могу запускать эпохи для случайно сгенерированных данных
3. Кроме того, в
validation = (x_test, y_test)
, измените его на(x_test, x_test)
4. добавил к ответу свою эпоху. вы можете видеть, что он работает для фигуры (16, 800,20,1) как x_train
5. Это сработало после изменения validation = (x_test, x_test). Спасибо Акшай 🙂