ym104432846
Вставьте ссылку на видео из Youtube, Rutube, VK видео
Задайте вопрос по видео
Что вас интересует?
00:00:32
Определение задачи машинного перевода:
  • Машинный перевод относится к классу задач Sequence-to-sequence.
  • Цель – перевести текст с одного языка на другой, максимизируя вероятность правильной выходной последовательности.
00:02:59
Метрики оценки качества перевода:
  • Первоначально рассматривается использование точности (precision) как метрики, но это не подходит из-за многозначности переводов.
  • Предлагается использовать метрику BLEU, которая оценивает совпадения n-грамм в переводе и целевом тексте.
00:04:47
Архитектура Encoder-Decoder:
  • Используется архитектура Encoder-Decoder с рекуррентными блоками.
  • Encoder обрабатывает входную последовательность, создавая сжатое представление, которое передается Decoder.
00:07:46
Реализация архитектуры:
  • Создаются токенайзеры для английского и русского языков.
  • Данные очищаются, нормализуются и разбиваются на тренировочную и валидационную выборки.
  • Модели реализованы с использованием LSTM слоев и встраиваемых представлений (embeddings).
00:18:16
Проблемы обучения и способы их решения:
  • Причина плохого обучения – ошибка декодера накапливается и распространяется.
  • Применяется Teacher Forcing для улучшения обучения, повышая стабильность и качество.
00:24:41
Механизм внимания (Attention):
  • Идея механизма внимания заключается в выборе релевантных частей исходного текста для каждого шага генерации.
  • Вектор внимания рассчитывается как взвешенная сумма скрытых состояний энкодера, использующая softmax.
00:34:11
Поиск оптимальной последовательности вывода:
  • Бим-серч (Beam Search) используется для поиска наиболее вероятной полной последовательности.
  • Метод предполагает одновременное отслеживание нескольких наиболее вероятных путей.
00:43:45
Заключение и дальнейшие направления:
  • Рассмотрены идеи механизмов внимания и Beam Search.
  • Подчеркнута важность этих подходов в области NLP, включая распознавание речи и обработку естественного языка.
