свертка-деконволюция с сохранением оригинального размера изображения

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

Я пытаюсь реализовать pspnet в tensorflow. Это требует модуля пулинга, который принимает входные данные вместе с несколькими размерами ядра:

выполняет средний пулинг на входе с каждым ядром AveragePooling2D

выполняет свертку 1×1, после чего используется UpSampling2D

В конце все разные выходы свертки-декодирования объединяются и передаются вперед

def pyramid_pooling_module(x, pool_sizes):
    pool_outputs = []
    for pool_size in pool_sizes:
        pooled= layers.AveragePooling2D(pool_size)(x)
        pooled= layers.Conv2D(512, (1,1), padding='same')(pooled)
        pooled= layers.UpSampling2D(size=pool_size, interpolation='bilinear')(pooled)
        print(pool_size)
        pool_outputs.append(pooled)
    return layers.Concatenate()(pool_outputs)

Входные данные будут размером 68, 120. Из-за этого используемые ядра (1×1, 2×2, 3×3, 6×6) будут иметь ошибки округления от слоев среднего пулинга для 3×3, 6×6

так что окончательные выходные данные для тех слоев составляют (66, 120)

Я не уверен, как это исправить, нужно ли мне изменить размер входных данных на такой, который делится на 6×6? Есть ли другой способ?

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

Для реализации модуля пирамидального пула (Pyramid Pooling Module) в PSPNet с использованием TensorFlow, ключевым аспектом является поддержание оригинального размера изображения после выполнения операций усредняющего пула (Average Pooling) и последующих операций.

Проблема

Когда вы используете разные размеры ядер (как 3×3 и 6×6) для усредняющего пула на изображениях размером 68×120, возникают ошибки округления. Например, применение пула 3×3 или 6×6 приводит к уменьшению размера выходного изображения, в результате чего у вас получается размер 66×120 вместо ожидаемого 68×120. Это мешает конкатенации различных выходов и, следовательно, нарушает структуру сети.

Решение

Первое, что нужно рассмотреть, – это изменение подхода к усредняющему пулу. Вместо того чтобы модифицировать входные данные, можно попробовать несколько стратегий:

  1. Использование strides: Вы можете установить strides в параметры AveragePooling2D, чтобы контролировать размер выходного тензора. Например, если вы установите strides=(1,1), то выходной размер останется тем же, что и входной размер, однако это приведет к увеличению вычислительной нагрузки.

  2. Использование padding: В AveragePooling2D можно установить padding='same', чтобы гарантировать, что выходное изображение имеет такие же размеры, что и оригинал. Однако при больших ядрах пула может все равно произойти округление, и данный подход может быть недостаточным.

  3. Постобработка: После применения пула можно использовать слои Cropping2D или ZeroPadding2D, чтобы подогнать размеры выходных данных под размеры входных данных. Это позволит сохранить необходимый размер в 68×120.

  4. Установка размеров входа: Если ни один из предыдущих методов не подходит, можно рассмотреть возможность изменения размера входных данных до более удобного. Например, размер 72×120 был бы полностью делим на 6 и даст вам целостный результат. Это наиболее простой подход, но он требует предобработки изображений.

Обновлённый Код

Вот обновлённый код функции pyramid_pooling_module, который включает в себя использование padding и корректировку размеров:

def pyramid_pooling_module(x, pool_sizes):
    pool_outputs = []
    for pool_size in pool_sizes:
        pooled = layers.AveragePooling2D(pool_size, strides=1, padding='same')(x)  # Установка padding='same'
        pooled = layers.Conv2D(512, (1, 1), padding='same')(pooled)
        pooled = layers.UpSampling2D(size=pool_size, interpolation='bilinear')(pooled)

        # Проверка и коррекция размера, если нужно
        if pooled.shape[1] != x.shape[1] or pooled.shape[2] != x.shape[2]:
            pooled = layers.Cropping2D(cropping=((0, 2), (0, 0)))(pooled)  # Корректируем размер, если необходимо

        pool_outputs.append(pooled)
    return layers.Concatenate()(pool_outputs)

Заключение

Таким образом, вы можете использовать указанные решения для корректировки размерности выхода и гарантирования, что результирующие тензоры будут иметь размеры, совместимые с входными данными. Таким образом, вы сможете эффективно использовать модуль пирамидального пула в своей модели PSPNet без потери информации из-за округления размеров.

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

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