ЖАНРЫ

Охота на электроовец. Большая книга искусственного интеллекта
Шрифт:

Среди них можно отметить статьи [2124] , [2125] Андрия Мниха — ещё одного аспиранта Джеффри Хинтона, Ронана Коллоберта и Джейсона Уэстона [2126] , а также соавторов Бенджио — Джозефа Туриана и Льва-Арье Ратинова [2127] . Однако решительный прорыв удалось совершить только в 2013 г., когда группа исследователей из компании Google под руководством Томаша Миколова опубликовала работу под названием «Эффективное вычисление представлений слов в векторном пространстве» (Efficient Estimation of Word Representations in Vector Space) [2128] . В конце того же года свет увидела вторая статья за авторством Миколова и его коллег под названием «Распределённые представления слов и фраз и их композиционность» (Distributed Representations of Words and Phrases and their Compositionality) [2129] , развивающая первое исследование и раскрывающая ряд новых деталей.

2124

Mnih A., Hinton G. E. (2009). A scalable hierarchical distributed language model / Advances in neural information processing systems, Vol. 21, pp. 1081—1088 // https://papers.nips.cc/paper/3583-a-scalable-hierarchical-distributed-language-model

2125

Mnih A., Teh Y. W. (2012). A fast and simple algorithm for training neural probabilistic language models // Proceedings of the 29th International Coference on International Conference on Machine Learning, pp. 419—426 // https://arxiv.org/abs/1206.6426

2126

Collobert R., Weston J. (2008). A unified architecture for natural language processing: deep neural networks with multitask learning / Proceedings of the 25th international conference on Machine learning, pp. 160—167 // https://doi.org/10.1145/1390156.1390177

2127

Turian J., Ratinov L., Bengio Y. (2010). Word representations: a simple and general method for semi-supervised learning / Proceedings of the 48th Annual Meeting of the Association for Computational Linguistics, pp. 384—394 // https://dl.acm.org/doi/10.5555/1858681.1858721

2128

Mikolov T., Chen K., Corrado G., Dean J. (2013). Efficient Estimation of Word Representations in Vector Space / International Conference on Learning Representations (ICLR-2013) // https://arxiv.org/abs/1301.3781

2129

Mikolov T., Sutskever I., Chen K., Corrado G., Dean J. (2013). Distributed Representations of Words and Phrases and their Compositionality / Proceedings of the 26th International Conference on Neural Information Processing Systems, Vol. 2, pp. 3111—3119 // https://papers.nips.cc/paper/5021-distributed-representations-of-words-and-phrases-and-their-compositionality.pdf

Помимо статей, была опубликована утилита для построения векторных представлений слов (word2vec, от word to vector — слово в вектор), а также сами наборы векторов для слов английского языка. На основе анализа поданного на вход большого текстового корпуса word2vec рассчитывает вектор признаков для каждого слова, встречающегося в корпусе, и создаёт на выходе словарь, включающий сами слова и наборы координат соответствующих им векторов.

«Под капотом» word2vec можно обнаружить сразу две нейросетевые модели, получившие названия «непрерывный мешок слов» (Continuous Bag of Words, CBOW) и «скипграмма» (Skip-gram). Обе эти модели являются прямыми наследницами модели Бенджио, поскольку получены из неё путём нескольких принципиальных доработок.

За прошедшее со времени исследований Бенджио и его коллег десятилетие появилась возможность обучать более «тяжёлые» модели с большим числом параметров. Создатели word2vec смогли увеличить длину контекста до десяти слов, а также использовать от 500 до 1000 нейронов в промежуточном (скрытом) слое сети. Однако этот прогресс был достигнут не только благодаря использованию нового поколения оборудования, но и ввиду применения методов для уменьшения количества параметров в выходном слое сети. Дело в том, что количество нейронов в выходном слое сети Бенджио равно количеству слов в словаре, и даже при сравнительно небольшом размере словаря, как это было в оригинальной работе Бенджио и его коллег, это становится проблемой. Ведь уже при словаре в 16 000 слов и 100 нейронах в скрытом слое мы получим 1,6 млн параметров, а что будет, если задействовать не игрушечный, а соответствующий реальному многообразию слов естественного языка словарь? Для реальных задач в области обработки естественного языка могут потребоваться словари в сотни тысяч или даже миллионы слов. В работе Миколова и его коллег использовался словарь размером в миллион слов, что при тысяче нейронов скрытого слоя даёт миллиард параметров на выходе сети. При размерности вектора признаков, равной 200, и длине контекста в десять слов общее число параметров сети будет равно 200 x 10 (входной слой) + 200 x 10 x 1000 (промежуточный слой) + 1000 x 1 000 000 (последний слой) = 1 002 002 000 — миллиарду с хвостиком. Как видно из этого расчёта, наибольшая часть параметров приходится на последний слой сети.

Миколов и его коллеги придумали, как можно уменьшить количество параметров в выходном слое сети, для чего ими было предложено два альтернативных метода: отрицательное семплирование [negative sampling] и иерархический softmax [hierarchical softmax].

Рассмотрим их подробнее.

Традиционно выходной слой нейронных сетей, используемых в задачах классификации с более чем двумя классами, применяет функцию softmax для нормализации выходных значений. Поскольку каждое выходное значение мы интерпретируем как вероятность принадлежности объекта одному из классов, то сумма выходных значений сети должна быть равна единице. Функция softmax является обобщением логистической функции для многомерного случая и рассчитывается по следующей нехитрой формуле:

