Векторное представление слов — различия между версиями

Материал из Викиконспекты
Перейти к: навигация, поиск
(Обучение модели word2vec и fastText на текстовом корпусе)
Строка 78: Строка 78:
 
  fastText_model.most_similar('car')[:3]
 
  fastText_model.most_similar('car')[:3]
 
  ''<font color="grey"># [('lcar', 0.8733218908309937), ('boxcar', 0.8559106588363647), ('ccar', 0.8268736004829407)]</font>
 
  ''<font color="grey"># [('lcar', 0.8733218908309937), ('boxcar', 0.8559106588363647), ('ccar', 0.8268736004829407)]</font>
 +
 +
== ELMO ==
 +
[[File:Elmo.png|500px|thumb|Архитектура и принцип работы ELMO]]
 +
<i>ELMO</i> - это многослойная двунаправленная [[:Рекуррентные_нейронные_сети|рекуррентная нейронная сеть]] c [[:Долгая_краткосрочная_память|LSTM]].
 +
При использовании word2vec или fastText не учитывается семантическая неоднозначность слов.
 +
Так, word2vec назначает слову один вектор независимо от контекста.
 +
ELMO решает эту проблему. В основе стоит идея использовать скрытые состояния языковой модели многослойной [[:Долгая_краткосрочная_память|LSTM]].
 +
Было замечено, что нижние слои отвечают за синтаксис и грамматику, а верхние - за смысл слов.
 +
Пусть даны токены <math>t_{1}, ..., t_{N}</math>, на которые поделено предложение. Будем предсказывать логарифм правдоподобия метки слова в обоих направлениях, учитывая контекст слева и контекст справа:
 +
 +
<math>\sum_{k=1}^{N} \left ( \log p( {t_{k}} | {t_{1}}, ..., {t_{k-1}};\Theta_{x}, \overrightarrow{\Theta}_{LSTM} , \Theta_{s}) + \log p( {t_{k}} | {t_{k+1}}, ..., {t_{N}};\Theta_{x}, \overleftarrow{\Theta}_{LSTM} , \Theta_{s} ) \right )</math>
 +
 +
Пусть есть <math>L</math> слоев сети. Тогда каждый результирующий вектор будем считать на основании множества:
 +
 +
<math>\boldsymbol{R}_{k} = \left \{ {x_{k}^{LM}}, \overrightarrow{h_{k, j}^{LM}}, \overleftarrow{h_{k, j}^{LM}} | j = 1, ..., L \right \} = \left \{ h_{k, j}^{LM} | j = 1, ..., L \right \}</math>
 +
 +
Здесь <math>x_{k}^{LM}</math> - входящий токен, а <math>\overrightarrow{h_{k, j}^{LM}}</math> и <math>\overleftarrow{h_{k, j}^{LM}}</math> - скрытые слои в одном и в другом направлении.
 +
 +
Тогда ELMO будет представлять из себя выражение:
 +
<math>ELMO_{k}^{task} = \gamma^{taks}\sum_{j=0}^{L} s_{i}^{task}h_{k,j}^{LM}</math>
 +
 +
Обучаемый общий масштабирующий коэффициент <math>\gamma</math> регулирует то, как могут отличаться друг от друга по норме векторные представления слов.
 +
 +
Коэффициенты <math>s</math> - это обучаемые параметры, нормализованные функцией <math>softMax</math>.
 +
 +
Модель применяют дообучая ее: изначально берут предобученную ELMO, а затем корректируют <math>\gamma</math> и <math>s_{i}</math> под конкретную задачу. Тогда вектор, который подается в используемую модель для обучения, будет представлять собой взвешенную сумму значений этого векторах на всех скрытых слоях ELMO.
 +
 +
 +
== BERT ==
 +
{{main|Bert}}
 +
[[File:Bert.png|500px|thumb|Архитектура BERT]]
 +
BERT - это модель предварительного обучения NLP, представляющая собой многослойный двунаправленный [[:Автокодировщик|кодировщик]] Transformer. В данной архитектуре используется двунаправленное [[:Механизм внимания|самовнимание]].
 +
