Добавить механизм Внимание для получения тепловых карт на выходе из нейронной сети - PullRequest
0 голосов
/ 21 апреля 2020

У меня есть эта нейронная сеть, которая принимает на входе изображение RGB и 2 других его варианта (фиксированный и динамический c). Я хотел бы добавить механизм «внимания», чтобы иметь на выходе тепловую карту тестовых экземпляров.

def build_model():
  inputRGB = tf.keras.Input(shape=(128,128,3), name='train_ds')
  inputFixed = tf.keras.Input(shape=(128,128,3), name='fixed_ds')
  inputDinamic = tf.keras.Input(shape=(128,128,3), name='dinamic_ds')

    #  RGB images
  rgb = models.Sequential()  
  rgb = layers.Conv2D(32, (5, 5), padding='SAME')(inputRGB)
  rgb = layers.PReLU()(rgb)
  rgb = layers.MaxPooling2D((2, 2))(rgb)
  rgb = layers.BatchNormalization()(rgb)
  rgb = layers.Conv2D(64, (3, 3))(rgb)
  rgb = layers.PReLU()(rgb)
  rgb = layers.Conv2D(64, (3, 3))(rgb)
  rgb = layers.PReLU()(rgb)
  rgb = layers.Conv2D(64, (3, 3))(rgb)
  rgb = layers.PReLU()(rgb)
  rgb = layers.Dropout(0.5)(rgb)
  rgb = layers.GlobalAvgPool2D()(rgb)
  rgb = Model(inputs = inputRGB, outputs=rgb)

    # First type of density 
  fixed = models.Sequential()
  fixed = layers.Conv2D(32, (5, 5), padding='SAME')(inputFixed)
  fixed = layers.PReLU()(fixed)
  fixed = layers.MaxPooling2D((2, 2))(fixed)
  fixed = layers.BatchNormalization()(fixed)
  fixed = layers.Conv2D(64, (3, 3))(fixed)
  fixed = layers.PReLU()(fixed)
  fixed = layers.Conv2D(64, (3, 3))(fixed)
  fixed = layers.PReLU()(fixed)
  fixed = layers.Conv2D(64, (3, 3))(fixed)
  fixed = layers.PReLU()(fixed)
  fixed = layers.Dropout(0.5)(fixed)
  fixed = layers.GlobalAvgPool2D()(fixed)
  fixed = Model(inputs = inputFixed, outputs=fixed)

    # Second type of density
  dinamic = models.Sequential()  
  dinamic = layers.Conv2D(32, (5, 5), padding='SAME')(inputDinamic)
  dinamic = layers.PReLU()(dinamic)
  dinamic = layers.MaxPooling2D((2, 2))(dinamic)
  dinamic = layers.BatchNormalization()(dinamic)
  dinamic = layers.Conv2D(64, (3, 3))(dinamic)
  dinamic = layers.PReLU()(dinamic)
  dinamic = layers.Conv2D(64, (3, 3))(dinamic)
  dinamic = layers.PReLU()(dinamic)
  dinamic = layers.Conv2D(64, (3, 3))(dinamic)
  dinamic = layers.PReLU()(dinamic)
  dinamic = layers.Dropout(0.5)(dinamic)
  dinamic = layers.GlobalAvgPool2D()(dinamic)
  dinamic = Model(inputs = inputDinamic, outputs=dinamic)

  concat = layers.concatenate([rgb.output, fixed.output, dinamic.output])  # merge the outputs of the two models
  k = layers.Dense(1)(concat)

  modelFinal = Model(inputs={'train_ds':inputRGB, 'fixed_ds':inputFixed, 'dinamic_ds':inputDinamic}, outputs=[k])

  opt = tf.keras.optimizers.Adam(learning_rate=0.001, amsgrad=False)


  modelFinal.compile(optimizer=opt , loss='mae', metrics=['mae'])
  return modelFinal

К сожалению, я впервые использую такую ​​механизацию. Из того, что я мог изучить, я должен вставить слой внимания между сцеплением и плотным слоем. Но является ли это правильным способом создания тепловых карт в качестве выхода?

1 Ответ

0 голосов
/ 21 апреля 2020

Уровень внимания, присутствующий в Tensorflow, предназначен для последовательных данных.

В сверточных сетях для изображений используются два различных типа механизмов внимания:

  1. Механизм самоконтроля ( Проверьте эту замечательную medium статью)

  2. Прямое прогнозирование карты веса, добавив свертку 1 x 1 с 1 фильтром после слоя, к которому вы хотите добавить, имея сигмовидную активацию .

  3. Использование гауссовского 2D-внимания, где указаны координаты x и y, для конкретного c ядра.

Однако все эти методы параметризованы и требуют обучения. Ваш вариант использования отличается.

Чтобы получить карту тепла из слоя, я обычно извлекаю ядро ​​с самыми высокими средними значениями активации. Одного этого часто недостаточно, поэтому я использую ядра k с наивысшими средними значениями активации.

Чтобы получить ядро ​​с наивысшими значениями активации, псевдокод:

Выполнить модель на входе с размером партии 1

Извлеките вывод слоя, для которого вы хотите тепловые карты. Это будет иметь форму (1, ч, ш, фильтры). Присвойте это переменной (скажем, «output»)

Выполните GAP для «output» и сожмите, чтобы получить вектор формы (filters,). Argmax этого вектора даст ядру, имеющему наивысшее среднее значение активации. Давайте назовем выходные данные argmax "kernel_number"

Plot "output" [0,:,:, "kernel_number"]. Это тепловая карта, которую вы ищете.

...