0: Всем привет. Сегодня мы с вами поговорим про задачи машинного перевода, про то, как в принципе её решать. В частности, мы обсудим самый интуитивно понятный метод, самый простой метод.
1: Вот, и также мы поговорим про другие, немножко про другие вариации архитектур, которые мы сегодня заиспользуй и как и почему их нужно использовать для задачи машинного перевода, собственно,
2: Что такое задача машинного перевода? Это задача из разряда сёк ту сёк, то есть sequence to sequence, последовательность, последовательность. Мы переводим текст на на исходном языке в текст на целевом языке, если
3: У нас есть входная последовательность, и мы хотим найти последовательность игрек такую что вероятность получить последовательность игрек при условии x. Она максимальна собственно, все просто и понятно, что у нас на последовательность игрек накладываются определённые усло.
4: В частности, что это последовательность токенов на на каком целевом языке, в частности, сегодня мы будем решать задачи перевода из английского языка в русский. На самом деле достаточно непростая задача. Для нас. Вполне понятно, как переводить, если
5: У нас покой, словарь если мы помним правила, то нам в целом понятно, как переводить текст с 1 языка на другой, но как это делать модели давайте мы будем решать такую же задачу, только у нас будет условие не только на последовательность x на после.
6: Последовательность на исходном языке, но и будет условие на параметр нашей модели, то есть при условии x y при условии параметров нашей модели.
7: Вот, собственно, в каком-то смысле мы функционируем примерно также мы своего рода нейронная сеть, я сам своего рода нейронка. Собственно, здесь при такой формулировке встают уже знакомые нам вопросы, которыми вы уже
8: Других задачах задавались, в частности, какую модель нам использовать, как оценивать качество, как выучить параметр тета и как в целом, выучив вот эту вот вероятность нам искать наилучший игрек со звездой последовательности на инференсе, на
9: Использовании сети. Для начала, прежде чем решать задачу, давайте поймём, как нам вообще оценивать успешность решения нашей задачи. В частности, встаёт вопрос качества. Мы, вообще говоря, будем решать задачу в каком-то смысле как задачу класс
10: То есть мы будем предсказывать токен за токеном. Вы уже знаете, что текст у нас, у нас разделяется на токены, разделяется на в нашем случае буквы, мы будем в качестве токенов использовать буквы и с этими токенами.
11: Уже идёт работа как с отдельными элементами текста. Собственно, мы будем решать задачу перевода как задачу классификации, а мы будем предсказывать класс токена в каком-то конечном пространстве, то есть в каком-то конечном наборе токенов, в частности букв, которые, как мы понимаем,
12: Конечное количество и 1 мысль, которая приходит к нам на ум, это, а давайте мы будем оценивать качество как задачу классификации, то есть, собственно, точность или precision, или прикол будем брать грубо.
13: Говоря, вот 1 мысль, которая приходит на ум, типа задача классификации. Давайте решайте как задачу классификации, но на самом деле это не есть хорошо в нашем конкретном случае. Почему вы можете поставить видео на паузу?
14: Подумать сами, а теперь я отвечу, потому что перевод может быть разным, то есть мы с вами сами по себе часто сталкивались с такой ситуацией, что одно и то же предложение, один и тот же текст можно перевести с 1 и тем же смыслом.
15: Разными словами, с разной последовательностью слов, особенно для русского языка, это очень типичная ситуация, поэтому просто оценивать качество перевода как в задаче классификации нам не подходит. Поэтому давайте мы придумаем другой способ. Как раз на такой
16: Случай есть метрика блео, что она нам даёт, что она нам позволяет подсчитывать если кратко и на пальцах, то это точность на языке грамм. То есть мы проверяем, как часто встречаются те или иные 4 граммы, в частности, 4 граммы, в на
17: Нашем тексте в соответствии с целевым текстом, с целевым, то есть который у нас есть, есть пара текст на исходном языке и текст на целевом языке. И вот мы, переведя исходный текст на целевой язык, как-то
18: Пытаемся сравнивать с нашими таргетами, с нашими текстами. Метрика блево на самом деле считается достаточно сложно, но смысл её примерно таков. Её значение у нас лежит от нуля до единицы. И, в частности, если лорана единичке, то
19: Это очень хорошо. Если нолик, то все-таки плоховато. Давайте теперь перейдём к моделям, которые мы с вами сегодня рассмотрим. В частности, это архитектура энкодер декодер, который вам, вам знакома с
20: Работа с картинками, в частности, там очень много архитектур в формате кодер декодер, но здесь мы данную архитектуру построим на на то есть на на рекуррентных блоках сейчас, сегодня это будут. У нас есть вот такой вот инкодер.
21: Куда мы подаём на вход наш текст, который у нас есть на исходном языке. И мы вот через это боттлнек, через некоторое представление, которое есть скрытое состояние после прогона по всему тексту, мы её зас.
22: Decoder и decoder авторегрессионно, то есть последовательно, предсказывает каждый токен, то есть он получил на вход токен сос старт оф сентенс и скрытое состояние инкодера, он предсказал токен, который будет следующим подал.
23: Его сам себе на вход взял своё скрытое состояние и так далее. Пошёл предсказывать токены, пока в итоге не получил токен. Но сентенс
24: Вот, собственно, таким вот образом мы и будем 1 способом решать нашу задачу. И давайте напишем для этого дела код. Вот здесь немного текстом мы расписали данную архитектуру, чтобы вам было
25: Понятнее, что здесь происходит? Да, в качестве токенов мы будем использовать, во первых, буквы русского и английского алфавита, пробел и знаки препинания и цифры.
26: Для того, чтобы отслеживать качество обучения в онлайне, то есть не залазя никуда, мы можем открыть стенсер ворд и, собственно, использовать его для отслеживания успешности обучения наших сеточек. Код, который представлен перед вами.
27: Этого приспособлен. Для начала мы импортируем все необходимые нам модули и, в частности, сам райтер это как раз вот
28: Класс своего рода класс для работы с тем. И мы также создадим объект лео метрик, который позволит нам впоследствии успешно посчитать метрику блео. Дальше мы
29: Имеем ячейку с глобальными переменными, где мы задаём все параметры нашего обучения. В частности, будем мы использовать дирекшнл слои, то есть влево и вправо значение для стартового токена.
30: Для конечного токена и так далее. А дальше давайте мы просто скачаем наши данные простой командой запросто че кол, чтобы, чтобы скачать наши данные. А дальше мы, мы создадим модельку, папочку для модельки. Куда
31: Там будем сохранять наши веса, наши результаты.
32: Метод чистки текста, он на самом деле зависит от задачи, но в нашем случае это будет просто приведение нижний регистр и и фильтровка символов русских и английских, ну и
33: И упомянутых ранее знаков, то есть цифр, знаков препинания и так далее. Мы ради интереса напишем, собственно, токенизатор по буквам, чтобы мы видели, как это все происходит внутри. В частности, мы, мы пишем
34: Класс токенайзер. Здесь мы передаём на вход сос еос анон и пад токены.
35: И дальше мы просто создаём все необходимые нам словари сейчас токен то id x idx, то токен, в частности, чтобы нам токены как-то пронумеровать и далее более просто оформлять решение задачи классификации дальше напишем метод.
36: А токенизации текста конверт, токен, икс. В общем, здесь, я думаю, все просто и из названий понятно, что что эти методы делают, в частности, конвертируют последовательность токенов в айдишники.
37: Токенов конвертирует текст в айдишники и так далее.
38: Здесь мы будем готовить наш токенизатор по пути до текстов, потому что впоследствии нам так удобнее определять токенайзер.
39: И дальше давайте считаем все данные и разделим их на тренировочные эволюционные выборки, в частности, просто разделив это явным образом на файлики час x rain пас, то есть текст на исходном языке мы, мы сохраним в отдельный
40: Файлик и пас и так далее. Собственно, собственно тренировочный набор данных и валидационный набор данных. Мы их отфильтруем по длине русского текста и возьмём, допустим, границу в
41: 100 символов вроде 100, да 100 символов на русском языке.
42: И дальше давайте подготовим наш x токенайзер, игрек, токенайзер, потому что, вообще говоря, токенизатор для разных текстов, они разные.
43: Дальше мы реализуем наш кастомный, наш собственный класс датасет, ну, который нам будет выплёвывать кусочки данных бачи, чтобы нам более удобно, более комфортно обучать наши модели.
44: Очень прост. Мы просто чистим текст и конвертируем текст в айдишники, и в конец мы добавляем до максимальной длины, до максимальной длины последовательности наши паддинги, то есть пад токены.
45: Включаем тензор с эриком мы поступаем аналогично.
46: А теперь давайте мы, мы создадим нашу инкодер декодер модель, а здесь у нас что происходит? Мы создаём слой эмбеддингов, мы будем их обучать на ходу, а также создаём лстм кусочек нашей сети и аналогично поступаем для декодер. То есть мы создаём слой эмбеддингов и
47: Слои, а вот и как раз и будет нам предсказывать наш класс каждого токена на каждом шаге здесь мы вытащим истинную длину в токенах нашего исходного текста.
48: Через, через эмбеддинг и плотненько упакуем, чтобы более удобно подсчитать проход стмк инкодера через наши иксы, через нашу исходную последовательность. Более эффективно подсчитать этот проход. Мы, собственно, собственно,
49: Создаём пакт сиквенс, то есть, то есть плотно упакованную последовательность, как она там плотно упакована. На самом деле не так, чтобы очень важно и прогоняем через инкодер, и вытаскиваем из инкодера его вот скрытое состояние, мы
50: Немного решейп, и дальше мы уже будем подавать его на вход декодера. Час на никодерм мы будем подавать на вход ему при state и токен айди. В частности, это будет sos токен, то есть старт.
51: Токен возьмём у этого токена от этого токена эмбеддинг сначала и затем подадим в декодер. Дальше мы выход декодер прогоним через линейный слой декодер, который нам, собственно, предска.
52: Вероятности класса, ну, вообще говоря, логиты, но не суть важно. И на данном этапе мы будем просто выбирать наиболее вероятный токен, как все здоровые люди это обычно и делают. Вот.
53: Собственно, все дальше мы просто создадим наши датасеты, дата лоудеры, создадим нашу модельку. Все как обычно. Ничего нового и дальше мы сдадим лос функцию.
54: Изатор райтер, то есть наш объект, который будет как раз в тензер ворд все выписывать и лямда функция, а также мы будем использовать скедулер. Это некоторое расписание измен.
55: Нашего, чтобы более тонко шло обучение нашей модельки.
56: И напишем также функцию, которая будет нам отрисовывать, отписывать какие наши рандомные примеры. В частности, 1, 3, минус 1. Просто от Балды. Мы, собственно, это делаем, чтобы отслеживать как-то состояние нашего обучении.
57: Также мы напишем функцию, которая, которая будет обрезать все, что после еос токена. Это как раз для подсчёта метрики блео, на самом деле сильно вникать в то, что написано здесь, не нужно, потому что здесь мы просто подгоняем
58: Наши, наши данные под вид, который принимает этот вот наш объект Бо метрик.
59: И дальше мы напишем функцию тренировки на на 1 эпохе. Здесь для вас все, мне кажется, должно быть достаточно знакомо. В частности, мы просто тренируемся по по тренировочному дата лоудеру, прогоняем модель.
60: Считаем ответы, считаем лосс функцию немного потише пив и немного попотев с размерами перед этим и попотев над тем, что нам нужно, что нам не нужно, и также мы будем немножко
61: Чтобы обучение шло более стабильно.
62: Дальше мы делаем шаг, шаг оптимизатора, запоминаем лос, запоминаем в целом тренировочный лосс на этой эпохе и делаем некоторый логгинг. В частности делаем логгинг. Также и консоль, чтобы нам было тоже
63: Возможно немного так отслеживать. Если вдруг с, то пойдёт что-то не так. На самом деле в коллабе периодически такое есть что-то не очень хорошо работает и
64: Поэтому для перестраховки нам удобно иметь некоторые принты с рисовкой лосса в консоль.
65: Вот, собственно, здесь некоторый логгинг, где мы нарисовам несколько примеров из нашего бача и добавляем данные в наш райтер, то есть наш Тенцер. И также мы иногда делаем скендер степ, то есть немножко меняем наш
66: В частности, мы умножаем его на константу меньше единицы, ну и после Прихода эпохи мы также будем подсчитывать блео, чтобы отслеживать, что происходит на тренировке.
67: Аналогичным образом мы напишем валидацию. Единственное, добавив, чтобы вычисления здесь происходили несколько быстрее и все, а все остальное здесь примерно такое же и будем на на нулевом.
68: Шаге валидации смотреть несколько примеров, потому что валидация у нас на самом деле небольшая и в целом мы просто хотим посмотреть на какой-то кусочек, как успешно наша сеть работает на валидации и также будем считать блео на валидации.
69: И напишем теперь функцию трейн, потому что вообще мы будем обучать несколько моделек и функция трейн у нас будет как раз организованно обучение какой-нибудь 1 модельки в общем стиле. Здесь тоже все просто мы интегрируемся по эпохам и
70: И запускаем тренировку 1 эпохи на каждой эпохе, а также запускаем валидацию на каждой эпохе, правда, неожиданно, и также делаем некоторый логгинг в наш тензер порт, если он валидация меньше, чем уже найденный.
71: Лучший лос, то тогда мы будем сохранять наши модельки папочку модуль нейм. Её мы будем передавать в качестве параметра функции. Train
72: Ну и давайте обучим нашу базовую инконито модельку.
73: На самом деле я уже её обучил, и здесь есть небольшой логгинг на этот счёт, чтобы посмотреть на то, как она училась и как успешно научилась.
74: Вот на 1 эпохе мы видим вот такое предложение, в ответе что-то странное и в тархете что-то вот такое видим, что все как-то не очень хорошо. И давайте посмотрим сразу на интересное и посмотрим на то, что
75: Происходит в конце.
76: Я обучал 10 эпох для того, чтобы как-то посмотреть результаты, этого должно хватить. Ну, такие примерные результаты на самом деле можно обучать и больше. Ну вот, допустим, на Валида.
77: Предложения и наш вот перевод нашей модельки. Видим, что все-таки как то не очень хорошо она работает, потому что слова все-таки несколько разные, несколько другие. Возможно, это свя.
78: Связано ещё с не очень высоким качеством данных, потому что в целом перевод может быть совершенно разный. Его могут составлять разные люди. В разный момент времени переводы будут разные, и нам задачи машинного перевода нужно с этим как-то мириться. Ну и
79: Видим, что есть некоторые заикания, некоторые такие вот моменты. В общем, че то перевела, че то научилась, но как то как-то хотелось бы получше собственно, как это сделать? В чем у нас проблема с тем, как мы обучали до
80: Проблема в том, что моделька учится с нуля, то есть она просто берет и
81: Учится на наших данных вроде и хорошо, вроде и не очень, потому что если декодер у нас начинает генерить токены и в какой-то момент ошибается, то все пиши пропало, потому что дальше предсказания декодера они будут
82: Неверными. И на самом деле сложно как-то оценивать то, что декодер говорит дальше как на этом обучаться. Поэтому вот метод тичер форсинг, что нам даёт, что он нам позволяет сделать, он нам даёт
83: Опцию подкидывать, подкладывать верхние токены в какие-то рандомные моменты времени. То есть у нас декодер берет, предсказывает 1 токен, 2 токен, 3 токен. И мы на каждой вот этой вот операции. 1, 2, 3 с какой-то вероятностью, вместо того чтобы
84: Подложить то, что предсказал нам декодер. Мы, мы подкладываем верхний токен, то есть мы его знаем, у нас есть какой-то набор текстов, мы будем его подкладывать в какие-то моменты времени.
85: В частности, на данный момент я поставил вероятность порсинга 0 5, вот обучение 0 5. Видимо, вот здесь вот закралась опечатка. Давайте её сразу поправим, чтобы никого не смущать.
86: И, собственно, да, будем, будем подкладывать верхний токен. И таким образом, последующие операции при обучении они уже не будут бесполезны, потому что мы какие-то моменты подложили токен, верхний токен и дальше уже, вообще говоря, в нашем
87: Предположение. Декодер должен работать хотя бы приблизительно, верно?
88: Собственно, давайте мы создадим нашу инкор модель, да, и определим переменную равно 0 5. То есть, а 0 5 мы будем подкладывать верхний токен. Понятно, что здесь мы
89: Быть проблемы, в частности, часто такая проблема, как переобучение нашей сети. Но давайте попробуем посмотрим, че он нам скажет на тренировке и сделаем дальше выводы на нашем опыте, потому что набивать шишки бывает
90: Полезно. Собственно, мы создадим нашу папочку для нашей новой модельки. Создадим объект нашей модельки и дальше определим райтер новый райтер и оптимизатор. И скелер новый для нашей модельки на са.
91: На самом деле я уже обучил модельку, вы можете запустить и попробовать это ещё раз. Здесь я дообучал 1 эпоху.
92: Здесь, в общем, 10 эпох. Вот что у нас по результатам я напомню, что это не 1 эпоха, а какая-то из последующих, потому что пришлось запускать обучение модельки ещё раз и здесь
93: Мы уже видим, что как минимум на тренировке все очень хорошо, почему же так произошло лукавый вопрос в студию.
94: То есть уже что-то чуть более осмысленное нам даёт наша моделька отдалённо, но все-таки получше. Почему так происходит? А почему так происходит тренировки? Потому что часть токенов мы с вами знаем, вообще говоря, половину, то есть
95: Как-то по тренировке успешности нашей модели не приходится. Вот давайте посмотрим на валидацию, что у нас здесь происходит вот такое предложение и мы
96: Казываем вот следующую вещь. На территории отеля предоставляется бесплатная парковка и целевое предложение территории отеля. Есть частная парковка. Ну, как минимум уже без ошибок, уже чуть лучше.
97: Чем было. И вот, допустим, также можем посмотреть на перевод вот здесь.
98: Гости могут пользоваться полотенца и постельное белье ну не очень хорошо, но уже вроде получше, чем было самое интересное, что loss на валидации у нас сильно больше чем лос на тренировке, но на самом деле.
99: Валидация все-таки не показывает реальное положение дел, давайте вы немножко подумаете, почему поставить на паузу и мы пойдём дальше, а на самом деле почему же loss на валидации нам не даёт особой информации, потому что это
100: Los у нас, как мы с вами могли заметить, это кроссэнтропия, то есть los, функция для задачи классификации. А как мы обсудили выше метрики для задачи классификации лос функции для задачи классификации они все-таки не очень хороши именно в задаче машинного перевода, поэтому
101: С этим приходится что-то делать, как-то жить. И в частности метрика блео нам немного в этом может помочь, но
102: Но она не подсчитана, поэтому придётся как-то думать, и в частности, мы видим, что здесь у нас вполне все неплохо и очень даже симпатичные переводы с некоторыми ошибками, но уже что-то, что-то
103: Что-то на самом деле нам есть что улучшать, то есть есть определённые проблемы, как нам улучшать то, что у нас есть. Давайте подумаем, что у нас происходит глобально, у нас есть инкодер, есть декодер и нам из
104: Иконе декодер подаётся просто какая-то агрегированная информация. На самом деле даже нам сложно, прочитав 1 раз исходное предложение, получить в итоге перевод того предложения. То есть, да, некоторые особо одарённые ребята могут это сделать, но
105: Мне самому, допустим, бывает достаточно сложно. Вот и модельки, на самом деле это достаточно сложно по какой-то агрегированной информации, как-то её вытащить оттуда, собрать в кучку и дать декодеру, чтобы он из неё как-то вы
106: Убрал ненужное, взял нужное и как-то перевёл.
107: В общем, нам это сложно, сложно брать вот полностью агрегированную информацию. Хочется как-то все-таки поглядывать на то, а что у нас было в исходном предложении.
108: То есть нам хочется, чтобы декодер как-то смотрел на то, что было, как-то обращал внимание на то, что было, на какие-то кусочки, которые были до этого.
109: И в связи с этим мы приходим к идее внимания, к идее аттеншен, которую мы с вами сейчас и обсудим. То есть мы дадим декодеру возможность как-то взвешивать кусочки из исходного предложения, насколько они важны ему в данный момент. То есть мы
110: Хотим как-то взвесить. И, собственно, когда мы переводим предложение, мы это и делаем, мы берём, читаем исходное предложение, начинаем переводить и в каждый момент времени, ну или не в каждый момент времени мы можем
111: Взглянуть на исходное предложение и понять, на что нам стоит обратить внимание именно в данный момент, что нам действительно важно именно сейчас, а что нам понадобится позже? Теперь давайте наконец определим, а как нам определять, насколько
112: Важно для текущего состояния декодера каждое из состояний, из скрытых состояний инкодера. Как это можно сделать? 1, что приходит на ум, можно посчитать просто скалярное произведение, использовать эту чиселку как некоторую характеристику, то есть
113: Мы берём и смотрим, насколько близки наши вектора, насколько близко скрытое состояние инкодера, какой-то предыдущий момент времени, когда мы гнали инкодер через наш текст и и смотрим на близость выхода нашего декодера.
114: Момент времени все логично, все просто. Но вообще эта чиселка достаточно разная может быть. То есть это может быть, вообще говоря, какое угодно число. А нам хотелось бы все-таки что то в районе от нолика до единички, потому что мы
115: Привыкли к таким чиселкам. И все-таки нам хочется, чтобы, вообще говоря, все веса для скрытых состояний инкодера, они были в сумме равны единичке, а потому что все-таки, как мы, хочется, чтобы сохранялось как-то.
116: Исходная информация, то есть как бы не становилась её больше в каком-то смысле. Поэтому что в целом предлагается сделать, предлагается взять вот эти вот все скалярные произведения, возможные с нашим выходом, декодер.
117: На текущем этапе и всех состояний инкодера взять, Клян, произведение и для них сделать софт. Макс. Почему так? Потому что мы можем и это даст нам то, что мы хотели, то, что мы хо,
118: Хотим получить и как вариант, мы можем вместо просто выхода декодера на вход декодер подавать не только выход предыдущего и токен, который был сгенерирован на предыдущей итерации, но и
119: И вот этот вот атеншен, то есть мы просуммируем наше вот скрытое состояние инкодера с этими вот весами и подадим на вход нашему декодеру на следующей итерации. То есть своего рода мы
120: Ещё раз посмотрели на наше исходное предложение на исходном тексте и как-то взвесили вот токены этого предложения и получили ееще агрегированную информацию, но уже под другим углом. То есть мы
121: Мы посмотрели именно в данный момент времени, что нам важно из этого текста, и вычленили наиболее важный кусочек. На самом деле делается в жизни примерно так, как я и сказал, но с некоторыми нюансами на самом деле мы можем
122: Брать не чисто наше скрытое представление декодера или скрытое представление инкодера, а как-то их преобразовывать, потому что все-таки они участвуют в другом контексте, потому что они участвуют в другой ситуации, и поэтому мы применяем к ним
123: Преобразование, то есть мы их немножко изменяем как бы под другой контекст нашей ситуации. Поэтому прежде чем взять скалярное произведение вот скрытого представления декодера представления, а мы их
124: На некоторые, на некоторые весовые матрички. И будем действовать, собственно, таким образом, как я и сказал выше.
125: Давайте на это посмотрим собственно, у нас что здесь происходит. У нас будет некоторая матричка, дубль вэ к и double the ку. Собственно, это наши матрички преобразования, которые будут как раз умножаться на
126: На скрытое состояние инкодера и на скрытое состояние декодера, и матричка дубль вэ в это матричка, которая будет преобразовывать нам скрытое состояние инкодера в значение, которые будут у нас уже иметь место на последнем этапе.
127: Вычисления, та, когда мы, собственно, берём и вычисляем взвешенную сумму наших скрытых состояний, потому что, опять же, контекст использования скрытого состояния конера, он уже немножко другой
128: Вот, и мы, что с вами делаем? Мы считаем наше ку. То есть некоторые представления от скрытого состояния декодера. Мы считаем-ка некоторое представление о скрытых состояний инкодера и счи.
129: Также некоторые представления о скрытых состояний инкодера.
130: И вот в этом объекте у нас будет подсчитываться то, что я и сказал выше давайте к нему вернёмся.
131: Здесь будет подписы, подсчитываться следующее мы q будем умножать на-ка. То есть мы будем, как я уже сказал, перемножать вот эти вот вектора, вычитать скалярное произведение их и делить некоторый коэффициентик, этот коэффициентик мы будем выделять как
132: Размер наших екторов это нужно для лучшей стабильности наших вычислений, для сохранения распределений всяких. В общем, пока это такой глубокий нюанс.
133: Вот. И дальше мы просто вот это Скляр произведение будем считать софт Макс и перемножать на вот нашу матричку в наше вот тоже представление кодера под другим углом. Собственно, здесь оно и
134: И давайте добавим аттеншен нашу модель. Здесь у нас все знакомо. Единственное добавится объект аттеншн.
135: Мы будем работать без траута, потому что пока он нам не нужен.
136: И дальше мы также, как и делали до этого, прогоняем инкодер, в частности, вычисляем бейлинги инкодера, упаковываем плотненько наш, наши имбединги, нашу пакт сиквенс и дальше прогоняем инкодер и, собственно,
137: Все, все вытаскиваем, все наши скрытые. Мы также здесь вытаскиваем, распаковав обратно последовательность.
138: И дальше мы делаем тоже самое. То есть берём преф токен, айди икс, то есть мы создаём тензер с sos токенами сос айдишниками. Дальше берём мб идикое.
139: И вытаскиваем предыдущее состояние декодера, в частности, на самый 1 декодера. Это скрытое состояние, как не сложно догадаться, это итоговое скрытое состояние инкодера дальше прогоняем.
140: Через предыдущее состояние декодера и 2 скрытых состояния инкодера, то есть мы q будем вычислять по скрытым состоянию декодера, а-ка и the мы будем по инкодер вычислят.
141: Как мы и обсудили выше, мы представляем скрыт состояние, она в немножко другом виде, потому что мы уже работаем с ними немного в другом контексте. Нам нужно с ними поработать с точки зрения декодера.
142: Вот, и дальше мы будем просто брать и в декодер передавать эмбеддинг токена и out нашего аттеншена, а дальше мы уже на этом будем гнать наш декодер и наш линейный слой, который
143: Возвращать вероятности нахождения токенов вот в данном конкретном месте.
144: И давайте теперь мы обучим нашу, нашу этеншн модельку.
145: И сразу посмотрим в самый конец а мы уже в самом конце и видим что че то как-то не очень на самом деле че то не очень хорошо получилось как с этим быть, почему так произошло потому что attention на самом деле.
146: Получается достаточно сложно и достаточно долго. То есть нам нужно с этим быть аккуратнее. Возможно где-то с коэффициентами че то не то произошло, но здесь вы можете вполне спокойно с этим поиграть, повозиться, и я думаю,
147: У вас получится обучить это дело лучше, чем получилось у меня, но тем не менее мы видим, что вот, допустим, здесь все прошло достаточно неплохо. То есть перевод тоже вполне вполне себе состоявшийся, на самом деле какой-то существенный прирост.
148: Механизм внимания даёт только на таких более длинных последовательностях, а здесь у нас последовательности были длинны около 100 около 100 символов на русском языке.
149: То есть мы именно по русскому языку, и здесь какого-то серьёзного прироста не получится, потому что русский язык, он такой более размашистый, скажем так, английский, он более сжатый. То есть предоставление инкодера у нас на самом деле не очень много.
150: Теперь давайте перейдём к другому вопросу. А как нам выбирать наилучшую последовательность на инференсе? То есть какую из предложенных последовательностей нам использовать. До этого мы с вами делали достаточно, просто мы на каждой такое выбирали наиболее
151: Вероятный токен, просто взяли его и все и говорим вот это вот нам надо вот это вот мы хотим использовать. Давайте вспомним, что жадная стратегия, вообще говоря, далеко не всегда приводит нас к успеху. В частности, наиболее Ясный, наиболее известный на мой
152: Пример это задача рюкзаке, где жадная стратегия просто пух и прах проигрывает чему-то более осмысленному, потому что она несостоятельна именно для данной задачи в частности. А почему мы вообще используем
153: Жадную стратегию в нашей задаче. Ведь, вообще говоря, нам нужна именно наиболее вероятная, полная последовательность. То есть мы хотим наиболее вероятную, полную последовательность текста. Где у нас гарантия, что если мы будем брать наиболее
154: Токен. На каждом этапе мы получим наиболее вероятную, полную последовательность. Очевидно, что такой гарантии нет, и нам с этим хочется что-то сделать. То есть давайте все-таки решать нашу исходную задачу. То есть давайте мы
155: Будем пытаться искать наиболее вероятную, полную последовательность. А для этого, что нам нужно сделать? Давайте вы поставите на паузу секунду подумаете, а я расскажу.
156: Собственно, что нам нужно сделать? Нам нужно взять исходную последовательность на исходном языке, прогнать её через инкодер, взять представление инкодеров и начать запускать наш декодер. То есть мы предсказали 1 токен, но, вообще говоря, не
157: Сказали, предсказали вероятности для токенов, находящихся на 1 месте, и для каждого из этих токенов, запустить декодера и получить уже вероятности для для последовательности из 2.
158: Символов, но кажется понятным, что дальше это делать не нужно, потому что у нас здесь уже возникают проблемы. В частности, это очень долго. То есть, если у нас токенов на целевом языке 100, то вариантов последовательность длины 4
159: Это 100 в 4 степени, это уже очень много, а потому что на потому что это очень много. То есть такой подход нам, вообще говоря, не подходит. То есть хочется вроде бы что-то среднее. То есть у нас есть жадная стратегия, где мы берём
160: На 1 токен есть такая вот серьёзная, сугубо строгая, жёсткая мысль по поводу вот такого вот поиска. Давайте что-то среднее возьмём. А зачем нам брать в целом 1
161: Токен 1 наиболее вероятный токен. Давайте мы будем брать, например, 3 наиболее вероятных токена на 1 итерации, и из каждого из них пытаться продолжать наше дерево вариантов, дерево последовательностей и для для 1 ни
162: Более вероятного мы запустим наш следующий декодера для 2 запустим также и для 3 запустим также и из того, что у нас получилось. Мы вновь выберем 3 наиболее вероятных, наиболее подходящих нам варианта. То есть мы на каждый
163: Уже не будем брать только 1 вариант, а мы будем брать несколько вариантов, и в каждый момент времени у нас будет сколько-то наиболее убедительных, наиболее подходящих нам вариантов. Да, разумеется, здесь у нас тоже может быть проблема.
164: И что мы, по сути, все ещё не можем решать нашу исходно поставленную задачу, но шансов найти именно решение поставленной задачи у нас уже сильно больше, потому что вариантов у нас уже сильно.
165: Больше которых мы рассматриваем. В частности, я вам рассказал про идею. Бимсерч. Это идея такого вот поиска по дереву, где мы храним на каждой последующей итерации определённое количество наших вот этих вот вариантов. Давай
166: Давайте ещё раз пробежимся по этой вот идее. Мы, мы берём на 1 итерации токен сос, мы его прогоняем через наш декодер. Берём-ка наиболее вероятных токен. Допустим, 3. С каждым таким токеном мы прогоняем наш декодер ещё на 1 итерации. Почему?
167: С каждым токеном в отдельности, потому что у нас вообще моделька авторинна, то есть выход дикона зависит от входного токена, который мы ему дали.
168: И мы, мы берём, прогоняем декодер через каждый из этих токенов и получаем 3 умножить на количество токенов наших вариантов, последовательностей и уже из 2 символов. И мы вот из этих последовательностей длины
169: 2 символа должны выбрать 3 наиболее подходящих, наиболее вероятных. То есть мы уже работаем с последовательностями какой-то длины и в каждый момент у нас есть к наиболее вероятных последовательностей. Давайте рассмотрим вот такой пример у нас
170: На самом деле, уже на нём жадная стратегия даст сбой, потому что вот у нас 1 токен, з, если бы мы действовали жадно, то мы бы выбрали следующим словом nice, а потом вумен.
171: Но посмотрим, что вероятность этой последовательности всего 0 2. А теперь давайте мы воспользуемся методом бимсерч и бимсерч нам бы уже разрешил эту ситуацию, потому что у нас
172: Было бы уже 2 варианта the dog has и the nice woman, и мы понимаем, что the dog has у нас имеет вероятность больше, чем предыдущая, то есть вероятность 0 36.
173: Это существенно больше, чем наш 1 вариант, который нам дала бы жадная стратегия.
174: Вот здесь небольшое у нас есть объяснение ещё раз по этому поводу, и давайте мы реализуем наш бимсерч, вынесем в отдельную функцию часть, где мы вычисляем выход инкодера.
175: Также создадим класс бимсерч ноут, где этот класс будет нам характеризовать как раз вот узел нашего дерева поиска, и он будет хранить как раз предыдущее состояние декодера, которое было для него предыдущий узел, из которых мы пришли.
176: У него токен айди алгорифм вероятности, потому что с ним работать проще и приятнее, чем с самой вероятностью. И длину последовательности, которую вот этот бимсерч ноут у нас кодирует. Дальше мы напишем функции, 1 из которых
177: Нам будет давать следующих кандидатов в количестве бивис. Собственно, здесь будет происходить то, что мы уже обсудили. Мы берём наши предыдущие ноды, предыдущие вершины. Их мы прогоняем через
178: И дальше мы прогоняем их через декодер.
179: Дальше мы из них создаём следующие ноды, следующие вершинки, и сохраняем их. А здесь мы по минус логарифм вероятности, мы выбираем наиболее вероятные наши ноды, наиболее вероятные последовательности, которые кодируют эти ноды. Подумайте, почему?
180: Логотип вероятности, а мы пока пойдём дальше, вы можете поставить на паузу и подумать над этим.
181: А эта функция у нас уже будет характеризовать сам бимсерч инференс, то есть здесь мы будем получать на вход лист текстов модель, токенизаторы и beam vs. То есть количество вариантов, которых нам нужно вернуть для каждого текста мы
182: Возьмём, очистим текст, получим максимальную длину последовательности, с которой нам надо работать, и рассмотрим каждый текст отдельно.
183: Мы добавим к тексту паддинг, преобразуем его в тензер и дальше прогоним через инкодер, создадим бимсерч ноут, который будет характеризовать наше начало, то есть наш sos токен стартов, сентенс, токен и мы.
184: Мы сохраним это nose и notes, то есть те ноды интересны нам ноды с предыдущей нерации. Дальше мы возьмём, вытащим следующие ноды.
185: Уже в цикле while, и мы просто их проверим, не являются ли они завершающими нодами, которые уже содержат в себе еос, токен, сенсен, токен и их предок не является наном. То есть это не 1 же токен, который
186: У нас был и будем это делать до тех пор, пока мы не наберём достаточное количество финальных нот или мы не наберём сильно большое количество всех нот, которые у нас когда-либо были вот в этом процессе.
187: И будем, будем восстанавливать наши последовательности, будем сохранять их в most likely худ. Текст. Лист вот будем его сохранять наиболее вероятные наши последовательности.
188: Собственно, здесь мы просто гуляем. Вот.
189: Листов к нашей исходной вершине сос и сохраняем это все в дистанцию. И из этой функции мы с вами вернём наиболее вероятные варианты. Собственно, у нас есть такой вот алгоритм.
190: Его можно проверить на наших модельках. Это вы лучше сделаете сами, у вас это получится лучше.
191: Всем спасибо за внимание. Сегодня мы с вами обсудили, что такое бимсерч. Такая достаточно мощная штука, используемая на самом деле не только в машинном переводе, но и, допустим, в распознавании речи, потому что там как раз опять же задача секту сёк, то есть последовательность Последова.
192: Также мы обсудили идею аттеншена, которая вам не раз ещё пригодится в части трансформерами, и обсудили архитектуру кодер декодер в контексте машинного перевода и в контексте.
193: Наши задачи. Всем спасибо за внимание.