есть ли способ масштабировать и складывать карты объектов разной формы в tensorflow?

#python #tensorflow

#python #tensorflow

Вопрос:

Я намерен использовать концепцию пропуска соединения в своем эксперименте. По сути, в моем конвейере карты объектов, которые появляются после Conv2D , будут сложены или объединены. Но карты объектов имеют разную форму, и попытка сложить их вместе в один тензор выдала мне ошибку. Кто-нибудь знает какой-нибудь возможный способ сделать это правильно в tensorflow? Есть какие-нибудь мысли или идеи, как это осуществить? Спасибо

блок-схема идеи

вот блок-схема конвейера, я хочу это сделать:

введите описание изображения здесь

мой случай немного отличается, потому что я получил дополнительный строительный блок, который используется после Conv2D и его вывод сейчас feature maps of 15x15x64 и так далее. Я хочу объединить эти карты объектов в одну, а затем использовать ее Conv2D снова.

моя попытка:

это моя воспроизводимая попытка:

 import tensorflow as tf
from tensorflow.keras.layers import Dense, Dropout, Activation, Conv2D, Flatten, MaxPool2D, BatchNormalization


inputs = tf.keras.Input(shape=(32, 32, 3))
x = inputs
x = Conv2D(32, (3, 3), input_shape=(32,32,3))(x)
x = BatchNormalization(axis=-1)(x)
x = Activation('relu')(x)
fm1 = MaxPooling2D(pool_size=(2,2))(x)

x = Conv2D(32,(3, 3), input_shape=(15,15,32))(fm1)
x = BatchNormalization(axis=-1)(x)
x = Activation('relu')(x)
fm2 = MaxPooling2D(pool_size=(2,2))(x)

concatted = tf.keras.layers.Concatenate(axis=1)([fm1, fm2])
  

но таким образом я закончил со следующей ошибкой: ValueError: A Concatenate layer requires inputs with matching shapes except for the concat axis. Got inputs shapes: [(None, 15, 15, 32), (None, 6, 6, 32)] . Я не уверен, какой был бы правильный способ сложить карты объектов разной формы. Как мы можем сделать это правильно? Есть какие-нибудь возможные мысли?

желаемый результат

в моей реальной модели я получил форму карт объектов TensorShape([None, 15, 15, 128]) и TensorShape([None, 6, 6, 128]) . Мне нужно найти способ объединить их или сложить в один. В идеале форма сцепленных или сложенных карт объектов должна быть следующей [None, 21,21,128] . Есть ли какой-нибудь способ сложить их в одно целое? Есть идея?

Ответ №1:

То, чего вы пытаетесь достичь, не работает математически. Позвольте мне проиллюстрировать. Возьмем простую одномерную задачу (например, одномерную свертку). У вас есть выходные данные размером (None, 64, 128) (fm1) и (None, 32, 128) (fm2), которые вы хотите объединить. Затем,

concatted = tf.keras.layers.Concatenate(axis=1)([fm1, fm2])

работает абсолютно нормально, выдавая на выходе размер (None, 96, 128) .

Давайте перейдем к 2D-задаче. Теперь у вас есть два тензора (None, 15, 15, 128) и (None, 6, 6, 128) , и вы хотите получить результат (None, 21, 21, 128) размера. Ну, математика здесь не работает. Чтобы понять почему, сократите это до формата 1D. Тогда вы получили

 fm1 -> (None, 225, 128)
fm2 -> (None, 36, 128)
  

С помощью concat вы получаете,

 concatted -> (None, 261, 128)
  

Если математика работает, вы должны получить (None, 441, 128) то, что можно изменить (None, 21, 21, 128) . Таким образом, это не может быть достигнуто, если вы не дополните края меньшего с 441-261 = 180 на измененном тензоре. А затем придайте ему желаемую форму. Ниже приведен пример того, как вы можете это сделать,

 concatted = tf.keras.layers.Lambda(
    lambda x: K.reshape(
                  K.concatenate(
                      [K.reshape(x[0], (-1, 225, 128)), 
                       tf.pad(
                           K.reshape(x[1], (-1, 36, 128)), [(0,0), (0, 180), (0,0)]
                       )
                      ], axis=1
                  ), (-1, 21, 21, 128))
              )([fm1, fm2])
  

Важно: Но я не могу гарантировать производительность вашей модели, это просто решает вашу проблему математически. С точки зрения машинного обучения я бы этого не советовал. Лучшим способом было бы убедиться, что выходные данные совместимы по размерам для конкатенации. Несколько способов могут быть,

  • Не уменьшать размер выходных данных свертки (шаг = 0 и заполнение = ‘то же самое’)
  • Используйте операцию транспонирования свертки, чтобы увеличить меньший размер

Комментарии:

1. Я действительно ценю вашу любезную помощь и подробный ответ. Если у нас есть карты объектов (None, 15, 15, 128) и (None, 6, 6, 128) , как мы их правильно складываем? Было бы неплохо сложить их так, как это делает skip connection? Разве я не должен объединить их в один? Не могли бы вы пояснить, что вы имеете в виду, говоря use transpose convolution operation ... ? Спасибо за ваше время 🙂

2. ничего, если я поделюсь оригинальными идеями, лежащими в основе этого вопроса? если мы собираемся складывать карты объектов с формой (None, 15, 15, 128) и (None, 6, 6, 128) , должен ли результат быть (None,21,21,128) ? Какая наилучшая рекомендуемая практика для применения здесь концепций пропуска соединений? Любые возможные мысли? Большое вам спасибо!

3. @kim я имею в виду транспонирование свертки tensorflow.org/api_docs/python/tf/nn/conv2d_transpose . Обычно я бы не стал использовать соединения skip для объединения выходных данных разного размера. Я бы рекомендовал сделать их одинакового размера, используя один из методов, которые я предложил в ответе.