То есть фактически мы делим экспоненту каждого из выходов слоя на сумму экспонент всех таких выходов. Как несложно заметить, для вычисления этой функции нам нужны значения всех выходов слоя. Получается, что при обучении подобных сетей надо вычислить экспоненту для каждого из громадного числа выходов, что весьма затратно. Поэтому при использовании отрицательного семплирования мы отказываемся от нормализации выходов сети, а просто пропускаем каждый из выходов через логистическую функцию. При этом, разумеется, сумма выходов сети перестаёт быть строго равной единице, но, как выясняется, это не влияет на качество полученных векторов признаков.

Далее, вместо расчёта ошибок и последующего обновления весов для всех выходов сети мы выбираем для этого лишь их часть: выход, соответствующий истинной метке класса (т. е. слову, действительно встретившемуся в тексте), и несколько других отобранных выходов, для которых мы хотим, чтобы сеть выдавала 0 (так называемых отрицательных примеров, отсюда и название метода). В статье говорится, что для маленьких датасетов достаточно 5–20 отрицательных примеров, а для больших и вовсе 2–5. Таким образом, при использовании отрицательного семплирования обновлению на каждом шаге подвергается лишь крошечная доля синаптических весов модели.

Отрицательные примеры отбирают случайным образом, но с вероятностями, зависящими от частоты соответствующих им слов в используемом корпусе (т. е. часто встречающиеся слова имеют больший шанс оказаться выбранными как отрицательные примеры, чем редкие). В результате экспериментов Миколов и его коллеги пришли к выводу, что наилучшие результаты получаются при использовании вероятностей, пропорциональных частотам слов, возведённым в степень 3/4 . Такого рода константы (как и метод отрицательного семплирования) являются характерным примером экспериментальной алхимии в духе школы «грязнуль», которым в значительной мере пропитан весь современный коннекционизм.

Впрочем, прежде чем перейти к столь радикальным мерам, команда Миколова опробовала более математически строгий способ решения проблемы большого количества параметров в выходном слое, получивший название «иерархический softmax». Для этого выходной слой сети был реорганизован весьма оригинальным образом. Для начала словарь был представлен в виде двоичного дерева. Рассмотрим алгоритм, применявшийся для его построения.

Рис. 129. Двоичное дерево, представляющее словарь

Предположим, что наш словарь содержит всего восемь слов: the, of, have, not, hobbit, dandelion, immodest и besieged. Для начала подсчитаем количество вхождений каждого из слов в наш корпус. Допустим, в итоге мы получили следующий набор пар вида (слово; число вхождений): (the; 123), (of; 119), (have; 61), (not; 57), (hobbit; 27), (dandelion; 25), (immodest; 22), (besieged; 19). Возьмём теперь две пары с самым маленьким числом вхождений, в нашем случае это будут пары (immodest; 22), (besieged; 19). Объединим эти пары в единый узел дерева, пусть это будет узел «0». Теперь удалим из списка объединённые нами пары и вместо них добавим пару, соответствующую вновь созданному узлу. В качестве числа вхождений будем использовать сумму соответствующих значений для объединённых нами пар. В результате мы получим следующий список: (the; 123), (of; 119), (have; 61), (not; 57), (hobbit; 27), (dandelion; 25), («0», 41). Будем повторять эту процедуру, пока в списке не останется единственная пара, соответствующая корню построенного двоичного дерева:

шаг 1: (the; 123), (of; 119), (have; 61), (not; 57), (hobbit; 27), (dandelion; 25), («0», 41)

шаг 2: (the; 123), (of; 119), (have; 61), (not; 57), («1», 52), («0», 41)

шаг 3: (the; 123), (of; 119), (have; 61), (not; 57), («2», 93)

шаг 4: (the; 123), (of; 119), («3», 118), («2», 93)

шаг 5: (the; 123), (of; 119), («4», 211)

шаг 6: («5»; 242), («4», 211)

шаг 7: («6»; 453)

Использованный нами алгоритм был разработан в 1952 г. и носит название «алгоритм Хаффмана», в честь его создателя Дэвида Хаффмана. Он относится к числу алгоритмов так называемого частотного кодирования и обычно применяется в задачах, связанных со сжатием данных. Дело в том, что дерево, построенное при помощи алгоритма Хаффмана, является визуализацией двоичного кода, позволяющего компактно представлять последовательности, состоящие из элементов, из которых было построено данное дерево. Двоичный код — это последовательность нулей и единиц. В случае дерева Хаффмана для кодирования каждого элемента мы будем использовать код, соответствующий пути, который следует пройти от корня дерева до нашего элемента. При этом 0 будет означать шаг влево, а 1 — шаг вправо. В нашем случае словам из словаря будут поставлены в соответствие следующие коды:

Идея кода Хаффмана заключается в том, что более часто встречающиеся элементы получат более короткие коды, что позволит минимизировать число бит, необходимое для хранения последовательности.

При использовании иерархической версии softmax выходной вектор сети имеет размерность, равную числу внутренних узлов дерева Хаффмана, построенного для используемого словаря. В нашем случае таких узлов семь («0», «1», …, «6»). Для каждого компонента вектора мы используем логистическую функцию активации, при этом сопоставление узлов и слов идёт следующим образом: значения в узлах меньше или равные 0,5 интерпретируются как шаги влево в них, а значения больше 0,5 — как шаги вправо. Например, слову hobbit будут соответствовать значения больше 0,5 у узлов «6» и «4» и значения меньше 0,5 у узлов «2» и «1» (здесь сумма компонентов выходного вектора вовсе не обязана быть равна единице). Кроме того, при каждом шаге мы будем обновлять веса только части выходов (узлов) — тех, через которые проходит путь в дереве, соответствующий правильной метке класса. При таком подходе обновления на каждом шаге обычно будут затрагивать не более чем log2N выходов сети, то есть при миллионе слов в словаре среднее число обновляемых выходов не будет превышать 20.

Поделиться с друзьями: