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

В настоящее время я пытаюсь изменить mobilenetv2 так, чтобы он обнаруживал определенные объекты на изображении и возвращал тепловую карту, которая отмечает позиции указанных объектов. Для этого необходимо, чтобы тепловая карта имела такое же разрешение, что и входное изображение.

Мой подход заключается в создании некоторой сети U-Net, подобной сети кодер-декодер, которая использует Conv2dTranspose для масштабирования выходных данных мобильной сети обратно в ее первоначальную форму с помощью кратких путей к каждой соответствующей свертке, которая уменьшает разрешение.

Первая конкатенация между первыми соответствующими слоями работает хорошо, однако вторая не дает результатов, поскольку формы их выходных данных не совпадают. Первый Conv2dTranspose увеличивает разрешение в 2 раза, как я и ожидал. Второй, однако, нет. Он имеет входную форму (Нет, 20, 80, 192) и должен выводить (Нет, 40, 160, 144). К сожалению, фактическая выходная форма оказывается (Нет, 36, 156, 144), что делает невозможным объединение слоев.

Как я могу добиться согласованной формы вывода? Я думал, что это то, что padding='same' должен был гарантировать? Помощь очень ценится!

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

base_model = MobileNetV2(input_shape=(imageShape[0], 
    imageShape[1], 3), include_top=False, weights='imagenet')
conv_layers = get_conv_layers(base_model)

x = base_model.output

c = conv_layers.pop()
c = conv_layers.pop()
x = Conv2DTranspose(filters=c.output_shape[-1],
                    kernel_size=(3, 3), strides=(2, 2), 
                    activation='relu', padding='same', 
                    kernel_initializer='he_normal')(x)
x = concatenate([c.output, x], axis=-1)
x = Conv2D(filters=c.output_shape[-1], kernel_size=(3, 3),
           activation='relu')(x)

c = conv_layers.pop()
x = Conv2DTranspose(filters=c.output_shape[-1],
                    kernel_size=(3, 3), strides=(2, 2), 
                    activation='relu', padding='same',
                    kernel_initializer='he_normal')(x)
x = concatenate([c.output, x], axis=-1)
x = Conv2D(filters=c.output_shape[-1], kernel_size=(3, 3),
           activation='relu')(x)

Ошибка значения: A Concatenate Для слоя требуются входные данные с соответствующими формами, за исключением оси concat. Получил входные формы: [(Нет, 40, 160, 144), (Нет, 36, 156, 144)]

Первая форма - это желаемая форма вывода Conv2dTransposed, вторая - фактическая. Они должны быть одинаковыми, чтобы конкатенация работала.

1 ответ

Решение

Итак, я понял это, иногда вы просто должны отойти от проблемы на некоторое время. Оказывается, я был настолько сфокусирован на Conv2dTranspose как виновнике, что я полностью упустил из виду, что между ними есть другие слои, которые могут вызвать проблему. В конце концов я забыл установить отступы обычного Conv2d на "то же самое". Установка этого параметра правильно решила проблему, и я получил ожидаемую форму вывода.

Другие вопросы по тегам