Содержание статьи
Внимание — все, что вам нужно: как работает attention в нейросетях
Резюме: что в сухом остатке
При обучении нейросети распознаванию кота на изображениях, для нейросети готовят сет из множества изображений для обучения. В результате она без серьёзных проблем может определить на изображении любителя побегать по квартире в четыре утра.
А в сети всё чаще можно встретить статьи, как научить нейросеть определять числа и знаки на изображении.
В следующих текстах «Системный Блокъ» расскажет о трансформерах — нейросетевых архитектурах, которые не передают информацию с шага на шаг, как это делают RNN, но справляются с задачами обработки последовательностей (типа машинного перевода) не хуже. Основа их работы — именно механизм внимания. Только там внимание устроено еще хитрее, чем описано выше.
Внимание в нейросетях — очень влиятельная идея. Сейчас все самые крутые архитектуры в обработке языка, начиная с GPT-2 от OpenAI и BERT до самых современных, полагаются на механизм внимания. Внимание можно применять не только в обработке текста: если «прикрутить» механизм к сверточным нейросетям, можно визуализировать, на какие части картинки смотрела нейросеть, когда решила, что на ней изобразили собаку.
Декодер здесь — однонаправленная RNN. Это значит, что на каждом шаге он смотрит на свою прошлую работу и на текущий вектор-контекст C, который пришел от энкодера. На первом слое декодера вектор C0 активирует какие-то нейроны, и картина их активации идет на следующий слой декодера.
Проблем у BRNN две. Первая — на слово сильнее всего влияют ближайшие соседи (но это проблема всех рекуррентных нейросетей). Вторая — не всегда можно получить последовательность целиком. С текстом это не сложно, но если вы распознаете речь в реальном времени, придется дождаться, пока человек договорит.
Трансформер — сложная архитектура. Лучше начать с механизма внимания рекуррентных нейросетей, которые все-таки передают информацию с шага на шаг. Так можно сделать, поскольку «внимание» нейросетей изобрели не авторы трансформеров: механизм использовался и раньше, но не был основным.
Итак, основная тема поста — механизм внимания.
Начнем с двунаправленной RNN. Она уже вычислила векторные представления Y для каждого слова X. Можно говорить «выучила признаки» слова. Y — это склеенные вектора активаций слоев A и B (передают контекст слева направо и справа налево).
Если убрать с картинки лишние детали, получится так
Стоит задача — перевести предложение с французского на русский при помощи модных нейросетей. Предложение — это цепочка слов, и длины цепочек в оригинале и в переводе не связаны. Значит, нужна RNN типа «энкодер-декодер». Энкодер будет двунаправленной RNN, чтобы учитывать слова не только слева, но и справа.
Как сделан механизм внимания в энкодере
Маленькая нейросеть, о которой идет речь, — это матрица весов внимания, которая «выучивается» при обучении, плюс функция активации. То, что нейросеть «однослойная», значит, что такая матрица только одна, а то, что маленькая — значит, у матрицы буквально малая размерность.
Чем длиннее путь слова, тем сильнее оно «размывается» в рекуррентной сети, даже если передавать по цепочке не весь контекст, а только важные части (как в LSTM). А отдаленные слова бывают важны. Вот предложение: «Кошка съела рыбу, котлету, сосиску и два блинчика, но все еще была голодна». Чтобы правильно угадать слово «была» (а не «был»), нужно помнить, что в контексте стоит вектор слова «кошка», а не «кот». В нейросети без внимания к вектору «кошки» примешивается вектор «котлеты», «сосиски» и «блинчиков», и к концу предложения уже трудно разобрать, что там стояло в начале.
Технические детали: на каждом шаге элементы вектора контекста возводятся в степень или умножаются, и через несколько шагов их производные либо «взрываются» (стремятся к бесконечности) либо «стираются» (стремятся к нулю). Это называется проблемой затухающих и взрывных градиентов. «Сотрутся» они или «взорвутся», отчасти зависит от того, было ли изначальное значение элемента больше или меньше единицы (если возвести 0,9 в квадрат, получится число меньше изначального, а если 1,1 — больше). Поэтому к концу преобразований всё сильно запутано.
Самая простая архитектура превращает один вектор в другой вектор, пользуясь начальной активацией нейронов a(0). Здесь вообще нет последовательности генерируемых векторов. По сути, это даже не рекуррентная нейросеть, ведь она не передает свое значение никуда дальше. Но ее можно представить как частный случай рекуррентности: пример показывает, что как на входе, так и на выходе нейросети может быть не последовательность, а единственный вектор.
При обучении нейросети распознаванию кота на изображениях, для нейросети готовят сет из множества изображений для обучения. В результате она без серьёзных проблем может определить на изображении любителя побегать по квартире в четыре утра.
А в сети всё чаще можно встретить статьи, как научить нейросеть определять числа и знаки на изображении.
Количество входных слов совпадает с количеством выходных. Так бывает, если пословно дополнять текст. Тогда старые предсказания h становятся новыми входными словами X. Еще так бывает, когда каждому входному слову нужно присвоить какую-то метку, например, 1 — если слово — имя собственное, 0 — если нет. Не всегда длина входной и выходной последовательности совпадают. Вот разные случаи.
Двунаправленная RNN считает контекстом все предложение целиком (или N слов слева и справа). Когда контекст — все предложение, яснее видно, что на каких-то словах нужно фокусироваться сильнее, чем на других. BRNN поможет проиллюстрировать, почему механизм внимания нужен и полезен.
А вот случай, про который уже писали раньше. Ряд векторов — на входе и на выходе, и длины рядов равны. Одинаковость входов и выходов прочно «вшита» в архитектуру: один выходной вектор получается, если нейросеть видит на входе один входной. Все примеры из прошлой статьи — про эту архитектуру.
У всех нейросетей, что передают данные с шага на шаг, есть фундаментальные проблемы. Первая — если данные передаются по цепочке, значит, следующие вычисления не начнутся, пока не закончатся прошлые. Причина — следующий шаг принимает результат предыдущего как переменную.