Модель используется в совокупности с некоторым классификатором, на вход которого подается результат работы BERT - векторное представление входных данных.
 +
В основе обучения модели лежат две идеи для обучения.
 +
 +
Первая заключается в том, чтобы заменить <math>15\%</math> слов масками и обучить сеть предсказывать эти слова.
 +
 +
Второй трюк состоит в том, чтобы дополнительно научить BERT определять, может ли одно предложение идти после другого.
 +
 +
Точно так же, как и в обычном Трансформере, BERT принимает на вход последовательность слов, которая затем продвигается вверх по стеку энкодеров.
 +
Каждый слой энкодера применяет внутреннее внимание (self-attention) и передает результаты в сеть прямого распространения, после чего направляет его следующему энкодеру.
 +
 +
Для каждой позиции на выход подается вектор размерностью <math>hiddenSize</math> (<math>768</math> в базовой модели).
 +
Этот вектор может быть использован как входной вектор для классификатора.
 +
  
 
== См. также ==
 
== См. также ==
Строка 94: Строка 139:
 
* [https://arxiv.org/pdf/1607.04606.pdf fastText article] {{---}} оригинальная статья по fastText от Piotr Bojanowski
 
* [https://arxiv.org/pdf/1607.04606.pdf fastText article] {{---}} оригинальная статья по fastText от Piotr Bojanowski
 
* [https://rusvectores.org/ru/ RusVectōrēs] {{---}} онлайн сервис для работы с семантическими отношениями русского языка
 
* [https://rusvectores.org/ru/ RusVectōrēs] {{---}} онлайн сервис для работы с семантическими отношениями русского языка
 +
* [https://arxiv.org/abs/1810.04805/ Cornell univerity arxiv] {{---}} оригинальная статья про Bert
 +
* [https://arxiv.org/abs/1802.05365/ Cornell univerity arxiv] {{---}} оригинальная статья с описанием ELMO
  
 
[[Категория: Машинное обучение]] [[Категория: Обработка естественного языка]]
 
[[Категория: Машинное обучение]] [[Категория: Обработка естественного языка]]

Версия 20:02, 14 декабря 2020

Векторное представление слов (англ. word embedding) — общее название для различных подходов к моделированию языка и обучению представлений в обработке естественного языка, направленных на сопоставление словам из некоторого словаря векторов небольшой размерности.

One-hot encoding

Пусть число различных слов равно [math]K[/math]. Сопоставим слову с номером [math]i[/math] вектор длины [math]K[/math], в котором [math]i[/math]-тая координата равна единице, а все остальные — нулям. Недостатком one-hot encoding является то, что по векторным представлениям нельзя судить о схожести смысла слов. Также вектора имеют очень большой размер, из-за чего их неэффективно хранить в памяти.






word2vec

word2vec — способ построения сжатого пространства векторов слов, использующий нейронные сети. Принимает на вход большой текстовый корпус и сопоставляет каждому слову вектор. Сначала он создает словарь, а затем вычисляет векторное представление слов. Векторное представление основывается на контекстной близости: слова, встречающиеся в тексте рядом с одинаковыми словами (а следовательно, имеющие схожий смысл), в векторном представлении имеют высокое косинусное сходство (англ. cosine similarity):

[math]\text{similarity}(\mathbf{A}, \mathbf{B}) = \cos(\theta) = {\mathbf{A} \cdot \mathbf{B} \over \|\mathbf{A}\| \|\mathbf{B}\|} = \frac{ \sum\limits_{i=1}^{n}{A_i B_i} }{ \sqrt{\sum\limits_{i=1}^{n}{A_i^2}} \sqrt{\sum\limits_{i=1}^{n}{B_i^2}} },[/math]


В word2vec существуют две основных модели обучения: Skip-gram и CBOW (англ. Continuous Bag of Words). В модели Skip-gram по слову предсказываются слова из его контекста, а в модели CBOW по контексту подбирается наиболее вероятное слово. На выходном слое используется функция [math]softmax[/math] или его вариация, чтобы получить на выходе распределение вероятности каждого слова. В обеих моделях входные и выходные слова подаются в one-hot encoding, благодаря чему при умножении на матрицу [math]W[/math], соединяющую входной и скрытый слои, происходит выбор одной строки [math]W[/math]. Размерность [math]N[/math] является гиперпараметром алгоритма, а обученная матрица [math]W[/math] — выходом, так как ее строки содержат векторные представления слов.

Для ускорения обучения моделей Skip-gram и CBOW используются модификации [math]softmax[/math], такие как иерархический [math]softmax[/math] и negative sampling, позволяющие вычислять распределение вероятностей быстрее, чем за линейное время от размера словаря.

Полученные векторы-слова отражают различные грамматические и семантические концепции.
[math]W_{king} + (W_{woman} - W_{man}) = W_{queen}[/math]
[math]W_{walked} - W_{walking} = W_{swam} - W_{swimming}[/math]

fastText

Недостатком word2vec является то, что с его помощью не могут быть представлены слова, не встречающиеся в обучающей выборке. fastText решает эту проблему с помощью [math]N[/math]-грамм символов. Например, [math]3[/math]-граммами для слова яблоко являются ябл, бло, лок, око. Модель fastText строит векторные представления [math]N[/math]-грамм, а векторным представлением слова является сумма векторных представлений всех его [math]N[/math]-грамм. Части слов с большой вероятностью встречаются и в других словах, что позволяет выдавать векторные представления и для редких слов.

Примеры кода с использованием библиотеки Gensim

Загрузка предобученной модели русского корпуса

import gensim
import gensim.downloader as download_api
russian_model = download_api.load('word2vec-ruscorpora-300')
# Выведем первые 10 слов корпуса.
#
В модели "word2vec-ruscorpora-300" после слова указывается часть речи: NOUN (существительное), ADJ (прилагательное) и так далее.
#
Но существуют также предоубученные модели без разделения слов по частям речи, смотри репозиторий
list(russian_model.vocab.keys())[:10] # ['весь_DET', 'человек_NOUN', 'мочь_VERB', 'год_NOUN', 'сказать_VERB', 'время_NOUN', 'говорить_VERB', 'становиться_VERB', 'знать_VERB', 'самый_DET']
# Поиск наиболее близких по смыслу слов. russian_model.most_similar('кошка_NOUN') # [('кот_NOUN', 0.7570087909698486), ('котенок_NOUN', 0.7261239290237427), ('собака_NOUN', 0.6963180303573608), # ('мяукать_VERB', 0.6411399841308594), ('крыса_NOUN', 0.6355636119842529), ('собачка_NOUN', 0.6092042922973633), # ('щенок_NOUN', 0.6028496026992798), ('мышь_NOUN', 0.5975362062454224), ('пес_NOUN', 0.5956044793128967), # ('кошечка_NOUN', 0.5920293927192688)]
# Вычисление сходства слов russian_model.similarity('мужчина_NOUN', 'женщина_NOUN') # 0.85228276
# Поиск лишнего слова russian_model.doesnt_match('завтрак_NOUN хлопья_NOUN обед_NOUN ужин_NOUN'.split()) # хлопья_NOUN
# Аналогия: Женщина + (Король - Мужчина) = Королева russian_model.most_similar(positive=['король_NOUN','женщина_NOUN'], negative=['мужчина_NOUN'], topn=1) # [('королева_NOUN', 0.7313904762268066)]
# Аналогия: Франция = Париж + (Германия - Берлин) russian_model.most_similar(positive=['париж_NOUN','германия_NOUN'], negative=['берлин_NOUN'], topn=1) # [('франция_NOUN', 0.8673800230026245)]

Обучение модели word2vec и fastText на текстовом корпусе

from gensim.models.word2vec import Word2Vec
from gensim.models.fasttext import FastText
import gensim.downloader as download_api
# Скачаем небольшой текстовый корпус (32 Мб) и откроем его как итерируемый набор предложений: iterable(list(string)) # В этом текстовом корпусе часть речи для слов не указывается corpus = download_api.load('text8')
# Обучим модели word2vec и fastText word2vec_model = Word2Vec(corpus, size=100, workers=4) fastText_model = FastText(corpus, size=100, workers=4)
word2vec_model.most_similar('car')[:3] # [('driver', 0.8033335208892822), ('motorcycle', 0.7368553876876831), ('cars', 0.7001584768295288)]
fastText_model.most_similar('car')[:3] # [('lcar', 0.8733218908309937), ('boxcar', 0.8559106588363647), ('ccar', 0.8268736004829407)]

ELMO

Архитектура и принцип работы ELMO

ELMO - это многослойная двунаправленная рекуррентная нейронная сеть c LSTM. При использовании word2vec или fastText не учитывается семантическая неоднозначность слов. Так, word2vec назначает слову один вектор независимо от контекста. ELMO решает эту проблему. В основе стоит идея использовать скрытые состояния языковой модели многослойной LSTM. Было замечено, что нижние слои отвечают за синтаксис и грамматику, а верхние - за смысл слов. Пусть даны токены [math]t_{1}, ..., t_{N}[/math], на которые поделено предложение. Будем предсказывать логарифм правдоподобия метки слова в обоих направлениях, учитывая контекст слева и контекст справа:

[math]\sum_{k=1}^{N} \left ( \log p( {t_{k}} | {t_{1}}, ..., {t_{k-1}};\Theta_{x}, \overrightarrow{\Theta}_{LSTM} , \Theta_{s}) + \log p( {t_{k}} | {t_{k+1}}, ..., {t_{N}};\Theta_{x}, \overleftarrow{\Theta}_{LSTM} , \Theta_{s} ) \right )[/math]

Пусть есть [math]L[/math] слоев сети. Тогда каждый результирующий вектор будем считать на основании множества:

[math]\boldsymbol{R}_{k} = \left \{ {x_{k}^{LM}}, \overrightarrow{h_{k, j}^{LM}}, \overleftarrow{h_{k, j}^{LM}} | j = 1, ..., L \right \} = \left \{ h_{k, j}^{LM} | j = 1, ..., L \right \}[/math]

Здесь [math]x_{k}^{LM}[/math] - входящий токен, а [math]\overrightarrow{h_{k, j}^{LM}}[/math] и [math]\overleftarrow{h_{k, j}^{LM}}[/math] - скрытые слои в одном и в другом направлении.

Тогда ELMO будет представлять из себя выражение: [math]ELMO_{k}^{task} = \gamma^{taks}\sum_{j=0}^{L} s_{i}^{task}h_{k,j}^{LM}[/math]

Обучаемый общий масштабирующий коэффициент [math]\gamma[/math] регулирует то, как могут отличаться друг от друга по норме векторные представления слов.

Коэффициенты [math]s[/math] - это обучаемые параметры, нормализованные функцией [math]softMax[/math].

Модель применяют дообучая ее: изначально берут предобученную ELMO, а затем корректируют [math]\gamma[/math] и [math]s_{i}[/math] под конкретную задачу. Тогда вектор, который подается в используемую модель для обучения, будет представлять собой взвешенную сумму значений этого векторах на всех скрытых слоях ELMO.


BERT

Основная статья: Bert
Архитектура BERT

BERT - это модель предварительного обучения NLP, представляющая собой многослойный двунаправленный кодировщик Transformer. В данной архитектуре используется двунаправленное самовнимание. Модель используется в совокупности с некоторым классификатором, на вход которого подается результат работы BERT - векторное представление входных данных. В основе обучения модели лежат две идеи для обучения.

Первая заключается в том, чтобы заменить [math]15\%[/math] слов масками и обучить сеть предсказывать эти слова.

Второй трюк состоит в том, чтобы дополнительно научить BERT определять, может ли одно предложение идти после другого.

Точно так же, как и в обычном Трансформере, BERT принимает на вход последовательность слов, которая затем продвигается вверх по стеку энкодеров. Каждый слой энкодера применяет внутреннее внимание (self-attention) и передает результаты в сеть прямого распространения, после чего направляет его следующему энкодеру.

Для каждой позиции на выход подается вектор размерностью [math]hiddenSize[/math] ([math]768[/math] в базовой модели). Этот вектор может быть использован как входной вектор для классификатора.


См. также

Источники информации