Вопрос или проблема
Я пытаюсь реализовать 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. Это мешает конкатенации различных выходов и, следовательно, нарушает структуру сети.
Решение
Первое, что нужно рассмотреть, – это изменение подхода к усредняющему пулу. Вместо того чтобы модифицировать входные данные, можно попробовать несколько стратегий:
-
Использование
strides
: Вы можете установитьstrides
в параметрыAveragePooling2D
, чтобы контролировать размер выходного тензора. Например, если вы установитеstrides=(1,1)
, то выходной размер останется тем же, что и входной размер, однако это приведет к увеличению вычислительной нагрузки. -
Использование
padding
: ВAveragePooling2D
можно установитьpadding='same'
, чтобы гарантировать, что выходное изображение имеет такие же размеры, что и оригинал. Однако при больших ядрах пула может все равно произойти округление, и данный подход может быть недостаточным. -
Постобработка: После применения пула можно использовать слои
Cropping2D
илиZeroPadding2D
, чтобы подогнать размеры выходных данных под размеры входных данных. Это позволит сохранить необходимый размер в 68×120. -
Установка размеров входа: Если ни один из предыдущих методов не подходит, можно рассмотреть возможность изменения размера входных данных до более удобного. Например, размер 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 без потери информации из-за округления размеров.