>>1.00<<>>1.00<<Видео проигрыватель загружается.Воспроизвести видеоВоспроизвестиБез звукаТекущее время 0:00/Продолжительность 5:47Загрузка: 0.00%0:00Тип потока ОНЛАЙНSeek to live, currently behind liveОНЛАЙНОставшееся время -5:47 1xСкорость воспроизведения2x1.75x1.5x1.25x1x, выбрано0.75x0.5xГлавыГлавыОписанияОтключить описания, выбраноСубтитрынастройки субтитров, откроется диалог настройки субтитровСубтитры выкл., выбраноЗвуковая дорожкаPicture-in-PictureПолноэкранный режимThis is a modal window.Начало диалоговго окна. Кнопка Escape закроет или отменит окноТекстColorБелыйЧерныйКрасныйЗеленыйСинийЖелтыйПурпурныйГолубойTransparencyПрозрачностьПолупрозрачныйФонColorЧерныйБелыйКрасныйЗеленыйСинийЖелтыйПурпурныйГолубойTransparencyПрозрачностьПолупрозрачныйПрозрачныйОкноColorЧерныйБелыйКрасныйЗеленыйСинийЖелтыйПурпурныйГолубойTransparencyПрозрачныйПолупрозрачныйПрозрачностьРазмер шрифта50%75%100%125%150%175%200%300%400%Стиль края текстаНичегоПоднятыйПониженныйОдинаковыйТеньШрифтПропорциональный без засечекМоноширинный без засечекПропорциональный с засечкамиМоноширинный с засечкамиСлучайныйПисьменныйМалые прописныеСбросить сбросить все найстройки по умолчаниюГотовоЗакрыть модальное окноКонец диалогового окна.
Перейдём к прямому проходу по этой модели. Традиционно, метод forward используется для того, чтобы получить предсказание модели для какого-то обучающего примера — например, получить метку класса. Но у нас здесь не вполне обычная модель, мы здесь используем метод forward для того, чтобы вычислить функцию потерь. Таким образом, наш класс модели, который мы сейчас описываем, на самом деле — это не модель, это алгоритм обучения, и мы назвали этот класс соответствующим образом — "trainer". Итак, на вход на каждой итерации нам дают пачку предложений — прямоугольный тензор размерности ["размер батча" на "максимальную длину предложения"]. Этот тензор имеет целочисленный тип. На первом шаге, для каждого токена из батча, мы получаем центральный эмбеддинг, то есть делаем выборку из таблицы центральных эмбеддингов. В результате мы получаем тензор вот такой размерности (трёхмерный тензор): ["размер батча" на "максимально длину предложения", и здесь у нас добавляется ещё "размер эмбеддинга"] в конец. Как вы помните, процесс обучения word2vec — это процесс обучения классификатора, который предсказывает — могут ли два слова встретиться в рамках какого-то небольшого окна, или не могут. Соответственно, нам нужны как положительные примеры, так и отрицательные примеры. Сначала разберёмся с положительными примерами. Для этого мы берём всё те же токены — все токены, которые у нас есть в батче, и делаем для них выборку из таблицы контекстных токенов. То есть, если сначала мы делали выборку из таблицы центральных токенов, теперь мы делаем выборку из таблицы контекстных токенов. И сразу же транспонируем её — то есть на этом шаге мы получаем тензор размерности ["батч" на "размер эмбеддинга" на "максимальную длину предложения"]. А затем мы вызываем функцию "torch.bmm", которая делает матричное произведение для каждой пары матриц в батче, то есть она принимает на вход два батча матриц прямоугольных, и выполняет матричное произведение для каждой пары. В результате мы получаем трёхмерный тензор размерности ["количество примеров в батче" на "максимальную длину предложения" на "максимальную длину предложения"]. Физический смысл этого тензора — это оценка сходства, оценка семантической близости, для каждой пары токенов, встретившихся внутри предложения. Далее мы преобразовываем оценки сходства в вероятности с помощью сигмоиды. Переменная positive props содержит оценки вероятностей того, что два слова встретятся вместе, и такие оценки вычислены для всех возможных пар слов для каждого предложения из батча. Но надо помнить, что мы хотим учитывать не все совместные встречаемости, а только совместные встречаемости внутри небольшого окна. Здесь-то нам и приходит на помощь матрица маски, которую мы построили чуть раньше. Так как мы решаем задачу классификации, то мы используем соответствующую функцию потерь — в данном случае бинарную кросс-энтропию, и здесь — важный момент — мы домножаем тензор вероятностей, который содержит вероятность для всех возможных пар токенов из наших предложений, на маску. Таким образом мы зануляем оценки вероятностей для всех пар токенов, которые не лежат внутри окна. И далее мы говорим, что настоящая метка для этих позиций — это единичка. То есть, для этих пар слов и этих позиций, модель должна предсказывать большую вероятность совместной встречаемости. Итак, с положительными примерами разобрались, давайте перейдём к отрицательным. В названии алгоритма есть слова "negative sampling", то есть сэмплирование отрицательных слов. Это достаточно буквальное название, то есть в качестве отрицательных слов мы выбираем случайные слова. В данном примере мы выбираем слова равномерно. В более продвинутых реализациях в качестве отрицательных слов используются более редкие слова, то есть сэмплирование уже идёт не равномерно, а с учётом частоты встречаемости каждого слова в обучающей выборке. Но, для простоты, мы опустим эти детали здесь. Итак, мы используем метод "torch.randint", который возвращает случайные целые числа в заданном диапазоне, для того, чтобы получить номера токенов, которые мы будем использовать в качестве отрицательных. Далее мы делаем выборку из таблицы контекстных векторов для полученных отрицательных токенов и сразу же её транспонируем. Таким образом, мы получаем трёхмерный тензор размерности ["количество предложений в батче" на "размер эмбеддинга" и на "количество отрицательных слов"], которые мы сэмплируем для каждого обучающего примера. Далее мы оцениваем семантическое сходство слов из настоящих предложений и случайно выбранных отрицательных слов. Делаем это так же — скалярным произведением. Далее мы также используем кросс-энтропию, для того чтобы сходство настоящих слов и отрицательных слов было поменьше, то есть мы передаём нули как таргеты. Кстати, здесь я использую функцию binary cross entropy with logits, она на вход принимает не оценки вероятностей, а оценки сходства, то есть не нормализованные значения. По сути, вот эти два способа использовать кросс-энтропию — они примерно одинаковы, но второй способ более стабильный с численной точки зрения. Ну и, наконец, мы просто возвращаем сумму функции потерь для положительных примеров и для отрицательных.
К сожалению, у нас пока нет статистики ответов на данный вопрос,
но мы работаем над этим.