TL; DR; Наконец, сообщество разработчиков ПО с открытым исходным кодом обратилось к требованиям динамической структуры нейронных сетей. За последние 3 месяца мы увидели 3 основных выпуска библиотек, поддерживающих динамические структуры.

  1. Tensorflow Fold (Google)
  2. Динет (КМУ)
  3. Pytorch (Twitter, NVIDIA, SalesForce, ParisTech, CMU, Digital Reasoning, INRIA, ENS)

В Инноплексус мы собираем информацию из структурированных, неструктурированных и полуструктурированных источников, чтобы помочь нашим клиентам принимать решения в режиме реального времени. Чтобы достичь этой скорости, мы конвертируем текст на естественном языке из неструктурированных источников в правильно структурированное представление. Поскольку скорость является основным узким местом, наши системы НЛП основаны на повторяющейся структуре языка из-за доступности инструментов и распределения вычислений по нескольким машинам.

Со временем мы осознали ограничения рекуррентных подходов, таких как LSTM и GRU, которые пытаются приспособить рекурсивный естественный язык к последовательной структуре. Это приводит к потере синтаксической информации в задаче обработки информации. Но, к сожалению, реализация рекурсивных нейронных сетей с нуля может оказаться кошмаром, поскольку требует написания сложного кода обратного распространения с очень высокой точностью.

Большинство библиотек машинного обучения, таких как Tensorflow, Torch или Theano, позволяют создавать статическую сеть, которая ограничивает изменение структуры сети в зависимости от входных данных. Это оказывается существенным ограничением в обработке / понимании естественного языка, где синтаксическая информация кодируется в дереве синтаксического анализа, которое изменяется в зависимости от входного текста. Многие приложения, такие как Синтаксический анализ, Машинный перевод и Анализ тональности, требуют синтаксической информации наряду с семантической. Из-за недоступности какой-либо структуры разработчики в конечном итоге внедряют процедуры обучения в Numpy. Это очень подвержено ошибкам и является утомительной задачей, которую необходимо выполнять с высокой точностью.

С похожей проблемой мы столкнулись при внедрении Entity Extractor в Инноплексус. Он использует семантически объединенные рекурсивные нейронные сети, которые имеют древовидную структуру. Из-за отсутствия каких-либо фреймворков, поддерживающих динамическую структуру, мы в конечном итоге реализовали его в Tensorflow. Это вызвало большие нагрузки на наш вычислительный график, что сделало процесс обучения медленным, а память неэффективной. Более того, выбор размера пакета для очистки графика стал критическим вопросом для процесса обучения. Когда мы собирались переписать всю процедуру обучения в Numpy, чтобы ускорить процесс, мы наткнулись на Dynet.

DyNet (ранее известная как cnn) - это библиотека нейронной сети, разработанная Университетом Карнеги-Меллона и многими другими. Он написан на C ++ (с привязками в Python) и разработан, чтобы быть эффективным при запуске на CPU или GPU, а также хорошо работать с сетями, которые имеют динамические структуры, которые изменяются для каждого обучающего экземпляра.

Мы реорганизовали наш код в Dynet, немного изменив код Tensorflow. Dynet не так развит, как тензорный поток с точки зрения доступных функций, поэтому мы закончили писать нашу реализацию для аналога Tensorflow. В качестве альтернативы PyTorch более зрелый и поддерживается более широким сообществом. Вы можете создать такой динамический график:

Google недавно запустил Fold, который включает в себя более широкий массив объектов Python, чем tensorflow. Он обеспечивает поддержку структурированных данных, таких как вложенные списки, словари и буферы протокола. Это преодолевает ограничение статического графа Tensorflow. Его подход полностью отличается от PyTorch / Dynet. Он использует динамическое пакетирование для распараллеливания операций в графах нескольких экземпляров. Посмотрите, это круто. Вкратце, вот как это работает:

В пространстве НЛП, где язык может иметь выражения различной длины, поэтому важны динамические вычислительные графы. Можно только представить, как анализируется грамматика, чтобы понять необходимость стека и, следовательно, динамической памяти и, следовательно, динамических вычислений. Это важное событие удачно описал Карлос Э. Перес в своем посте.

При таком развитии событий было бы разумно ожидать, что архитектуры глубокого обучения пройдут тот же эволюционный путь, что и традиционные вычисления. То есть от монолитных автономных программ до более модульных программ. Представление динамических вычислительных графов похоже на введение концепции процедуры, когда все, что раньше было, - это операторы goto. Именно концепция процедуры заключается в том, что мы можем писать наши программы компонуемым образом. Конечно, можно возразить, что архитектурам DL не нужен стек, однако нужно только ознакомиться с недавними исследованиями сетей HyperNetworks и Stretcher. В исследовании есть сети, в которых переключение контекста, например, стек, оказывается эффективным.

Мы используем эти библиотеки для рефакторинга нашего кода, чтобы перейти от рекурсивных систем к рекурсивным системам с небольшими изменениями. Это дало нам огромное улучшение нашей существующей модели, а также позволило нам решать проблемы, которые ранее были недоступны. Надеюсь, это поможет вам сделать то же самое, что и мы!

Удачного взлома: D