#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 для объединения выходных данных разного размера. Я бы рекомендовал сделать их одинакового размера, используя один из методов, которые я предложил в ответе.