«Это 15-й день моего участия в ноябрьском испытании обновлений. Подробную информацию об этом событии см.:Вызов последнего обновления 2021 г."
внимание к себе
Самостоятельное внимание стало популярным с введением моделей обработки естественного языка (NLP), называемых «трансформерами». В приложениях НЛП, таких как языковой перевод, моделям часто необходимо читать предложения дословно, чтобы понять их, прежде чем производить вывод. Нейронная сеть, использовавшаяся до появления Трансформера, представляла собой рекуррентную нейронную сеть (RNN) или ее варианты, такие как долговременная кратковременная память (LSTM). RNN имеет свое внутреннее состояние и может лучше обрабатывать информацию о последовательности, например, ввод предыдущих слов в предложении связан с вводом последующих слов. Но у RNN есть и свои недостатки, например, когда количество слов увеличивается, градиент первого слова может исчезнуть. То есть по мере того, как RNN читает больше слов, слова в начале предложения постепенно становятся менее важными. Трансформеры обрабатываются по-разному. Он читает все слова сразу и взвешивает важность каждого слова. Поэтому больше внимания сосредоточено на более важных словах, поэтому это также называется вниманием.
Механизм само-внимания — это вариант механизма внимания, который снижает зависимость от внешней информации и лучше улавливает внутреннюю корреляцию данных или признаков. Самовнимание является краеугольным камнем современных моделей НЛП, таких как BERT и GPT-3.
Самостоятельное внимание в компьютерном зрении
Во-первых, кратко рассмотрим основные моменты сверточных нейронных сетей (CNN): CNN в основном состоит из сверточных слоев. Для сверточного слоя с размером ядра 3×3 он просматривает только 3×3 = 9 признаков во входных активациях (эту область также можно назвать рецептивным полем ядра) для вычисления каждого выходного признака. не смотрите на пиксели за пределами этого диапазона. Чтобы захватить пиксели за пределами этого диапазона, мы можем немного увеличить размер ядра до 5×5 или 7×7, но рецептивное поле все еще мало по сравнению с размером карты признаков.
Мы должны увеличить глубину сети, чтобы рецептивное поле ядра свертки было достаточно большим, чтобы захватить то, что мы хотим. Как и в случае RNN, относительная важность входных признаков уменьшается по мере продвижения по слоям сети. Следовательно, мы можем использовать внутреннее внимание, чтобы наблюдать за каждым пикселем на карте признаков и фокусироваться на более важных пикселях.
Теперь мы изучим, как работает механизм внутреннего внимания. Первым шагом в самовнимании является проецирование каждого входного признака на три вектора, называемые ключом, запросом и значением, хотя эти термины реже встречаются в компьютерном зрении. или НЛП можно лучше понять:
- Значение (значение) представляет входную функцию. Мы не хотим, чтобы модуль внутреннего внимания просматривал каждый пиксель, так как это было бы затратно в вычислительном отношении и было бы ненужным. Вместо этого нас больше интересуют локальные регионы, активированные вводом. Следовательно, значения уменьшают размерность входных признаков как с точки зрения размера карты активации (например, ее можно уменьшить, чтобы иметь меньшую высоту и ширину), так и количества каналов. Для активации сверточного слоя количество каналов уменьшается за счет использования сверток 1x1, а пространственный размер уменьшается за счет максимального или среднего объединения.
- Ключи и запросы используются для вычисления важности функций в графе само-внимания. Для расчета местоположенияВыходная функция при , мы находимся в положениизапросить во всех местах и сравнить его с ключами во всех местах.
Чтобы проиллюстрировать это далее, предположим, что у нас есть портрет, когда сеть обрабатывает один глаз портрета, она сначала сделает запрос, который имеет семантическое значение «глаз», и сверит его с ключами из других областей портрета. Если одним из ключей другой области является глаз, то сеть знает, что она нашла другой глаз, и это та область, на которую сеть обратит внимание, чтобы сеть могла обрабатывать дальше.
В более общем виде, выраженное с помощью математических уравнений: Для функций, мы вычисляем вектор. затем используйтеНормализуйте векторы, чтобы их сумма равнялась 1,0 доллара, что является требуемой оценкой внимания. Используйте оценки внимания в качестве весов для выполнения поэлементного умножения значений для получения результата внимания.
На следующей диаграмме показано, как создается карта внимания из запроса:
Изображение выше красного цвета, а изображение в крайнем левом столбце — это изображение запросов, отмеченных точками. На следующих пяти изображениях показаны карты внимания, полученные в результате запроса. Первая карта внимания вверху запрашивает один глаз кролика; на карте внимания больше белых областей вокруг обоих глаз (указывающих на важные области), а другие области почти полностью черные (менее важные).
Есть несколько способов добиться внимания к себе. На следующем рисунке показан модуль внимания, используемый в SAGAN, где,иСоответствует ключу, запросу и значению:
Большинство вычислений в глубоком обучении векторизованы для повышения скорости, и внимание к себе ничем не отличается. Если для простоты игнорировать размер партии, активации после свертки 1 × 1 будут иметь форму (H, W, C). Первый шаг — преобразовать его в двумерную матрицу формы (В×Ш, С) и использоватьиУмножение матриц для расчета карты внимания. В модуле самоконтроля, используемом в SAGAN, есть еще одна свертка 1×1, чтобы восстановить количество каналов до того же числа, что и количество входных каналов, а затем выполнить операцию масштабирования с обучаемыми параметрами.
Tensorflow реализует модуль самоконтроля
Сначала определите все сверточные слои 1 × 1 и веса в build() пользовательского слоя. Здесь используйтеФункция спектральной нормализацииВ качестве ограничения ядра для сверточного слоя:
class SelfAttention(Layer):
def __init__(self):
super(SelfAttention, self).__init__()
def build(self, input_shape):
n,h,w,c = input_shape
self.n_feats = h * w
self.conv_theta = Conv2D(c//8, 1, padding='same', kernel_constraint=SpectralNorm(), name='Conv_Theta')
self.conv_phi = Conv2D(c//8, 1, padding='same', kernel_constraint=SpectralNorm(), name='Conv_Phi')
self.conv_g = Conv2D(c//8, 1, padding='same', kernel_constraint=SpectralNorm(), name='Conv_g')
self.conv_attn_g = Conv2D(c//8, 1, padding='same', kernel_constraint=SpectralNorm(), name='Conv_AttnG')
self.sigma = self.add_weight(shape=[1], initializer='zeros', trainable=True, name='sigma')
нужно знать, это:
- Внутренние активации могут быть уменьшены в размере, чтобы ускорить выполнение вычислений.
- После каждого сверточного слоя активация преобразуется по форме (H, W, C) в двумерную матрицу формы (H * W, C). Затем мы можем использовать матричное умножение на матрице.
Затем слои соединяются в функции call() для выполнения операции самоконтроля. Рассчитать сначала,и:
def call(self, x):
n, h, w, c = x.shape
theta = self.conv_theta(x)
theta = tf.reshape(theta, (-1, self.n_feats, theta.shape[-1]))
phi = self.conv_phi(x)
phi = tf.nn.max_pool2d(phi, ksize=2, strides=2, padding='VALID')
phi = tf.reshape(phi, (-1, self.n_feats//4, phi.shape[-1]))
g = self.conv_g(x)
g = tf.nn.max_pool2d(g, ksize=2, strides=2, padding='VALID')
g = tf.reshape(g, (-1, self.n_feats//4, g.shape[-1]))
Затем карта внимания будет рассчитана следующим образом:
attn = tf.matmul(theta, phi, transpose_b=True)
attn = tf.nn.softmax(attn)
Наконец, объедините карту внимания с запросомУмножьте и произведите окончательный вывод:
attn_g = tf.matmul(attn, g)
attn_g = tf.reshape(attn_g, (-1, h, w, attn_g.shape[-1]))
attn_g = self.conv_attn_g(attn_g)
output = x + self.sigma * attn_g
return output