1.
Идея
Механизм Attention (внимание) в настоящее время встречается в
самых различных архитектурах и задачах (перевод, генерация текста, аннотация
изображений и т.д.).
При работе с естественным языком, каждому слову
в словаре ставится в соответствие вектор с вещественными компонентами (эмбединг слова). Эти векторы поступают на вход нейронной сети с
той или иной архитектурой. Компоненты векторов являются параметрами, которые
подбираются в процессе обучения так, чтобы близкие по смыслу слова имели схожие
векторы. В качестве меры близости обычно выступает косинус угла между
векторами, который определяется их скалярным произведением.
Например, стоит
задача — перевести предложение с французского на русский при
помощи модных нейросетей. Предложение — это цепочка слов, и длины
цепочек в оригинале и в переводе не связаны. Значит, нужна
RNN типа «энкодер-декодер». Энкодер будет двунаправленной RNN, чтобы учитывать
слова не только слева, но и справа.
Энкодер зашифрует все
предложение в единый вектор-контекст. Вектор-контекст — сумма
векторов отдельных слов. Перед тем, как складывать слова, вектора важных слов
умножим на большие числа. Таким образом мы искусственно повысим
значимость важных слов на последующих шагах работы алгоритма. Это
умножение — и есть механизм внимания. После кодирования декодер-RNN
расшифрует вектор-контекст и сделает из него перевод. И этот
перевод будет лучше, чем если бы внимания не было.
Само слово
«внимание» — метафора: алгоритм заставляет нейросеть «сконцентрироваться»
на отдельных элементах рабочего предложения. Так же поступает
и человек: когда переводчик работает с текстом, он больше всего
сосредоточен на переводе текущего слова, учитывает ближайший контекст
до и после него, а если нужно, посматривает на дальние
слова, сильно меняющие смысл. Всю последовательность переводчику запоминать
не обязательно.
2.
Как сделан механизм внимания
в энкодере
Начнем
с двунаправленной RNN. Она уже вычислила векторные представления Y
для каждого слова X. Можно говорить «выучила признаки» слова. Y — это
склеенные вектора активаций слоев A и B (передают контекст слева
направо и справа налево). Если убрать с картинки лишние детали,
получится так
Теперь сверху
появляется первый слой рекуррентного декодера D, который будет принимать
на вход что-то и выдавать перевод первого слова. Перевод выдается
в виде вектора O, сокращенно от output — результат.
Декодеру на вход подается
представление какого-то одного слова — обычно последнего
в предложении, ведь в нем собрался весь прошлый контекст. Однако лучшим
решением будет подать декодеру сумму сразу всех представлений, но перед
этим умножим каждое из них на свой «вес». Вес — это тоже вектор
(на рисунке обозначен символом V). Чем больше вес, тем сильнее нейросеть
обращает внимание на слово.
Нейросеть
сильнее всего обратила внимание на слово Джейн, и почти совсем не посмотрела в
конец предложения, ведь это не нужно
Как определить вес
внимания и важность слова — ниже. Сейчас важно, что из суммы
«взвешенных» (умноженных на вес) векторных представлений Y получается
вектор-контекст C. Именно вектор C, в котором «зашиты» не только
представления каждого слова, но и степень их важности, послужит
«топливом» для декодера.
Еще раз: C = V1Y1
+ V2Y2 + V3Y3 + …. + VnYn.
3.
Как сделан механизм внимания
в декодере
Декодер здесь —
однонаправленная RNN. Это значит, что на каждом шаге он смотрит
на свою прошлую работу и на текущий вектор-контекст C, который
пришел от энкодера. На первом слое декодера вектор C0 активирует
какие-то нейроны, и картина их активации идет на следующий слой
декодера.
На втором шаге
декодирования все повторяется. Сперва рассчитываются новые веса внимания V
для каждого слова. Взвешенная сумма векторов слов становится
вектором-контекстом С1. На вход декодеру приходит его прошлая работа
D0 и новый контекст C1.
Дальше — все
то же самое. Новое слово перевода получится из нового
вектора-контекста и прошлой работы декодера. Так декодер будет
генерировать слова одно за другим, пока не сгенерирует метку конца
предложения.
Как получить вес
внимания и понять, что на самом деле важно «запомнить»? Пускай вес
предсказывает однослойная нейросеть
Важность конкретного
слова зависит от реакции на него энкодера и последней активации
декодера (так решили разработчики). Последняя активация декодера называется
D(t-1). Нынешней активации D(t) пока нет, ее надо вычислить.
Когда декодируется “Африка”, веса
внимания зависят
от D1 и всех Y по очереди
Вес внимания как-то
зависит от двух переменных, но как — непонятно. Если есть
зависимость — есть функция. Она принимает переменные и выдает вес
внимания, и эту функцию никто точно не знает. Нейросети как раз нужны
для того, чтобы моделировать неизвестные функции.
Пусть нейросеть угадывает, как из активации энкодера и декодер
получить вес внимания! Но только очень маленькая, однослойная нейросеть,
потому что угадывать придется много и часто.
Когда декодируется
«Африка», веса внимания зависят от D1 и всех Y
по очереди
Когда
декодируется “Африка”, веса внимания зависят
от D1 и всех
Y по очереди
Маленькая нейросеть,
о которой идет речь, — это матрица весов внимания, которая
«выучивается» при обучении, плюс функция активации. То, что нейросеть
«однослойная», значит, что такая матрица только одна, а то, что
маленькая — значит, у матрицы буквально малая размерность.
Чтобы получить вес
внимания, берется работа энкодера Y, свежую активацию декодера D(t-1),
конкатенируется, умножается на матрицу. Получается вектор L, который пропускается через активационную функцию Softmax и затем получается V, вес внимания.
Сперва конкатенируются вектора Y и D(t-1). Просто два вектора записываются подряд
и получается один: [1, 2] + [3, 4] = [1, 2, 3, 4]. Далее предсказывается L.
«Предсказать вектор
L» — значит умножить входной конкатенированный вектор на матрицу
весов внимания. Предсказание пропускают через функцию активации Softmax, которая превратит вектор L,
в котором может находиться что угодно, в распределение неотрицательных
весов, которые в сумме дают 1.
У каждого
входного слова несколько матриц внимания: по одной на каждый слой
декодера. Каждую матрицу нужно выучить и где-то хранить. Поэтому авторы
отмечают, что «окно внимания» их нейросети — примерно
от 15 до 40 слов. Дальше становится трудно запоминать
контекст. Когда нужно перевести большой текст, «окно внимания» передвигают
по нему «внахлест»: так, чтобы в новое окно поместилось немного
из старого. То есть в окно попадают сначала первые 40 слов,
потом слова с 20 по 60-е, потом с 40 по 80, потом
с 60 по 100 и т. д.