diff --git a/docs/_config.yml b/docs/_config.yml index e46afeae8..5cea31658 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -688,6 +688,11 @@ ru: - path: ru/week01/01-1.md - path: ru/week01/01-2.md - path: ru/week01/01-3.md + - path: ru/week12/12.md + sections: + - path: ru/week12/12-1.md + - path: ru/week12/12-2.md + - path: ru/week12/12-3.md ################################## Vietnamese ################################## vi: diff --git a/docs/en/week12/12-3.md b/docs/en/week12/12-3.md index cdeab6fd6..6b7149760 100644 --- a/docs/en/week12/12-3.md +++ b/docs/en/week12/12-3.md @@ -284,7 +284,7 @@ Throughout the training of a transformer, many hidden representations are genera We will now see the blocks of transformers discussed above in a far more understandable format, code! -The first module we will look at the multi-headed attention block. Depenending on query, key, and values entered into this block, it can either be used for self or cross attention. +The first module we will look at the multi-headed attention block. Depending on query, key, and values entered into this block, it can either be used for self or cross attention. ```python @@ -392,7 +392,7 @@ Recall that self attention by itself does not have any recurrence or convolution $$ \begin{aligned} -E(p, 2) &= \sin(p / 10000^{2i / d}) \\ +E(p, 2i) &= \sin(p / 10000^{2i / d}) \\ E(p, 2i+1) &= \cos(p / 10000^{2i / d}) \end{aligned} $$ diff --git a/docs/ru/index.md b/docs/ru/index.md index 1dff0c5a6..197308036 100644 --- a/docs/ru/index.md +++ b/docs/ru/index.md @@ -325,6 +325,23 @@ lang: ru 🎥 + + + + Практикум + Вывод для энергетических моделей со скрытыми переменными + + 🖥️ + 🎥 + + + + Обучение энергетических моделей со скрытыми переменными + + 🖥️ + 🎥 + + diff --git a/docs/ru/week12/12-1.md b/docs/ru/week12/12-1.md new file mode 100644 index 000000000..0ccab0ef6 --- /dev/null +++ b/docs/ru/week12/12-1.md @@ -0,0 +1,431 @@ +--- +lang: ru +lang-ref: ch.12-1 +title: Глубокое обучение для обработки естественного языка +lecturer: Mike Lewis +authors: Jiayu Qiu, Yuhong Zhu, Lyuang Fu, Ian Leefmans +date: 20 Apr 2020 +translation-date: 01 Dec 2020 +translator: Evgeniy Pak +--- + + + + +## [Обзор](https://www.youtube.com/watch?v=6D4EWKJgNn0&t=44s) + +* Поразительный прогресс за несколько последних лет : + - Люди предпочитают машинный перевод человеческому для некоторых языков + - Серхчеловеческая производительность на многих выборках данных с ответами на вопросы + - Модели языка генерируют плавные параграфы (например Radford и др. 2019) +* Минимальные специальные техники, необходимые для задач, которые можно решить при помощи довольно общих моделей + + + + +## Модели языка + +* Модели языка присваивают тексту вероятность: + $p(x_0, \cdots, x_n)$ +* Много возможных предложений, значит мы не можем просто обучить классификатор +* Наиболее популярный метод заключается в факторизации распределения, используя цепное правило: + +$$p(x_0,...x_n) = p(x_0)p(x_1 \mid x_0) \cdots p(x_n \mid x_{n-1})$$ + + + +## Нейронные модели языка + +В основном мы вводим текст в нейронную сеть, нейронная сеть подбирает соответствующий вектор для всего контекста. Этот вектор представляет следующее слово и мы получаем некоторую большую матрицу характеристик слов. Эта матрица содержит по вектору для каждого слова, которое может выдать модель. Затем мы вычисляем сходство посредством скалярного произведения контекстного вектора и вектора для каждого слова. Мы получим вероятность предсказания следующего слова, затем обучим эту модель, максимизируя вероятность. Ключевой момент здесь: мы не работаем со словами напрямую, но имеем дело с сущностями, называемыми подсловами или символами. + +$$p(x_0 \mid x_{0, \cdots, n-1}) = \text{softmax}(E f(x_{0, \cdots, n-1}))$$ + +
+ +
Рис.1 : Нейронная модель языка
+
+ + + + +### Свёрточные модели языка + +* Первая нейронная модель языка +* Интерпретирует каждое слово как вектор, являясь таблицей поиска, по отношению к матрице характеристик, таким образом слово получит один и тот же вектор независимо от того, в каком контексте оно появляется +* Применяет одну и ту же сеть с прямой связью на каждом временном шаге +* К сожалению, история с фиксированной длиной означает, что она может быть обусловленна только ограниченным контекстом +* У этих моделей есть преимущество быстродействия + +
+ +
Рис.2 : Свёрточная модель языка
+
+ + + + +### Рекуррентные модели языка + +* Наиболее популярный подход вплоть до недавних лет +* Концептуально прямолинейны: на каждом временном шаге мы поддерживаем некоторое состояние (полученное из предыдущего временного шага), которое представляет то, что мы уже прочитали до сих пор. Это комбинируется с текущим прочитанным словом и используется в последующих состояниях. Затем мы повторяем этот процесс столько временных шагов, сколько нам необходимо. +* Пользуется неограниченным контекстом: в принципе название книги повлияет на скрытое состояние последнего слова в книге. +* Недостатки: + - Вся история чтения документа сжимается в вектор фиксированной размерности на каждом временном шаге, что является узким местом этой модели + - Градиенты имеют тенденцию исчезать при длинном контексте + - Нет возможности параллелизации по временным шагам, отсюда медленное обучение. + +
+ +
Рис.3 : Рекуррентная модель языка
+
+ + + +### [Модель языка трансформер](https://www.youtube.com/watch?v=6D4EWKJgNn0&t=828s) + +* Новейшая модель, используемая в естественной обработке языка +* Революционный штраф +* Три основных этапа + * Входной этап + * $n$ блоков трансформеров (кодирующих слоёв) с различными параметрами + * Выходной этап +* Пример с 6 модулями трансформерами (кодирующими слоями) в статье первоисточнике о трансформерах: + +
+ +
Рис.4: Модель языка трансформер
+
+ +Подслои соединяются посредством элементов, отмеченных "Add&&Norm". Часть "Add" означает остаточное соединение, которое помогает остановить исчезание градиента. Норма здесь обозначает нормализацию слоя. + +
+ +
Рис.5: Кодирующий слой
+
+ +Следует отметить, что трансформеры делятся весами между временными шагами + + + + + +# Многоголовое внимание + +
+ +
Рис.6: Многоголовое внимание
+
+ + +Для слов, которые мы пытаемся предсказать, мы вычисляем значения, называемые **query(q)**. Все предыдущие слова, используемые для предсказания, мы называем **keys(k)**. Запрос - это то, что говорит о контексте, например предыдущие прилагательные. Ключ - это что-то наподобие метки, содержащей информацию о текущем слове, такую как является ли оно прилагательным или нет. После вычисления q, мы можем получить распределение предыдущих слов ($p_i$): + +$$p_i = \text{softmax}(q,k_i)$$ + +Затем мы также вычисляем величины, называемые **values(v)** для предыдущих слов. Значения представляют содержимое слов. + +Как только мы получили значения, вычисляем скрытые состояния, максимизируя распределение внимания: + + $$h_i = \sum_{i}{p_i v_i}$$ + +Мы вычисляем ту же самую вещь с различными запросами, значениями и ключами множество раз параллельно. Причина в том, что мы хотим предсказать следующее слово, используя различные вещи. Например, когда мы предсказываем слово "единороги", используя три предыдущих слова "Эти" "рогатые" и "серебристо-белые". Мы знаем, что это единорог по словам "рогатый" и "серебристо-белый". Однако, мы можем узнать о множественном числе "единороги" по "Эти". Поэтому мы, вероятно, захотим использовать все три слова,чтобы знать, каким должно быть следующее. Многоголовое внимание - это способ позволить каждому слову посмотреть на несколько предыдущих. + +Одним из больших преимуществ многоголового внимания является его хорошая параллелизуемость. В отличие от RNNs, оно вычисляет все головы модулей многоголового внимания и все временные шаги за раз. Одна из проблем одновременного вычисления всех временных шагов заключается в том, что также возможно смотреть на будущие слова, в то время как мы хотим учитывать только предыдущие. Одно из решений этой проблемы - это так называемая **self-attention маскировка**. Маска - это верхнетреугольная матрица, имеющая нули в нижнем треугольнике и минус бесконечность в верхнем. Эффект добавления этой маски к выходу модуля внимания состоит в том, что каждое слово слева имеет гораздо более высокую оценку внимания, чем слова справа, поэтому модель на практике фокусируется только на предыдущих словах. Применение маски имеет решающее значение в модели языка, поскольку оно делает её математически правильной, однако в кодировщиках текста двунаправленный контекст может быть полезным. + +Одна деталь, заставляющяя модель языка трансформер работать, - добавление позиционных характеристик ко входу. В языке некоторые свойства такие, как порядок важны для интерпретации. Используемая здесь техника заключается в обучении отдельных характеристик на различных временных шагах и добавлении их ко входу, так что теперь вход является суммой вектора слова и позиционного вектора. Это придаёт порядок информации. + +
+ +
Рис.7: Архитектура трансформер
+
+ +**Почему модель так хороша:** + +1. Она даёт прямые соединения между каждой парой слов. Каждое слово может быть напрямую получить доступ к скрытому состоянию предыдущих слов, смягчая исчезание градиентов. Она довольно легко обучает очень дорогие функции. +2. Все временные шаги вычисляются параллельно +3. Self-attention квадратично (все временные шаги могут следить за всеми другими), ограничивая максимальную длину последовательности + + + + +## [Некоторые прёмы (особенно для многоголового внимания и позиционного кодирования) и декодирующие модели языка](https://www.youtube.com/watch?v=6D4EWKJgNn0&t=1975s) + + + +### Приём 1: Широкое применение нормализации слоёв действительно полезно для стабилизации обучения + +- Действительно важно для трансформеров + + +### Приём 2: Разогрев (Warm-up) + график обучения обратный квадратный корень + +- Используйте график скорости обучения: чтобы трансформеры работали хорошо, вы должны сделать скорость обучения линейно-уменьшающейся от нуля до тысячных шагов. + + + +### Приём 3: Тщательная инициализация + +- Действительно полезна для таких задач, как машинный перевод + + + +### Приём 4: Сглаживание меток + +- Действительно полезно для таких задач, как машинный перевод + +Ниже приведены результаты некоторых методов, упомянутых выше. В этих тестах, метрикой справа, называемой `ppl` была перплексия (чем меньше `ppl`, тем лучше) + +
+ +
Рис.8: Сравнение производительности моделей
+
+ +Вы могли видеть, что с появлением трансформеров, производительность значительно улучшилась. + + + +## Некоторые важные факты о моделях языка трансформерах + + - Минимальный индуктивный сдвиг. + - Все слова напрямую связаны, что смягчает исчезание градиентов. + - Все временные шаги вычисляются параллельно. + + +Self-attention квадратично (все временные шаги могут следить за всеми другими), ограничивая максимальную длину последовательности. + +- Поскольку self-attention квадратично, его стоимость растёт линейно на практике, что может вызывать проблемы. + +
+ +
Рис.9: Трансформеры *против* RNNs
+
+ + + +### Трансформеры очень хорошо масштабируются + +1. Неограниченные обучающие данные, даже больше, чем вам нужно +2. GPT 2 использовала 2 миллиарда параметров в 2019 +3. Последние модели используют до 17Млрд параметров в 2020 + + + +## Декодирующие модели языка + +Мы можем сейчас обучить вероятностное распределение по тексту - теперь, по сути, мы можем получить экспоненциально много различных выходов, поэтому мы не можем вычислить максимум. Какой бы выбор вы ни сделали для первого слова, оно может повлиять на все остальные решения. Таким образом, учитывая это, жадное декодирование было представлено следующим образом. + + + +### Жадное декодирование не работает + +Мы берём наиболее вероятное слово на каждом временном шаге. Однако, нет никаких гарантий, что такой подход даст наиболее вероятную последовательность, потому что если вы сделали этот шаг в какой-то момент, у вас нет пути отслеживания предыдущих шагов, чтобы отменить предыдущие решения. + + + +### Полный перебор также невозможен + +Он требует вычисления всех возможных последовательностей и поскольку сложность порядка $O(V^T)$, это будет очень дорого + + + + +## Вопросы и ответы для понимания +1. В чём преимущество многоголового внимания по сравнению с моделью одноголового внимания? + * Чтобы предсказать следующее слово, вам нужно наблюдать несколько различных вещей, другими словами внимание можно сосредоточить на нескольких предыдущих словах, пытаясь понять контекст, необходимый для предсказания следующего слова + +2. Как трансформеры решают информационно узкие места CNNs и RNNs ? + * Модели внимания позволяют установить прямую связь между всеми словами, позволяя каждому слову быть обусловленным всеми предыдущими, эффективно устраняя это узкое место. + +3. Чем трансформеры отличаются от RNN в смысле использования параллелизации GPU? + * Модули многоглового внимания в трансформерах хорошо параллелизуемы, тогда как RNNs - нет, и поэтому рекуррентные сети не могут использовать преимущество GPU технологий. По факту трансформеры вычисляют все временные шаги за раз в один прямой проход. + diff --git a/docs/ru/week12/12-2.md b/docs/ru/week12/12-2.md new file mode 100644 index 000000000..27e206918 --- /dev/null +++ b/docs/ru/week12/12-2.md @@ -0,0 +1,638 @@ +--- +lang: ru +lang-ref: ch.12-2 +title: Декодирующие модели языка +lecturer: Mike Lewis +authors: Trevor Mitchell, Andrii Dobroshynskyi, Shreyas Chandrakaladharan, Ben Wolfson +date: 20 Apr 2020 +translation-date: 03 Dec 2020 +translator: Evgeniy Pak +--- + + + + +## [Лучевой поиск](https://www.youtube.com/watch?v=6D4EWKJgNn0&t=2732s) + +Лучевой поиск - это ещё одна техника декодирования модели языка и генерации текста. На каждом шаге алгоритм отслеживает $k$ наиболее вероятных (наилучших) частичных переводов (гипотез). Оценка каждой гипотезы равна логарифму её вероятности. + +Алгоритм выбирает гипотезы с лучшей оценкой. + +
+
+Рис. 1: Лучевое декодирование +
+ +Как глубоко разветвляется лучевое дерево ? + +Лучевое дерево продолжается, пока не достигнет конца предложения. После вывода конца предложения, гипотеза завершена. + +Почему (в нейронном машинном переводе) очень большие размерности луча часто приводят к пустому переводу? + +В момент обучения алгоритм часто не использует луч, поскольку это очень дорого. Вместо этого используется авторегрессивная факторизация (по данному предыдущему корректному выходу, предсказывает $n+1$ первых слов). Модель не отображает собственные ошибки в процессе обучения, так что возможно появление "бессмыслицы" в луче. + +Сводка: Продолжайте лучевой поиск, пока все $k$ гипотез порождают конечный токен или пока не достигнете максимального предела декодирования T. + + + + +### Семплирование + +Нам может быть не нужна наиболее вероятная последовательность. Вместо этого мы можем семплировать из распределения модели. + +Однако выборка из распределения модели приносит свои проблемы. После "плохого" выбора, модель находится в состоянии, с которым никогда не сталкивалась в процессе обучения, возрастает вероятность продолжения "плохой" оценки. Алгоритм может затем застрять в ужасных циклах обратной связи. + + + + + +### Топ-K семлирование + +Чистая техника семплирования, где вы усекаете распределение до $k$ наилучших и затем перенормализуете и выбираете из распределения. + +
+
+Рис. 2: Топ K семлирование +
+ + + + + +#### Вопрос: Почему Топ-K семплирование работает так хорошо? + +Этот метод работает хорошо, поскольку он по сути пытается предотвратить выход за пределы многообразия хорошего языка, когда мы выбираем что-то плохое, используя только головную часть распределения и обрезая хвостовую часть. + + + + + +## Оценка генерации текста + +Оценка модели языка требует просто вычислить логарифм вероятности выведенных данных. Однако, таким образом сложно оценить текст. Обычно используются метрики совпадения слов с упоминанем (BLEU, ROUGE etc.), но у них есть свои проблемы. + + + + +## Sequence-To-Sequence модели + + + + +### Обусловленные модели языка + +Обусловленные модели языка не подходят для генерации случайых семплов на английском, но они полезны для генерации текста по заданному входу. + +Примеры: + +- По заданному предложению на французском сгенерируйте английский перевод +- По заданному документу сгенерируйте краткое изложение +- По заданному диалогу сгенерируйте следующий ответ +- По заданному вопросу сгенерируйте ответ + + + + + +### Sequence-To-Sequence модели + +Обычно входной текст закодирован. Эта результирующая характеристика известна как "thought vector", которая затем передаётся декодеру для генерации токенов слово за слово. + +
+
+Рис. 3: Thought Vector +
+ + + + + +### Sequence-To-Sequence трансформер + +Sequence-to-sequence варианты трансформеров имеют 2 стека: + +1. Стек кодировщик – Self-attention не маскируется, так что каждый входной токен может смотреть на любой другой токен входа + +2. Стек декодировщик – Помимо использования внимания на себе, он также использует внимание по всему входу + +
+
+Рис. 4: Sequence to Sequence трансформер +
+ +Каждый токен на выходе имеет прямую связь с каждым предыдущим выходным токеном, а также с каждым входным словом. Связи делают модели очень выразительными и мощными. Эти трансформеры улучшили оценку в машинном переводе по сравнению с предыдущими рекуррентными и свёрточными моделями. + + + + + +## [Обратный перевод](https://www.youtube.com/watch?v=6D4EWKJgNn0&t=3811s) + +При обучении этих моделей мы обычно полагаемся на большие объёмы размеченного текста. Хороший источник данных - это отчёты Европейского Парламента - текст вручную переведён на несколько языков, который мы можем затем использовать как входы и выходы модели. + + + + + +### Проблемы + +- Не все языки представлены в Европейском Парламенте, означая, что мы не получим пары переводов по всем языкам, в которых мы можем заинтересоваться. Как мы находим текст для обучения на языке, для которого мы не можем получить данные? +- Поскольку модели как трансформеры намного более производительны при большем количестве данных, как мы используем монолингвистический текст эффективно, *т.е.* нет входных / выходных пар? + +Предположим, мы хотим обучить модель для перевода с немецкого языка на английский. Идея обратного перевода заключается в том, что сперва обучаем обратную модель с английского на немецкий. + +- Используя некоторый ограниченный парный текст, мы можем получать одинаковые предложения на двух различных языках +- Как только мы имеем модель перевода с английского языка на немецкий, переводим множество монолингвистических слов с английского на немецкий. + +Наконец, обучаем модель перевода с немецкого языка на английский, используя немецкие слова, которые были 'обратно переведены' на предыдущем шаге. Отметим, что: + +- Неважно, насколько хороша обратная модель - мы можем иметь зашумленные немецкие переводы, но в итоге чисто перевести на английский. +- Нам нужно обучить модель, чтобы понимать английский хорошо за пределами данных англиских/немецких пар (уже переведённых) - использовать большие объёмы монолингвистических данных на английском языке + + + + + +### Итеративный обратный перевод + +- Мы можем итерировать процедуру обратного перевода, чтобы генерировать ещё больше двунаправленных текстовых данных и достичь лучшей производительности - просто продолжая обучаться на монолингвистических данных. +- Сильно помогает, когда немного параллельных данных + + + + + +## Массивный мультиязычный машинный перевод + +
+
+Рис. 5: мультиязычный машинный перевод +
+ +- Вместо того, чтобы пытаться обучить модель переводить с одого языка на другой, попытаться создать нейронную сеть для обучения переводам на несколько языков. +- Модель изучает некоторую общую языко-независимую информацию. + +
+
+Рис. 6: Результаты мультиязычной нейронной сети +
+ +Отличные результаты, особенно если мы хотим обучить модель переводить на язык, для которого у нас нет много доступных данных (низко ресурсный язык). + + + + + +## Обучение без учителя для естественной обработки языка + +Есть большое количество текстовых данных без какой-либо разметки и немного размеченных данных. Как много мы можем изучить о языке, просто читая неразмеченный текст? + + + + + +### `word2vec` + +Наитие - если слова появляются близко друг к другу в тексте, они вероятно связаны между собой, поэтому мы надеемся, что просто посмотрев на неразмеченный английский текст, мы можем обучиться, что они значат. + +- Целью является изучить векторное пространство представлений слов (изучить характеристики) + +Задача предобучения - замаскируем некоторые слова и используем соседние слова, чтобы заполнить пробелы. + +
+
+Рис. 7: word2vec визуализация маскировки +
+ +Например, здесь, идея заключается в том, что "рогатый" и "седовласый" более вероятно появятся в контексте "единорога", чем какого-то другого животного. + +Возьмём слова и применим линейную проекцию + +
+
+Рис. 8: word2vec характеристики +
+ +Хотим узнать + +$$ +p(\texttt{единороги} \mid \texttt{Эти седовласые ??? были ранее неизвестны}) +$$ + +$$ +p(x_n \mid x_{-n}) = \text{softmax}(\text{E}f(x_{-n}))) +$$ + +Характеристики слов придерживаются некоторой структуры + +
+
+Рис. 9: Пример структуры характеристик +
+ +- Идея заключается в том, что если мы возьмём характеристический вектор для слова "король" после обучения и добавим характеристический вектор для слова "женский" мы получим характеристику, очень близкую к слову "королева" +- Показывает некоторые выразительные разности между векторами + + + + +#### Вопрос: Представления слов зависимы или независимы от контекста? + +Независимы и не имеют представления, как они зависят от других слов + + + + +#### Вопрос: Какой может быть пример ситуации, затруднительный для данной модели? + +Интерпретация слов сильно зависит от контекста. Поэтому на примерах двусмысленных слов - слов, которые могут иметь множество значений - модель будет затрудняться, поскольку характеристические вектора не будут захватывать контекст, необходимый для корректного понимания слова. + + + +### GPT + +Чтобы добавить контекст, мы можем обучить обусловленную модель языка. Затем, по заданной модели языка, которая предсказывает слово на каждом временном шаге, заменяем каждый выход модели на некоторую другую характеристику. + +- Предобучение - предсказываем следующее слово +- Тонкая настройка - заменяем на специфическую задачу. Например: + - Предсказываем где существительное, а где прилагательное + - По заданному некоторому тексту, содержащему обзор с Amazon, предсказать оценку настроения для обзора + +Этот подход хорош, поскольку мы можем использовать модель повторно. Мы предобучаем одну большую модель и можем тонко настраивать её для других задач. + + + + + +### ELMo + +GPT рассматривает только левосторонний контекст, что означает модель не может зависеть от каких-либо будущих слов - это ограничивает, что модель не может делать довольно много. + +Подход заключается в обучении _двух_ моделей языка + +- Одну на тексте слева направо +- Одну на тексте справа налево +- Конкатенируем выходы двух моделей, чтобы получить представление слова. Теперь можно обусловливать на обоих: правостороннем и левостороннем контексте. + +Это до сих пор "поверхностная" комбинация, и мы хотим некоторое более сложное взаимодействие между левым и правым контекстом. + + + + + +### BERT + +BERT похож на word2vec в том смысле, что у нас также есть задача заполнения пробелов. Однако, в word2vec у нас есть линейные проекции в то время, как в BERT есть большой трансформер, которые может посмотреть больше контекста. Для обучения мы маскируем 15% токенов и пытаемся предсказать пробелы. + +Можем увеличить масштаб BERT (RoBERTa): + +- Упростим задачу предобучения BERT +- Увеличим размер батча +- Обучим на большом количестве GPUs +- Обучим на ещё большем количестве текста + +Ещё больше улучшений поверх BERT производительности - в задаче ответов на вопросы сейчас производительность свехрчеловека. + + + + + +## [Предобучение для обработки естественного языка](https://www.youtube.com/watch?v=6D4EWKJgNn0&t=4963s) + +Давайте кратко рассмотрим различные подходы предобучения самостоятельного обучения, разработанные для естественной обработки языка. + +- XLNet: + + Вместо того, чтобы предсказывать все замаскированные токены условно-независимо, XLNet предсказывает замаскированные токены авторегрессивно в случайном порядке + +- SpanBERT + + Маскирует диапазон (последовательность слов) вместо токенов + +- ELECTRA: + + Вместо маскировки слов, мы заменяем токены на похожие. Затем мы решаем задачу бинарной классификации, пытаясь предсказать, где были заменены токены. + +- ALBERT: + + Облегченный Bert: Мы модифицируем BERT и облегчаем его уменьшая количество весов the weights в слоях. Это уменьшает количество параметров модели и сложные вычисления. Интересно, что авторам ALBERT не пришлось сильно жертвовать точностью. + +- XLM: + + Мультиязычный BERT: Вместо подачи английского текста, мы подаём текст из множества языков. Как и ожидалось, она изучает межязыковые соединения лучше. + +Ключевые выводы из различных моделей, упомянутых выше: + +- Много различных задач предобучения работают хорошо! + +- Глубина модели критична, двунаправленные взаимодействия между словами + +- Большой выигрыш от увеличения масштабов предобучения, до сих пор без чётких ограничений. + + +Большинство моделей, обсуждённых выше разработаны для решения задачи классификации текста. Однако, для решения задачи генерации текста, где мы генерируем выход последовательно, очень похоже на `seq2seq` модель, нам нужен немного другой подход для предобучения. + + + + + +#### Предобучение для обусловленной генерации: BART и T5 + +BART: предобучение `seq2seq` модели посредством очищения текста от шумов + +В BART для предобучения мы берём последовательность и искажаем её, маскируя токены случайным образом. Вместо предсказания замаскированных токенов (как в задаче BERT), мы подаём целую искажённую последовательность и пытаемся предсказать искажённую последовательность целиком. + +Этот `seq2seq` подход предобучения даёт нам гибкость в дизайне наших искажённых схем. Мы можем перемешивать предложения, удалять фразы, вставлять новые фразы и т. д. + +BART сопоставим с RoBERTa на задачах SQUAD и GLUE. Однако, он был новым SOTA на обобщениях, диалогах и абстрактных вопросах/ответах выборках данных. Эти результаты усиливают нашу мотивацию для BART, быть лучше в задачах генерации текста, чем BERT/RoBERTa. + + + + + +### Некоторые открытые вопросы в естественной обработке языка NLP + +- Как нам интегрировать мировые знания +- Как нам моделировать длинные документы? (модели на основе BERT обычно используют 512 токенов) +- Как нам лучше всего выполнять многозадачное обучение? +- Можем ли мы выполнять тонкую настройку с меньшим количеством данных? +- Эти модели на самом деле понимают язык? + + + + + +### Резюме + +- Обучение моделей на большом количестве данных лучше, чем явное моделирование лингвистической структуры + +С точки зрения дисперсии смещения, трансформеры малосмещённые (очень выразительные) модели. Подавая этим моделям большое количество текста лучше явного моделирования лингвистических структур (сильно смещённых). Архитектуры должны сжимать последовательность дл прохождения через узкие места + +- Модели могут изучить много о языке, предсказывая слова в неразмеченном тексте. Это оказывается отличной задачей обучения без учителя. Тонкая настройка для специфических задач после проста. + +- Двунаправленность контекста критична + + + + + +### Дополнительные идеи из вопросов после лекции: + +Какими способами можно измерить 'понимание языка’? КАк мы можем узнать, что эти модели действительно понимают язык? + +"Трофей не поместился в чемодан, поскольку он был очень большим”: Разрешить ссылку ‘оно’ в этом предложении сложно для машин. Люди хороши в этой задаче. Есть выборка данных, состоящая из подобных сложных примеров и люди достигают 95% точности на этой выборке. Компьютерные программы были способны достичь лишь около 60% до революции, совершённой трансформерами. Современные модели транфсормеры способны достигать больше 90% на этой выборке данных. Это повзоляет предположить, что эти модели не просто запоминают / эксплуатируют данные, но изучают концепции и объекты посредством статистических шаблонов в данных. + +Более того, BERT и RoBERTa достигают сверхчеловеческой производительности на SQUAD и Glue. Текстовые сводки, сгенерированные BART,смотрятся очень реалистично для людей (высокие оценки BLEU). Эти факты свидетельства того, что модели понимают язык в каком-то плане. + + + + + +#### Приземлённый язык + +Интересно, что лектор (Майк Льюис, Учёный исследователь, FAIR) работает над концепцией, называемой ‘Grounded Language’. Цель этой области исследований создать разоговорных агентов, которые будут способны болтать или вести переговоры. Болтовня и переговоры абстрактные задачи с нечёткими целями по сравнению с классификацией текста или резюмирование текста. + + + + + +#### Можем ли мы оценить, когда модель уже обладает мировыми знаниями? + +‘Мировые знания’ это абстрактная концепция. Мы можем тестировать модели на очень базовом уровне на их мировые знания, спрашивая их простые вопросы о концепциях, которые нам интересны. Модели как BERT, RoBERTa и T5 имеют миллиарды параметров. Учитывая, что эти модели обучаются на большом своде информационного текста, как Википедия, они запомнили бы факты, используя их параметры и смогли бы ответить на наши вопросы. Более того, мы можем также подумать о проведении того же самого теста знаний до и после тонкой настройки модели для какой-либо задачи. Это даст нам представление о том, как много информации "забыла" модель. diff --git a/docs/ru/week12/12-3.md b/docs/ru/week12/12-3.md new file mode 100644 index 000000000..3e95e9603 --- /dev/null +++ b/docs/ru/week12/12-3.md @@ -0,0 +1,886 @@ +--- +lang: ru +lang-ref: ch.12-3 +title: Внимание и Трансформер +lecturer: Alfredo Canziani +authors: Francesca Guiso, Annika Brundyn, Noah Kasmanoff, and Luke Martin +date: 21 Apr 2020 +translation-date: 05 Dec 2020 +translator: Evgeniy Pak +--- + + + + + +## [Внимание](https://www.youtube.com/watch?v=f01J0Dri-6k&t=69s) + +Введём концепцию внимания перед тем, как говорить об архитектуре Трансформеров. Есть два основных типа внимания: self attention *против.* перекрёстного внимания, среди этих категорий мы можем выделить жёсткое *против.* мягкого внимания. + +Как мы увидим позже, трансформеры составлены из модулей внимания, которые являются отображениями множеств, скорее чем последовательностей, что значит мы не навязываем порядок нашим входам/выходам. + + + + + +### Self Attention (I) + +Рассмотрим множество $t$ входов $\boldsymbol{x}$'s: + +$$ +\lbrace\boldsymbol{x}_i\rbrace_{i=1}^t = \lbrace\boldsymbol{x}_1,\cdots,\boldsymbol{x}_t\rbrace +$$ + +гд каждый $\boldsymbol{x}_i$ есть $n$-мерный вектор. Поскольку в множестве есть $t$ элементов, каждый из которых принадлежит $\mathbb{R}^n$, мы можем представить множество как матрицу $\boldsymbol{X}\in\mathbb{R}^{n \times t}$. + +При self-attention внутреннее представление $h$ является линейной комбинацией входов: + +$$ +\boldsymbol{h} = \alpha_1 \boldsymbol{x}_1 + \alpha_2 \boldsymbol{x}_2 + \cdots + \alpha_t \boldsymbol{x}_t +$$ + +Используя матрицу представлений, описанную выше, мы можем записать внутренний слой, как произведение матриц: + +$$ +\boldsymbol{h} = \boldsymbol{X} \boldsymbol{a} +$$ + +где $\boldsymbol{a} \in \mathbb{R}^n$ вектор-столбец с компонентами $\alpha_i$. + +Отметим, что это отличается от внутреннего представления, которое мы видели до сих пор, где входы умножались на матрицу весов. + +В зависимости от ограничений налагаемых на вектор $\vect{a}$, мы получаем жёсткое или мягкое внимание. + + + + + +#### Жётское Внимание + +При жёстком внимании, мы налагаем следующие ограничения на альфы: $\Vert\vect{a}\Vert_0 = 1$. Это значит $\vect{a}$ является унитарным вектором. Следовательно все, кроме одного, коэффициенты в линейной комбинации входов равняются нулю, и внутренние представления сокращаются до входа $\boldsymbol{x}_i$, соответствующего элементу $\alpha_i=1$. + + + + + +#### Мягкое внимание + +При мягком внимании, мы налагаем ограничение $\Vert\vect{a}\Vert_1 = 1$. Внутреннее представление является линейной комбинацией входов, где сумма коэффициентов равна единице. + + + + + +### Self Attention (II) + +Откуда берутся $\alpha_i$? + +Мы получаем вектор $\vect{a} \in \mathbb{R}^t$ следующим образом: + +$$ +\vect{a} = \text{[soft](arg)max}_{\beta} (\boldsymbol{X}^{\top}\boldsymbol{x}) +$$ + +Где $\beta$ представляет параметр обратной температуры $\text{soft(arg)max}(\cdot)$. $\boldsymbol{X}^{\top}\in\mathbb{R}^{t \times n}$ есть транспонированная матрица представлений множества $\lbrace\boldsymbol{x}_i \rbrace\_{i=1}^t$, и $\boldsymbol{x}$ представляет собой набор $\boldsymbol{x}_i$ из множества. Заметим, что $j$-я строка $X^{\top}$ соответствует элементу $\boldsymbol{x}_j\in\mathbb{R}^n$, так что $j$-я строка $\boldsymbol{X}^{\top}\boldsymbol{x}$ является скалярным произведением $\boldsymbol{x}_j$ с каждым $\boldsymbol{x}_i$ из $\lbrace \boldsymbol{x}_i \rbrace\_{i=1}^t$. + +Компоненты вектора $\vect{a}$ также называются "оценки", потому что скалярное произведение двух векторов говорит нам, как направлены или схожи два вектора. Следовательно элементы $\vect{a}$ предоставляют информацию о схожести всего множества с частным $\boldsymbol{x}_i$. + +Квадратные скобки представляют represent необязательный аргумент. Заметим, что если используется $\arg\max(\cdot)$, мы получаем унитарный вектор альф, результирующий в жёсткое внимание. С другой стороны, $\text{soft(arg)max}(\cdot)$ приводит к мягкому вниманию. В каждом случае компоненты результирующего вектора $\vect{a}$ в сумме дают 1. + +Генерируя $\vect{a}$ таким образом даёт их множество, по одному для каждого $\boldsymbol{x}_i$. Более того, каждый $\vect{a}_i \in \mathbb{R}^t$, так что мы можем образовать из альф матрицу $\boldsymbol{A}\in \mathbb{R}^{t \times t}$. + +Поскольку каждое внутреннее состояние является линейной комбинацией входов $\boldsymbol{X}$ и вектора $\vect{a}$, мы получаем множество $t$ внутренних состояний, которые можем объединить в матрицу $\boldsymbol{H}\in \mathbb{R}^{n \times t}$. + +$$ +\boldsymbol{H}=\boldsymbol{XA} +$$ + + + + + +## [Хранилище ключ-значение](https://www.youtube.com/watch?v=f01J0Dri-6k&t=1056s) + +Хранилище ключ-значение - парадигма разработанная для хранения (сохранения), извлечения (запроса) и управления ассоциативными массивами (словарями / хеш-таблицами). + +Например, скажем нам нужно найти рецепт лазаньи. У нас есть книга рецептов и поисковое слово "лазанья" - это запрос. Этот запрос проверяется для каждого возможного из ключей вашей выборки данных - в этом случае это могут быть названия всех рецептов в книге. Мы проверяем как направлен запрос по отношению к каждому названию, чтобы найти максимальную оценку совпадения между запросом и всем соответствующими ключами. Если нашим выходом является функция argmax - мы получаем один рецепт с наивысшей оценкой. В другом случае, если мы используем функцию soft argmax, мы получим вероятностное распределение и можем получить рецепты в порядке от наиболее схожего содержимого до менее и менее релевантного, соответствующего запросу. + +По сути, запрос есть вопрос. По заданному запросу, мы проверяем этот запрос по каждому ключу и получаем всё соответствующее содержимое. + + + + + +### Запросы, ключи и значения + +$$ +\begin{aligned} +\vect{q} &= \vect{W_q x} \\ +\vect{k} &= \vect{W_k x} \\ +\vect{v} &= \vect{W_v x} +\end{aligned} +$$ + +Каждый из векторов $\vect{q}, \vect{k}, \vect{v}$ может быть представлен как поворот определённого входа $\vect{x}$. Где $\vect{q}$ есть просто $\vect{x}$ повёрнутый $\vect{W_q}$, $\vect{k}$ просто $\vect{x}$ повёрнутый посредством $\vect{W_k}$ и аналогично для $\vect{v}$. Заметим, что мы впервые вводим "обучаемые" параметры. Мы также не включаем каких-либо нелинейностей, поскольку внимание полностью опирается на направление. + +Чтобы сравнить запрос с каждым из возможных ключей, $\vect{q}$ и $\vect{k}$ должны быть одинаковой размерности, *т.е.* $\vect{q}, \vect{k} \in \mathbb{R}^{d'}$. + +Однако, $\vect{v}$ может быть любой размерности. Если мы продолжим нажпример с рецептом лазаньи - нам нужно, чтобы запрос имел такую же размерность, как у ключей, *т.е.* названий различных рецептов по которым мы будем искать. Размерность соответствующего полученного рецепта, $\vect{v}$, однако может быть сколь угодно большой. Таким образом мы имеем, что $\vect{v} \in \mathbb{R}^{d''}$. + +Для простоты здесь мы сделаем предположение, что у всего размерность $d$, т.е. + +$$ +d' = d'' = d +$$ + +Так что сейчас у нас есть множество $\vect{x}$-ов, множество запросов, множество ключей и множество значений. Мы можем объединить эти множества в матрицы, каждая с $t$ столбцами, поскольку мы объединяем $t$ векторов; каждый вектор длины $d$. + +$$ +\{ \vect{x}_i \}_{i=1}^t \rightsquigarrow \{ \vect{q}_i \}_{i=1}^t, \, \{ \vect{k}_i \}_{i=1}^t, \, \, \{ \vect{v}_i \}_{i=1}^t \rightsquigarrow \vect{Q}, \vect{K}, \vect{V} \in \mathbb{R}^{d \times t} +$$ + +Мы сравниваем один запрос $\vect{q}$ с матрицей всех ключей $\vect{K}$: + +$$ +\vect{a} = \text{[soft](arg)max}_{\beta} (\vect{K}^{\top} \vect{q}) \in \mathbb{R}^t +$$ + +Затем внутренний слой будет линейной комбинацией столбцов $\vect{V}$, взвешенной коэффициентами из $\vect{a}$: + +$$ +\vect{h} = \vect{V} \vect{a} \in \mathbb{R}^d +$$ + +Поскольку у нас $t$ запросов, мы получим $t$ соответствующих $\vect{a}$ весов и следовательно матрицу $\vect{A}$ размерности $t \times t$. + +$$ +\{ \vect{q}_i \}_{i=1}^t \rightsquigarrow \{ \vect{a}_i \}_{i=1}^t, \rightsquigarrow \vect{A} \in \mathbb{R}^{t \times t} +$$ + +Следовательно в матричной записи мы имеем: + +$$ +\vect{H} = \vect{VA} \in \mathbb{R}^{d \times t} +$$ + +Отдельно мы обычно устанавливаем $\beta$ значение: + +$$ +\beta = \frac{1}{\sqrt{d}} +$$ + +Это делается для того, чтобы поддерживать постоянную температуру на протяжении различных выборов размерности $d$, и поэтому мы делим на квадратный корень числа измерений $d$. (Подумайте какая длина вектора $\vect{1} \in \R^d$.) + +Во время реализации мы можем ускорить вычисления объединяя все $\vect{W}$-ки в одну $\vect{W}$ и затем вычислить $\vect{q}, \vect{k}, \vect{v}$ за один проход: + +$$ +\begin{bmatrix} +\vect{q} \\ +\vect{k} \\ +\vect{v} +\end{bmatrix} = +\begin{bmatrix} +\vect{W_q} \\ +\vect{W_k} \\ +\vect{W_v} +\end{bmatrix} \vect{x} \in \mathbb{R}^{3d} +$$ + +Существует также концепция "голов". Выше мы видели пример с одной головой, но у нас может быть много голов. Например, скажем у нас $h$ голов, значит у нас $h$ $\vect{q}$-ек, $h$ $\vect{k}$-ек и $h$ $\vect{v}$-ек и мы получаем вектор из $\mathbb{R}^{3hd}$: + +$$ +\begin{bmatrix} +\vect{q}^1 \\ +\vect{q}^2 \\ +\vdots \\ +\vect{q}^h \\ +\vect{k}^1 \\ +\vect{k}^2 \\ +\vdots \\ +\vect{k}^h \\ +\vect{v}^1 \\ +\vect{v}^2 \\ +\vdots \\ +\vect{v}^h +\end{bmatrix} = +\begin{bmatrix} +\vect{W_q}^1 \\ +\vect{W_q}^2 \\ +\vdots \\ +\vect{W_q}^h \\ +\vect{W_k}^1 \\ +\vect{W_k}^2 \\ +\vdots \\ +\vect{W_k}^h \\ +\vect{W_v}^1 \\ +\vect{W_v}^2 \\ +\vdots \\ +\vect{W_v}^h +\end{bmatrix} \vect{x} \in \R^{3hd} +$$ + +Однако, всё ещё можем преобразовать многоголовые значения, чтобы иметь изначальную размерность $\R^d$, используя $\vect{W_h} \in \mathbb{R}^{d \times hd}$. Это просто один из возможных способов реализации хранилища ключ-значение. + + + + + +## [Трансформер](https://www.youtube.com/watch?v=f01J0Dri-6k&t=2114s) + +Расширяя наши знания о внимании в частности, мы теперь интерпретируем фундаментальные строительные блоки трансформера. В частности, мы возьмём прямой проход через базовый трансформер, и посмотрим, как внимание используется в стандартной парадигме кодировщик-декодировщик и сравним последовательные архитектуры с RNNs. + + + + + +### Архитектура Кодировщик-Декодировщик + +Мы уже знакомы с этой терминологией. Наиболее заметно это было показано на примере автокодировщика, и необходимо понимание этого момента. Резюмируя, вход подаётся в кодировщик и декодировщик налагает некоторого рода ограничения на данные, стимулируя использовать только самую важную информацию. Эта информация сохранена в выходе кодирующего блока, и может быть использована в множестве не связанных задач. + +
+
+Рисунок 1: Два примера диаграм автокодировщика. Модель слева показывает, как автокодировщик может быть спроектирован с двумя аффинными преобразованиями + активациями, где изображение справа заменяет единственный "слой" на произвольный модуль операций. +
+ +Наше "внимание" изображено на схеме автокодировщика, как показано в модели справа, и сейчас заглянем внутрь в контексте трансформеров. + + + + + +### Модуль Кодировщик + +
+
+Рисунок 2: Кодировщик трансформера, которые принимает множество входов $\vect{x}$, и выводит множество внутренних представлений $\vect{h}^\text{Enc}$. +
+ +Кодирующий модуль принимает множество входов, которые сразу подаются на блок self attention и проходят через него, достигая блока `Add, Norm`. В этот момент, они снова проходят через 1D-Свёртку и другой `Add, Norm` блок, и в результате выводятся как мнрожество внутренних представлений. Это множество внутренних представлений затем либо проходит через произвольное число кодирующих модулей (*т.е.* больше слоёв), либо через декодировщик. Теперь обсудим эти блоки более подробно. + + + + + +### Self-attention + +Модель self-attention есть обычная модель внимания. Запросы, ключи и значения сгенерированы из того же самого последовательного входа. В задачах, которые пытаются моделировать последовательные данные, позиционные кодировщики добавляются перед этим входом. Вход этого блока есть взвешенные вниманием значения. Блок self-attention принимает множество входов, из $1, \cdots , t$, и выводит $1, \cdots, t$ взевешнных вниманием значений, которые проходят через остальную часть кодировщика. + +
+
+Рисунок 3: Блок self-attention. Последовательность входов изображена как множество в третьем измерении и сконкатенирована. +
+ + + + + +#### Сумма, Норма + +Блок суммы нормы содержит два компонента. Первый - это блок суммы, который есть остаточное соеденение, и нормализация по слою. + + + + + +#### 1D-свёртка + +Продолжая этот шаг, применяется 1D-свёртка (позиционная прямая сеть). Этот блок состоит из двух полносвязных слоёв. В зависимости от заданных значений, этот блок позволяет вам настраивать размеры выхода $\vect{h}^\text{Enc}$. + + + + + +### Модуль декодировщик + +Декодировщик трансформера следует процедуре, похожей на кодировщик. Однако, тут есть дополнительный блок, который принимается во внимание. Дополнительно, входы этого модуля различны. + +
+
+Рисунок 4: Более дружелюбное объяснение декодировщика. +
+ + + + + +#### Перекрёстное-внимание + +Перекрёстное внимание следует настройке запросов, ключей и значений, используемой в блоках self-attention. Однако, входы немного более сложные. Вход в декодировщик - это точка данных $\vect{y}\_i$, которая затем проходит через self attention и блоки суммы нормы, и наконец завершается блоком перекрёстного внимания. Это служит запоросом перекрёстного внимания, где пары ключей и значений есть выходы $\vect{h}^\text{Enc}$, где этот выход рассчитывается со всеми прошлыми входами $\vect{x}\_1, \cdots, \vect{x}\_{t}$. + + + + + +## Резюме + +Множество от $\vect{x}\_1$ до $\vect{x}\_{t}$ проходит через кодировщик. Используя self-attention и несколько других блоков, получаем представление выхода $\lbrace\vect{h}^\text{Enc}\rbrace_{i=1}^t$, которое подаётся на декодировщик. После применения к нему self-attention, применяется перекрёстное внимание. В этом блоке запрос соответствует представлению символа в целевом языке $\vect{y}\_i$, а ключ и значения из предложения на исходном языке (от $\vect{x}\_1$ до $\vect{x}\_{t}$). Интуитивно, перекрёстное внимание находит, какие значения во входной последовательности наиболее релевантны к построению $\vect{y}\_t$, и затем заслуживают наивысшие коэффициенты внимания. Выход этого перекрёстного внимания затем проходит через ещё один блок 1D-свёртки, имеем $\vect{h}^\text{Dec}$. Для указанного целевого языка, отсюда легко увидеть, как начать обучение, сравнивая $\lbrace\vect{h}^\text{Dec}\rbrace_{i=1}^t$ с некоторыми целевыми данными. + + + + + +### Мировые модели языка + +Есть несколько важных фактов, которые мы опустили выше, чтобы объяснить наиболее важных модулей трансформера, но нам нужно обсудить их сейчас, чтобы понимать, как трансформеры могут достичь state-of-the-art результатов в задачах языка. + + + + + +#### Позиционное кодирование + +Механизмы внимания позволяют нам параллелизовать операции и сильно ускорить время обучения модели, но теряется последовательность информации. Функция позционного кодирования позволяет нам захватить этот контекст. + + + + + +#### Сематические представления + +На протяжении обучения трансформера, генерируется множество внутренних представлений. Чтобы создать пространство характеристик, подобное тому, которое использовалось в примере модели мирового языка на PyTorch, выход перекрёстного внимания предоставит семантическое представление слова $x_i$, после чего можно проводить дальнейшие эксперименты на этой выборке данных. + + + + + +### Резюме кода + +Сейчас мы увидим блоки трансформера, обсуждённые выше в намного более понятном формате, давайте кодить! + +Первый модуль, который мы рассмотрим - блок много-голового внимания. В зависимости от запроса, ключа и значений поданных на вход этого блока, он может быть использован, либо для self-attention, либо для перекрёстного внимания. + + +```python +class MultiHeadAttention(nn.Module): + def __init__(self, d_model, num_heads, p, d_input=None): + super().__init__() + self.num_heads = num_heads + self.d_model = d_model + if d_input is None: + d_xq = d_xk = d_xv = d_model + else: + d_xq, d_xk, d_xv = d_input + # Embedding dimension of model is a multiple of number of heads + assert d_model % self.num_heads == 0 + self.d_k = d_model // self.num_heads + # These are still of dimension d_model. To split into number of heads + self.W_q = nn.Linear(d_xq, d_model, bias=False) + self.W_k = nn.Linear(d_xk, d_model, bias=False) + self.W_v = nn.Linear(d_xv, d_model, bias=False) + # Outputs of all sub-layers need to be of dimension d_model + self.W_h = nn.Linear(d_model, d_model) +``` + + +Инициализация класса многоголового внимания. Если подан `d_input`, он становится перекрёстным вниманием. В ином случае - self-attention. Настройка запроса, ключа, значения строится как линейное преобразование входа `d_model`. + + +```python +def scaled_dot_product_attention(self, Q, K, V): + batch_size = Q.size(0) + k_length = K.size(-2) + + # Scaling by d_k so that the soft(arg)max doesnt saturate + Q = Q / np.sqrt(self.d_k) # (bs, n_heads, q_length, dim_per_head) + scores = torch.matmul(Q, K.transpose(2,3)) # (bs, n_heads, q_length, k_length) + + A = nn_Softargmax(dim=-1)(scores) # (bs, n_heads, q_length, k_length) + + # Get the weighted average of the values + H = torch.matmul(A, V) # (bs, n_heads, q_length, dim_per_head) + + return H, A +``` + +Возвращает внутренний слой, соответствующий кодам значений после масштабирования вектором внимания. Для целей учёта (какие значения в последовательности были замаскированы вниманием?) A также возвращается. + +```python +def split_heads(self, x, batch_size): + return x.view(batch_size, -1, self.num_heads, self.d_k).transpose(1, 2) +``` + +Разделим последнюю размерность на (`heads` × `depth`). Возвращает результат после транспонирования в форме (`batch_size` × `num_heads` × `seq_length` × `d_k`) + +```python +def group_heads(self, x, batch_size): + return x.transpose(1, 2).contiguous(). + view(batch_size, -1, self.num_heads * self.d_k) +``` + +Комбинирует головы внимания вместе, чтобы получить правильную форму, совместимую с размером батча и длиной последовательности. + +```python +def forward(self, X_q, X_k, X_v): + batch_size, seq_length, dim = X_q.size() + # After transforming, split into num_heads + Q = self.split_heads(self.W_q(X_q), batch_size) + K = self.split_heads(self.W_k(X_k), batch_size) + V = self.split_heads(self.W_v(X_v), batch_size) + # Calculate the attention weights for each of the heads + H_cat, A = self.scaled_dot_product_attention(Q, K, V) + # Put all the heads back together by concat + H_cat = self.group_heads(H_cat, batch_size) # (bs, q_length, dim) + # Final linear layer + H = self.W_h(H_cat) # (bs, q_length, dim) + return H, A +``` + +Прямой проход многоголового внимания. + +Заданные входы разделяет на q, k и v, после чего эти значения проходят через масштабированное скалярное произведение механизма внимания, конкатенируются и проходят через конечный линейный слой. Последний выход блока внимания есть полученное внимание, и внутреннее предстваление, которое проходит через остальные блоки. + +Следующий блок, демонстрируемый в трансформере/кодировщике, является Суммой,Нормой, которые являются функциями, уже встроенными в PyTorch. Таким образом, это чрезвычайно простая реализация, и для неё не нужен отдельный класс. Затем идёт 1-D свёрточный блок. Пожалуйста обратитесь к предыдущим разделами для более подробной информации. + +Теперь, когда все наши основные классы построены (или встроены для нас), мы перейдём к модулю кодировщику. + +```python +class EncoderLayer(nn.Module): + def __init__(self, d_model, num_heads, conv_hidden_dim, p=0.1): + self.mha = MultiHeadAttention(d_model, num_heads, p) + self.layernorm1 = nn.LayerNorm(normalized_shape=d_model, eps=1e-6) + self.layernorm2 = nn.LayerNorm(normalized_shape=d_model, eps=1e-6) + + def forward(self, x): + attn_output, _ = self.mha(x, x, x) + out1 = self.layernorm1(x + attn_output) + cnn_output = self.cnn(out1) + out2 = self.layernorm2(out1 + cnn_output) + return out2 +``` + +В самых мощных трансформерах произвольно большое количество этих кодировщиков соединены друг с другом. + +Вспомните, что self attention само по себе не имеет каких-либо циклов или свёрток, но это то, что позволяет выполнять его так быстро. Чтобы сделать его чувствительным к положению, мы обеспечиваем позиционные кодировки. Они вычисляются следующим образом: + + +$$ +\begin{aligned} +E(p, 2i) &= \sin(p / 10000^{2i / d}) \\ +E(p, 2i+1) &= \cos(p / 10000^{2i / d}) +\end{aligned} +$$ + + +Чтобы не занимать слишком много места на мелких деталях, мы отсылаем вас к https://github.com/Atcold/pytorch-Deep-Learning/blob/master/15-transformer.ipynb для полного кода, использованного здесь. + + +Весь кодировщик, с N последовательными слоями кодировщиками, а также позиционные характеристики, написаны следующим образом: + + +```python +class Encoder(nn.Module): + def __init__(self, num_layers, d_model, num_heads, ff_hidden_dim, + input_vocab_size, maximum_position_encoding, p=0.1): + self.embedding = Embeddings(d_model, input_vocab_size, + maximum_position_encoding, p) + self.enc_layers = nn.ModuleList() + for _ in range(num_layers): + self.enc_layers.append(EncoderLayer(d_model, num_heads, + ff_hidden_dim, p)) + def forward(self, x): + x = self.embedding(x) # Transform to (batch_size, input_seq_length, d_model) + for i in range(self.num_layers): + x = self.enc_layers[i](x) + return x # (batch_size, input_seq_len, d_model) +``` + + + + + +## Пример использования + +Есть множество задач, где вы можете использовать только Кодировщик. В прилагаемой рабочей тетради, мы увидим, как кодировщик может быть использован для анализа настроений. + +Используя выборку данных обзоров imdb, мы можем выводить из кодировщика скрытое представление последовательности текста, и обучить этот процесс кодирования с двоичной перекрёстной энтропией, соответствующей положительному или негативному обзору фильма. + +Опять мы опускаем азы, и направляем вас к рабочей тетради, но здесь есть наиболее важные компоненты архитектуры, используемые в трансформере: + + + +```python +class TransformerClassifier(nn.Module): + def forward(self, x): + x = Encoder()(x) + x = nn.Linear(d_model, num_answers)(x) + return torch.max(x, dim=1) + +model = TransformerClassifier(num_layers=1, d_model=32, num_heads=2, + conv_hidden_dim=128, input_vocab_size=50002, num_answers=2) +``` +Где эта модель обучается типичным образом. diff --git a/docs/ru/week12/12.md b/docs/ru/week12/12.md new file mode 100644 index 000000000..6bea6d8f9 --- /dev/null +++ b/docs/ru/week12/12.md @@ -0,0 +1,30 @@ +--- +lang: ru +lang-ref: ch.12 +title: Неделя 12 +translation-date: 01 Dec 2020 +translator: Evgeniy Pak +--- + + + +## Часть A лекции + + + +В этом разделе мы обсуждаем различные архитектуры, используемые в приложениях обработки естественного языка, начиная с CNNs, RNNs, и, в конечном итоге, рассматривая state-of-the-art архитектуру, трансформеры. Затем мы обсуждаем различные модули, которые включают трансформеры и то, как они дают преимущество трансформерам в задачах естественной обработки языка. В итоге мы обсудим приёмы, позволяющие эффективно обучать трансформеры. + + + +## Часть B лекции + + + +В этом разделе мы знакомим с лучевым поиском как золотой серединой между жадным декодированием и полным перебором. Мы рассматриваем случай, когда требуется выборка из порождающего распределения (*т.e.* при генерации текста) и вводим понятие "top-k" выборки. Затем мы знакомим с моделями sequence to sequence (в варианте трансформера) и обратным переводом. После рассматриваем подход обучения без учителя к обучению характеристик и обсуждаем word2vec, GPT и BERT. + + +## Практикум + + + +Вводим понятие внимания, фокусируясь на self-attention и его представлениях входов на скрытом слое. Затем мы представляем парадигму хранилища ключ-значение и обсуждаем, как представить запросы, ключи и значения, как повороты входов. Наконец мы используем внимание для интерпретации архитектуры трансформер, взяв результат прямого прохода через базовый трансформер и сравнивая парадигму кодирования-декодирования с последовательной архитектурой.