Интерпретация документов о внимании (1) | Нелокальная нейронная сеть | CVPR2018 | Воспроизведено

искусственный интеллект

0 Обзор

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

Как сверточные, так и рекурсивные операции работают с локальной окрестностью в пространстве или времени; долгосрочные корреляции могут быть зафиксированы только в том случае, если эти операции применяются многократно, распространяя сигнал пошагово через данные.

Другими словами, в сверточной сети, если вы хотите увеличить поле зрения, вы должны продолжать увеличиватьКоличество сверточных слоев и количество объединяющих слоев, другими словами, увеличение поля зрения увеличивает глубину сети. Это неизбежно приведет к увеличению стоимости расчета, количества параметров, а также необходимости учитывать проблему исчезновения градиента.

  • В НЛП долговременная корреляция относится к корреляции между двумя словами, которые находятся далеко друг от друга в предложении, а в CV — к корреляции между двумя частями, которые находятся далеко друг от друга в изображении. Вообще CNN распознает объекты, и обращает внимание только на пиксели вокруг объекта, и не рассматривает очень дальние места, это тоже особенность CNN, локальное поле зрения. В некоторых случаях это естественное преимущество, а может, конечно, превратиться и в недостаток.

1 Основное содержание

На этот раз мы учимся сначала смотреть на код, а затем анализировать код с бумаги.

1.1 Преимущества нелокального

  • Захват удаленных зависимостей с меньшим количеством параметров и слоев;
  • Подключи и играй

1.2 репродукция питорча

class Self_Attn(nn.Module):
    """ Self attention Layer"""
    def __init__(self,in_dim,activation):
        super(Self_Attn,self).__init__()
        self.chanel_in = in_dim
        self.activation = activation
 
        self.query_conv = nn.Conv2d(in_channels = in_dim , out_channels = in_dim//8 , kernel_size= 1)
        self.key_conv = nn.Conv2d(in_channels = in_dim , out_channels = in_dim//8 , kernel_size= 1)
        self.value_conv = nn.Conv2d(in_channels = in_dim , out_channels = in_dim , kernel_size= 1)
        self.gamma = nn.Parameter(torch.zeros(1))
 
        self.softmax  = nn.Softmax(dim=-1)
    def forward(self,x):
        """
            inputs :
                x : input feature maps( B X C X W X H)
            returns :
                out : self attention value + input feature
                attention: B X N X N (N is Width*Height)
        """
        m_batchsize,C,width ,height = x.size()
        proj_query  = self.query_conv(x).view(m_batchsize,-1,width*height).permute(0,2,1) # B X CX(N)
        proj_key =  self.key_conv(x).view(m_batchsize,-1,width*height) # B X C x (*W*H)
        energy =  torch.bmm(proj_query,proj_key) # transpose check
        attention = self.softmax(energy) # BX (N) X (N)
        proj_value = self.value_conv(x).view(m_batchsize,-1,width*height) # B X C X N
 
        out = torch.bmm(proj_value,attention.permute(0,2,1) )
        out = out.view(m_batchsize,C,width,height)
 
        out = self.gamma*out + x
        return out,attention

1.3 Интерпретация кода

Карта входных объектов — это BatchxChannelxHeightxWidth, мы сначала помещаем эту карту входных объектов x в:

  • Запросите сверточный слой, получите BatchxChannel//8xHeightxWidth
  • ключевой слой свертки, получить BatchxChannel//8xHeightxWidth
  • слой свертки значения, получить BatchxChannelxHeightxWidth

Нам нужно вычислить сходство между запросом и ключевым пикселем за пикселем, и тогда более важны пиксели с высоким сходством, а пиксели с низким сходством не так важны.Каждый пиксель представлен вектором длины канала//8. (Здесь может быть более абстрактно, ведь первоначальный вариант самовнимания находится в области НЛП, а нелокальный скопирован из НЛП, поэтому его нелегко понять напрямую.)

Сходство рассчитывается поумножение векторовЧтобы представить, то мы не должны вычислять сходство пикселей по одному с этим HeightxWidth таким количеством пикселей. Итак, мы конвертируем BatchxChannel//8xHeightxWidth в BatchxChannel//8xN, где N — это HeightxWidth, а N означаетколичество пикселей в изображении.

Затем мы используемtorch.bmm()Чтобы выполнить умножение матриц: перемножьте две матрицы (N, Channel//8) и (Channel//8, N), чтобы получить матрицу (N, N).

Значение элементов i-й строки и j-го столбца в этой (N, N)-матрице представляет собой соотношение между пикселем в позиции i и пикселем в позиции j на рисунке! Затем мы выполняем матричное умножение между матрицей значений и этим (N, N), и результат, полученный таким образом, представляет собой карту объектов, которая учитывает глобальную информацию.

Во втором матричном умножении это умножение (Канал, N) и (N, N), и каждое значение в выходной карте объектов представляет собой средневзвешенное значение N значений, которое также показывает, что выход Каждое значение в объекте map учитывает пиксели всего изображения.

1.4 Интерпретация статьи

На приведенном выше рисунке представлена ​​структурная схема нелокального языка в статье. Видно, что сначала пройти свертку 1х1, уменьшить количество каналов, а потом пройтиθиф\тета и \фиявляются запросом и ключом соответственно, а затем эти две свертки получают матрицу (N, N), которая затем объединяется сgg(значение) для выполнения матричного умножения.

Ну, я признаю, что есть небольшая разница с кодом, но общая идея та же.

2 Резюме

  • После нелокальной карты признаков поле зрения расширяется до полного изображения без добавления большого количества параметров.
  • Однако из-за умножения матрицы BMM график расчета градиента быстро расширяется, поэтому вычисления и память будут занимать много места. Поэтому я добавлю нелокальный слой в глубокий слой сети (когда размер карты признаков мал). но! ! ! В статье постарайтесь поместить его в передний слой, поэтому, когда вычислительная мощность позволит, выдвиньте его вперед.
  • Этот метод действительно улучшился в некоторых задачах, я пробовал его сам, и это нормально.
  • В будущем будет много алгоритмов, чтобы уменьшить потребление этих вычислений. Мы поговорим об этом позже. Если вам это нравится, пожалуйста, подпишитесь и поставьте лайк~
Категории