Яндекс открывает технологию машинного обучения CatBoost. Изучаем нейронные сети за четыре шага

Рассмотрим импульсные нейронные сети: особенности, перспективы и преимущества, благодаря которым успешно вытесняется 2-е поколение.

Всякий, кто следит за текущим прогрессом в анализе данных, слышал о применении в машинном обучении искусственных нейронных сетей второго поколения. Эти сети обычно полносвязные, принимающие и выдающие непрерывно изменяющиеся значения. Хотя нейронные сети осуществили прорыв , в биологическом отношении они не вполне соответствуют структуре реальных нейронов и механизмам обработки информации в человеческом мозге.

Импульсные нейронные сети: принцип работы

К природной физиологии ближе импульсные (спайковые) нейронные сети (spiking neural network, SNN). Импульсные нейронные сети преодолевают разрыв между нейронаукой и машинным обучением, используя для обработки информации биологически реалистичные модели нейронов.

Импульсная нейронная сеть принципиально отличается от нейронных сетей второго поколения, используемых аналитиками данных. Такая сеть вместо непрерывно меняющихся во времени значений оперирует дискретными событиями, происходящими в определенные моменты времени. Сеть получает на входы серию импульсов и выдаёт импульсы на выходе.


Пример сигналов на трех нейронах импульсной нейронной сети

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


Потенциал на мембране нейрона в процессе передачи сигнала

Для описания процесса используются различные модели . Импульсные нейронные сети также отличаются от сетей второго поколения менее связной и более специфичной топологией.

Импульсные нейронные сети: расстояние и время

На первый взгляд, подход SNN может показаться шагом назад – от непрерывной, своего рода аналоговой картины, к импульсной, двоичной. Однако преимущество SNN состоит в том, что импульсный подход позволяет оперировать данными, учитывая расстояния между нейронами и длительность распространения сигнала, то есть в контексте пространства и времени. За счет этого сети SNN гораздо лучше приспособлены для обработки данных от настоящих сенсоров.

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

Временной аспект соответствует тому, что тренировочные импульсы приходят с различными задержками, и та информация, что мы «теряем» при переходе от непрерывного сигнала к импульсному, на самом деле сохраняется в информации о задержке импульсов друг относительно друга. Это позволяет естественным образом обрабатывать временны́е данные без дополнительной сложности. Доказано, что импульсные нейроны являются более мощными вычислительными единицами, чем традиционные искусственные нейроны.

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

Учитывая, что SNN в теории являются более мощными нейронными сетями, чем сети второго поколения, остается удивляться, почему мы не видим их широкого применения. Основная проблема практического использовании SNN – обучение. Несмотря на наличие методов биологического неконтролируемого обучения (без учителя), таких как Hebbian и STDP , пока неизвестны эффективные методы обучения SNN, обеспечивающие более высокую производительность, чем сети второго поколения.

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

Другая, более близкая к решению, проблема, заключается в аппаратной составляющей. Симуляция SNN на стандартном оборудовании представляет трудоемкую задачу, так как требует моделирования дифференциальных уравнений. Нейроморфные аппаратные средства, такие как IBM TrueNorth , направлены на решение этой проблемы путем моделирования нейронов с использованием специализированного аппаратного обеспечения, соответствующего дискретности и разреженности биологических нейронных сетей.

Перспективы развития

Будущее SNN остается неясным. С одной стороны, они являются естественными преемниками современных нейронных сетей. С другой стороны, SNN пока далеки от практических инструментов для большинства задач. Уже существуют реальные приложения SNN для обработки изображений и звука в режиме реального времени, однако литература по практическим применениям остается скудной.

Большинство публикаций по SNN являются либо теоретическими, либо демонстрируют неудовлетворительную для современных задач производительность. В виду чрезвычайной перспективности этого направления над решением указанных задач работают многие научные группы.

  • Python ,
  • Машинное обучение ,
  • Поисковые технологии
  • Сегодня Яндекс выложил в open source собственную библиотеку CatBoost, разработанную с учетом многолетнего опыта компании в области машинного обучения. С ее помощью можно эффективно обучать модели на разнородных данных, в том числе таких, которые трудно представить в виде чисел (например, виды облаков или категории товаров). Исходный код, документация, бенчмарки и необходимые инструменты уже опубликованы на GitHub под лицензией Apache 2.0.

    CatBoost – это новый метод машинного обучения, основанный на градиентном бустинге. Он внедряется в Яндексе для решения задач ранжирования, предсказания и построения рекомендаций. Более того, он уже применяется в рамках сотрудничества с Европейской организацией по ядерным исследованиям (CERN) и промышленными клиентами Yandex Data Factory. Так чем же CatBoost отличается от других открытых аналогов? Почему бустинг, а не метод нейронных сетей? Как эта технология связана с уже известным Матрикснетом? И причем здесь котики? Сегодня мы ответим на все эти вопросы.

    Термин «машинное обучение» появился еще в 50-х годах. Этот термин обозначает попытку научить компьютер решать задачи, которые легко даются человеку, но формализовать путь их решения сложно. В результате машинного обучения компьютер может демонстрировать поведение, которое в него не было явно заложено. В современном мире мы сталкиваемся с плодами машинного обучения ежедневно по многу раз, многие из нас сами того не подозревая. Оно используется для построения лент в социальных сетях, списков «похожих товаров» в интернет-магазинах, при выдаче кредитов в банках и определении стоимости страховки. На технологиях машинного обучения работает поиск лиц на фотографиях или многочисленные фотофильтры. Для последних, кстати, обычно используются нейронные сети, и о них пишут так часто, что может сложиться ошибочное мнение, будто бы это «серебряная пуля» для решения задач любой сложности. Но это не так.

    Нейросети или градиентный бустинг

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

    Нейросети прекрасно решают определенные задачи – например, те, где нужно работать с однородными данными. Из однородных данных состоят, например, изображения, звук или текст. В Яндексе они помогают нам лучше понимать поисковые запросы, ищут похожие картинки в интернете, распознают ваш голос в Навигаторе и многое другое. Но это далеко не все задачи для машинного обучения. Существует целый пласт серьезных вызовов, которые не могут быть решены только нейросетями – им нужен градиентный бустинг. Этот метод незаменим там, где много данных, а их структура неоднородна.

    Например, если вам нужен точный прогноз погоды, где учитывается огромное количество факторов (температура, влажность, данные с радаров, наблюдения пользователей и многие другие). Или если вам нужно качественно ранжировать поисковую выдачу – именно это в свое время и подтолкнуло Яндекс к разработке собственного метода машинного обучения.

    Матрикснет

    Первые поисковые системы были не такими сложными, как сейчас. Фактически сначала был просто поиск слов – сайтов было так мало, что особой конкуренции между ними не было. Потом страниц стало больше, их стало нужно ранжировать. Начали учитываться разные усложнения - частота слов, tf-idf . Затем страниц стало слишком много на любую тему, произошёл первый важный прорыв - начали учитывать ссылки.

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

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

    Яндекс еще в 2009 году внедрили собственный метод Матрикснет, основанный на градиентном бустинге. Можно сказать, что ранжированию помогает коллективный разум пользователей и «мудрость толпы ». Информация о сайтах и поведении людей преобразуется во множество факторов, каждый из которых используется Матрикснетом для построения формулы ранжирования. Фактически, формулу ранжирования теперь пишет машина. Кстати, в качестве отдельных факторов мы в том числе используем результаты работы нейронных сетей (к примеру, так работает алгоритм Палех, о котором в прошлом году).

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

    Ещё одна важная особенность Матрикснета - в том, что формулу ранжирования можно настраивать отдельно для достаточно узких классов запросов. Например, улучшить качество поиска только по запросам про музыку. При этом ранжирование по остальным классам запросов не ухудшится.

    Именно Матрикснет и его достоинства легли в основу CatBoost. Но зачем нам вообще понадобилось изобретать что-то новое?

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

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

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

    Именно поэтому было важно научить машину работать не только с числами, но и с категориями напрямую, закономерности между которыми она будет выявлять самостоятельно, без нашей ручной «помощи». И CatBoost разработан нами так, чтобы одинаково хорошо работать «из коробки» как с числовыми признаками, так и с категориальными. Благодаря этому он показывает более высокое качество обучения при работе с разнородными данными, чем альтернативные решения. Его можно применять в самых разных областях - от банковской сферы до промышленности.

    Кстати, название технологии происходит как раз от Categorical Boosting (категориальный бустинг). И ни один кот при разработке не пострадал.

    Бенчмарки

    Можно долго говорить о теоретических отличиях библиотеки, но лучше один раз показать на практике. Для наглядности мы сравнили работу библиотеки CatBoost с открытыми аналогами XGBoost, LightGBM и H20 на наборе публичных датасетов. И вот результаты (чем меньше, тем лучше): https://catboost.yandex/#benchmark

    Не хотим быть голословными, поэтому вместе с библиотекой в open source выложены описание процесса сравнения, код для запуска сравнения методов и контейнер с использованными версиями всех библиотек. Любой пользователь может повторить эксперимент у себя или на своих данных.

    CatBoost на практике

    Новый метод уже протестировали на сервисах Яндекса. Он применялся для улучшения результатов поиска, ранжирования ленты рекомендаций Яндекс.Дзен и для расчета прогноза погоды в технологии Метеум - и во всех случаях показал себя лучше Матрикснета. В дальнейшем CatBoost будет работать и на других сервисах. Не будем здесь останавливаться – лучше сразу расскажем про Большой адронный коллайдер (БАК).

    CatBoost успел найти себе применение и в рамках сотрудничества с Европейской организацией по ядерным исследованиям. В БАК работает детектор LHCb, используемый для исследования асимметрии материи и антиматерии во взаимодействиях тяжёлых прелестных кварков. Чтобы точно отслеживать разные частицы, регистрируемые в эксперименте, в детекторе существуют несколько специфических частей, каждая из которых определяет специальные свойства частиц. Наиболее сложной задачей при этом является объединение информации с различных частей детектора в максимально точное, агрегированное знание о частице. Здесь и приходит на помощь машинное обучение. Используя для комбинирования данных CatBoost, учёным удалось добиться улучшения качественных характеристик финального решения. Результаты CatBoost оказались лучше результатов, получаемых с использованием других методов.

    Как начать использовать CatBoost?

    Для работы с CatBoost достаточно установить его на свой компьютер. Библиотека поддерживает операционные системы Linux, Windows и macOS и доступна на языках программирования Python и R. Яндекс разработал также программу визуализации

    В этот раз я решил изучить нейронные сети. Базовые навыки в этом вопросе я смог получить за лето и осень 2015 года. Под базовыми навыками я имею в виду, что могу сам создать простую нейронную сеть с нуля. Примеры можете найти в моих репозиториях на GitHub. В этой статье я дам несколько разъяснений и поделюсь ресурсами, которые могут пригодиться вам для изучения.

    Шаг 1. Нейроны и метод прямого распространения

    Так что же такое «нейронная сеть»? Давайте подождём с этим и сперва разберёмся с одним нейроном.

    Нейрон похож на функцию: он принимает на вход несколько значений и возвращает одно.

    Круг ниже обозначает искусственный нейрон. Он получает 5 и возвращает 1. Ввод - это сумма трёх соединённых с нейроном синапсов (три стрелки слева).

    В левой части картинки мы видим 2 входных значения (зелёного цвета) и смещение (выделено коричневым цветом).

    Входные данные могут быть численными представлениями двух разных свойств. Например, при создании спам-фильтра они могли бы означать наличие более чем одного слова, написанного ЗАГЛАВНЫМИ БУКВАМИ, и наличие слова «виагра».

    Входные значения умножаются на свои так называемые «веса», 7 и 3 (выделено синим).

    Теперь мы складываем полученные значения со смещением и получаем число, в нашем случае 5 (выделено красным). Это - ввод нашего искусственного нейрона.

    Потом нейрон производит какое-то вычисление и выдает выходное значение. Мы получили 1, т.к. округлённое значение сигмоиды в точке 5 равно 1 (более подробно об этой функции поговорим позже).

    Если бы это был спам-фильтр, факт вывода 1 означал бы то, что текст был помечен нейроном как спам.

    Иллюстрация нейронной сети с Википедии.

    Если вы объедините эти нейроны, то получите прямо распространяющуюся нейронную сеть - процесс идёт от ввода к выводу, через нейроны, соединённые синапсами, как на картинке слева.

    Шаг 2. Сигмоида

    После того, как вы посмотрели уроки от Welch Labs, хорошей идеей было бы ознакомиться с четвертой неделей курса по машинному обучению от Coursera , посвящённой нейронным сетям - она поможет разобраться в принципах их работы. Курс сильно углубляется в математику и основан на Octave, а я предпочитаю Python. Из-за этого я пропустил упражнения и почерпнул все необходимые знания из видео.

    Сигмоида просто-напросто отображает ваше значение (по горизонтальной оси) на отрезок от 0 до 1.

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

    Но на одних видео далеко не уедешь. Для полного понимания я решил закодить её самостоятельно. Поэтому я начал писать реализацию алгоритма логистической регрессии (который использует сигмоиду).

    Это заняло целый день, и вряд ли результат получился удовлетворительным. Но это неважно, ведь я разобрался, как всё работает. Код можно увидеть .

    Вам необязательно делать это самим, поскольку тут требуются специальные знания - главное, чтобы вы поняли, как устроена сигмоида.

    Шаг 3. Метод обратного распространения ошибки

    Понять принцип работы нейронной сети от ввода до вывода не так уж и сложно. Гораздо сложнее понять, как нейронная сеть обучается на наборах данных. Использованный мной принцип называется

    Кручинин Дмитрий, Долотов Евгений, Кустикова Валентина, Дружков Павел, Корняков Кирилл

    Введение

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

    Глубокое обучение (deep learning) рассматривает методы моделирования высокоуровневых абстракций в данных с помощью множества последовательных нелинейных трансформаций, которые, как правило, представляются в виде искусственных нейронных сетей. На сегодняшний день нейросети успешно используются для решения таких задач, как прогнозирование, распознавание образов, сжатие данных и ряда других.

    Актуальность темы машинного обучения и, в частности, глубокого обучения подтверждается регулярным появлением статей на данную тему на хабре: Данная статья посвящена сравнительному анализу некоторых программных инструментов глубокого обучения, коих в последнее время появилось великое множество . К числу таких инструментов относятся программные библиотеки, расширения языков программирования, а также самостоятельные языки, позволяющие использовать готовые алгоритмы создания и обучения нейросетевых моделей. Существующие инструменты глубокого обучения имеют различный функционал и требуют от пользователя разного уровня знаний и навыков. Правильный выбор инструмента - важная задача, позволяющая добиться необходимого результата за наименьшее время и с меньшей затратой сил.

    В статье представлен краткий обзор инструментов проектирования и обучения нейросетевых моделей. Основное внимание уделено четырем библиотекам: Caffe , Pylearn2 , Torch и Theano . Рассматриваются базовые возможности указанных библиотек, приводятся примеры их использования. Сравнивается качество и скорость работы библиотек при конструировании одинаковых топологий нейросетей для решения задачи классификации рукописных цифр (в качестве обучающей и тестовой выборки используется датасет MNIST). Также делается попытка дать оценку удобства применения рассматриваемых библиотек на практике.

    Набор данных MNIST

    Далее в качестве исследуемого набора данных будет использоваться база изображений рукописных цифр MNIST (). Изображения в данной базе имеют разрешение 28x28 и хранятся в формате оттенков серого. Цифры отцентрированы на изображении. Вся база разбита на две части: тренировочную, состоящую из 50000 изображений, и тестовую - 10000 изображений.

    Программные средства для решения задач глубокого обучения

    Существует множество программных средств для решения задач глубокого обучения. В можно найти общее сравнение функциональных возможностей наиболее известных, здесь приведем общую информацию о некоторых из них (). Первые шесть программных библиотек реализуют наиболее широкий спектр методов глубокого обучения. Разработчики предоставляют возможности для создания полностью связанных нейросетей (fully connected neural network, FC NN ), сверточных нейронных сетей (convolutional neural network, CNN) , автокодировщиков (autoencoder, AE) и ограниченных машин Больцмана (restricted Boltzmann machine, RBM) . Необходимо обратить внимание на оставшиеся библиотеки. Несмотря на то, что они обладают меньшей функциональностью, в некоторых случаях их простота помогает достичь большей производительности.

    Таблица 1. Возможности программных средств глубокого обучения

    # Название Язык OC FC NN CNN AE RBM
    1 DeepLearnToolbox Matlab Windows, Linux + + + +
    2 Theano Python Windows, Linux, Mac + + + +
    3 Pylearn2 Python Linux, Vagrant + + + +
    4 Deepnet Python Linux + + + +
    5 Deepmat Matlab ? + + + +
    6 Torch Lua, C Linux, Mac OS X, iOS, Android + + + +
    7 Darch R Windows, Linux + - + +
    8 Caff e C++, Python, Matlab Linux, OS X + + - -
    9 nnForge С++ Linux + + - -
    10 CXXNET С++ Linux + + - -
    11 Cuda-convnet С++ Linux, Windows + + - -
    12 Cuda CNN Matlab Linux, Windows + + - -

    Основываясь на приведенной в информации и рекомендациях специалистов, для дальнейшего рассмотрения выбраны четыре библиотеки: , - одни из самых зрелых и функционально полных библиотек, и - широко используемые сообществом. Каждая библиотека рассматривается по следующему плану:
    1. Краткая справочная информация.
    2. Технические особенности (ОС, язык программирования, зависимости).
    3. Функциональные возможности.
    4. Пример формирования сети типа логистическая регрессия.
    5. Обучение и использование построенной модели для классификации.
    После рассмотрения перечисленных библиотек проводится их сравнение на ряде тестовых конфигураций сетей.

    Библиотека Caffe



    Разработка Caffe ведется с сентября 2013 г. Начало разработки положил Yangqing Jia во время его обучения в калифорнийском университете в Беркли. С указанного момента Caffe активно поддерживается Центром Зрения и Обучения Беркли (The Berkeley Vision and Learning Center, BVLC) и сообществом разработчиков на GitHub . Библиотека распространяется под лицензией BSD 2-Clause.

    Caffe реализована с использованием языка программирования C++, имеются обертки на Python и MATLAB. Официально поддерживаемые операционные системы - Linux и OS X, также имеется неофициальный порт на Windows . Caffe использует библиотеку BLAS (ATLAS, Intel MKL, OpenBLAS) для векторных и матричных вычислений. Наряду с этим, в число внешних зависимостей входят glog, gflags, OpenCV, protoBuf, boost, leveldb, nappy, hdf5, lmdb. Для ускорения вычислений Caffe может быть запущена на GPU с использованием базовых возможностей технологии CUDA или библиотеки примитивов глубокого обучения cuDNN .

    Разработчики Caffe поддерживают возможности создания, обучения и тестирования полностью связанных и сверточных нейросетей. Входные данные и преобразования описываются понятием слоя . В зависимости от формата хранения могут использоваться следующие типы слоев исходных данных:

    • DATA - определяет слой данных в формате leveldb и lmdb.
    • HDF5_DATA - слой данных в формате hdf5.
    • IMAGE_DATA - простой формат, который предполагает, что в файле приведен список изображений с указанием метки класса.
    • и другие.
    Преобразования могут быть заданы с помощью слоев:
    • INNER_PRODUCT - полностью связанный слой.
    • CONVOLUTION - сверточный слой.
    • POOLING - слой пространственного объединения.
    • Local Response Normalization (LRN) - слой локальной нормализации.
    Наряду с этим, при формировании преобразований могут использоваться различные функции активации.
    • Положительная часть (Rectified-Linear Unit, ReLU).
    • Сигмоидальная функция (SIGMOID).
    • Гиперболический тангенс (TANH).
    • Абсолютное значение (ABSVAL).
    • Возведение в степень (POWER).
    • Функция биноминального нормального логарифмического правдоподобия (binomial normal log likelihood, BNLL).
    Последний слой нейросетевой модели должен содержать функцию ошибки. В библиотеке имеются следующие функции:
    • Среднеквадратичная ошибка (Mean-Square Error, MSE).
    • Краевая ошибка (Hinge loss).
    • Логистическая функция ошибки (Logistic loss).
    • Функция прироста информации (Info gain loss).
    • Сигмоидальная кросс-энтропия (Sigmoid cross entropy loss).
    • Softmax-функция. Обобщает сигмоидальную кросс-энтропию на случай количества классов больше двух.
    В процессе обучения моделей применяются различные методы оптимизации. Разработчики Caffe предоставляют реализацию ряда методов:

    В библиотеке Caffe топология нейросетей, исходные данные и способ обучения задаются с помощью конфигурационных файлов в формате prototxt. Файл содержит описание входных данных (тренировочных и тестовых) и слоев нейронной сети. Рассмотрим этапы построения таких файлов на примере сети “логистическая регрессия” (). Далее будем считать, что файл называется linear_regression.prototxt, и он размещается в директории examples/mnist.
    Рис. 2. Структура нейронной сети

    Библиотека Pylearn2


    Pylearn2 - библиотека, разрабатываемая в лаборатории LISA в университете Монреаля с февраля 2011 года. Имеет около 100 разработчиков на GitHub . Библиотека распространяется под лицензией BSD 3-Clause.

    Pylearn2 реализована на языке Python, в настоящее время поддерживается операционная система Linux, также возможен запуск на любой операционной системе с использованием виртуальной машины, т.к. разработчики предоставляют сконфигурированную обертку виртуальной среды на базе Vagrant. Pylearn2 является надстройкой над библиотекой Theano . Дополнительно требуются PyYAML, PIL. Для ускорения вычислений Pylearn2 и Theano используют Cuda-convnet , которая реализована на C++/CUDA, что дает значительный прирост в скорости.

    В Pylearn2 поддерживается возможность создания полностью связанных и сверточных нейросетей, различных видов автокодировщиков (Contractive Auto-Encoders, Denoising Auto-Encoders) и ограниченных машин Больцмана (Gaussian RBM, the spike-and-slab RBM). Предусмотрены несколько функций ошибки: кросс-энтропия (cross-entropy), логарифмическое правдоподобие (log-likelihood). Имеются следующие методы обучения:

    • Пакетный градиентный спуск (Batch Gradient Descent, BGD).
    • Стохастический градиентный спуск (Stochastic Gradient Descent, SGD).
    • Нелинейный метод сопряженных градиентов (Nonlinear conjugate gradient descent, NCG).
    В библиотеке Pylearn2 нейросети задаются с помощью их описания в конфигурационном файле в формате YAML. YAML-файлы являются удобным и быстрым способом сериализации объектов, так как она разработана с использованием методов объектно-ориентированного программирования.

    Библиотека Torch


    Torch - библиотека для научных вычислений с широкой поддержкой алгоритмов машинного обучения. Разрабатывается Idiap Research Institute , New York University и NEC Laboratories America , начиная с 2000г., распространяется под лицензией BSD.

    Библиотека реализована на языке Lua с использованием C и CUDA. Быстрый скриптовый язык Lua в совокупности с технологиями SSE, OpenMP, CUDA позволяют Torch показывать неплохую скорость по сравнению с другими библиотеками. На данный момент поддерживаются операционные системы Linux, FreeBSD, Mac OS X. Основные модули также работают и на Windows. В зависимостях Torch находятся пакеты imagemagick, gnuplot, nodejs, npm и другие.

    Библиотека состоит из набора модулей, каждый из которых отвечает за различные стадии работы с нейросетями. Так, например, модуль nn обеспечивает конфигурирование нейросети (определению слоев, и их параметров), модуль optim содержит реализации различных методов оптимизации, применяемых для обучения, а gnuplot предоставляет возможность визуализации данных (построение графиков, показ изображений и т.д.). Установка дополнительных модулей позволяет расширить функционал библиотеки.

    Torch позволяет создавать сложные нейросети с помощью механизма контейнеров. Контейнер - это класс, объединяющий объявленные компоненты нейросети в одну общую конфигурацию, которая в дальнейшем может быть передана в процедуру обучения. Компонентом нейросети могут быть не только полносвязные или сверточные слои, но и функции активации или ошибки, а также готовые контейнеры. Torch позволяет создавать следующие слои:

    • Полносвязный слой (Linear).
    • Функции активации: гиперболический тангенс (Tanh), выбор минимального (Min) или максимального (Max), softmax-функция (SoftMax) и другие.
    • Сверточные слои: свертка (Convolution), прореживание (SubSampling), пространственное объединение (MaxPooling, AveragePooling, LPPooling), разностная нормализация (SubtractiveNormalization).
    Функции ошибки: средне-квадратичная ошибка (MSE), кросс-энтропия (CrossEntropy) и т.д.

    При обучении могут использоваться следующие методы оптимизации:

    Рассмотрим процесс конфигурирования нейронной сети в Torch. Сначала необходимо объявить контейнер, затем добавить в него слои. Порядок добавления слоев важен, т.к. выход (n-1)-го слоя будет входом n-го.
    regression = nn.Sequential() regression:add(nn.Linear(784,10)) regression:add(nn.SoftMax()) loss = nn.ClassNLLCriterion()
    Использование и обучение нейросети:

    1. Загрузка входных данных X. Функция torch.load(path_to_ready_dset) позволяет загрузить подготовленный заранее датасет в текстовом или бинарном формате. Как правило, это Lua-таблица состоящая из трёх полей: размер, данные и метки. В случае если готового датасета нет, можно воспользоваться стандартными функциями языка Lua (например, io.open(filename [, mode])) или функциями из пакетов библиотеки Torch (например, image.loadJPG(filename)).
    2. Определение ответа сети для входных данных X:
      Y = regression:forward(X)
    3. Вычисление функции ошибки E = loss(Y,T), в нашем случае это функция правдоподобия.
      E = loss:forward(Y,T)
    4. Просчет градиентов согласно алгоритму обратного распространения.
      dE_dY = loss:backward(Y,T) regression:backward(X,dE_dY)
    Теперь соберем все воедино. Для того чтобы обучить нейросеть в библиотеке Torch, необходимо написать собственный цикл обучения. В нем объявить специальную функцию (замыкание), которая будет вычислять ответ сети, определять величину ошибки и пересчитывать градиенты, и передать это замыкание в функцию градиентного спуска для обновления весов сети.
    -- Создаём специальные переменные: веса нейросети и их градиенты w, dE_dw = regression:getParameters() local eval_E = function(w) dE_dw:zero() -- Обновляем градиенты local Y = regression:forward(X) local E = loss:forward(Y,T) local dE_dY = loss:backward(Y,T) regression:backward(X,dE_dY) return E, dE_dw end -- Затем в цикле обучения вызываем optim.sgd(eval_E, w, optimState)
    где optimState - параметры градиентного спуска (learningRate, momentum, weightDecay и пр.). Полностью цикл обучения можно посмотреть .

    Несложно видеть, что процедура объявления, как и процедура обучения, занимает менее 10 строк кода, что говорит о простоте использования библиотеки. При этом библиотека позволяет работать с нейросетями на достаточно низком уровне.

    Сохранение и загрузка натренированной сети осуществляется с помощью специальных функций:
    torch.save(path, regression) net = torch.load(path)
    После загрузки сеть может быть использована для классификации или дополнительной тренировки. Если необходимо узнать, к какому классу принадлежит элемент sample, то достаточно выполнить проход по сети и вычислить выход:
    result = net:forward(sample)
    Более сложные примеры можно найти в обучающих материалах к библиотеке .

    Библиотека Theano


    Theano - это расширение языка Python, позволяющее эффективно вычислять математические выражения, содержащие многомерные массивы. Библиотека получила свое название в честь имени жены древнегреческого философа и математика Пифагора - Феано (или Теано). Theano разработана в лаборатории LISA для поддержки быстрой разработки алгоритмов машинного обучения.

    Библиотека реализована на языке Python, поддерживается на операционных системах Windows, Linux и Mac OS. В состав Theano входит компилятор, который переводит математические выражения, написанные на языке Python в эффективный код на C или CUDA.

    Theano предоставляет базовый набор инструментов для конфигурации нейросетей и их обучения. Возможна реализация многослойных полностью связанных сетей (Multi-Layer Perceptron), сверточных нейросетей (CNN), рекуррентных нейронных сетей (Recurrent Neural Networks, RNN), автокодировщиков и ограниченных машин Больцмана. Также предусмотрены различные функции активации, в частности, сигмоидальная, softmax-функция, кросс-энтропия. В ходе обучения используется пакетный градиентный спуск (Batch SGD).

    Рассмотрим конфигурацию нейросети в Theano. Для удобства реализуем класс LogisticRegression (), в котором будут содержаться переменные - обучаемые параметры W, b и функции для работы с ними - подсчет ответа сети (y = softmax(Wx + b)) и функция ошибки. Затем для тренировки нейросети создаем функцию train_model. Для нее необходимо описать методы, определяющие функцию ошибки, правило вычисления градиентов, способ изменения весов нейросети, размер и местоположение mini-batch выборки (сами изображения и ответы для них). После определения всех параметров функция компилируется и передается в цикл обучения.


    Рис. 3. Схема класса для реализации нейронной сети в Theano

    Программная реализация класса

    class LogisticRegression(object): def __init__(self, input, n_in, n_out): # y = W * x + b # объявляем переменные, определяем тип, количество входов и выходов self.W = theano.shared(# инициализируем начальные веса нулями value=numpy.zeros((n_in, n_out), dtype=theano.config.floatX), name="W", borrow=True) self.b = theano.shared(value=numpy.zeros((n_out,), dtype=theano.config.floatX), name="b", borrow=True) # добавляем функцию активации softmax, выход сети - переменная y_pred self.p_y_given_x = T.nnet.softmax(T.dot(input, self.W) + self.b) self.y_pred = T.argmax(self.p_y_given_x, axis=1) self.params = # определяем функцию ошибки def negative_log_likelihood(self, y): return -T.mean(T.log(self.p_y_given_x)) # x - подается на вход сети # набор изображений (minibatch) располагается по строкам в матрице x # y - ответ сети на каждый семпл x = T.matrix("x") y = T.ivector("y") # создаем модель логистической регрессии каждое MNIST изображение имеет размер 28*28 classifier = LogisticRegression(input=x, n_in=28 * 28, n_out=10) # значение функции ошибки, которое мы пытаемся минимизировать в течение обучения cost = classifier.negative_log_likelihood(y) # чтобы посчитать градиенты, необходимо вызвать функцию Theano - grad g_W = T.grad(cost=cost, wrt=classifier.W) g_b = T.grad(cost=cost, wrt=classifier.b) # определяем правила обновления весов нейросети updates = [(classifier.W, classifier.W - learning_rate * g_W), (classifier.b, classifier.b - learning_rate * g_b)] # компилируем функцию тренировки, в дальнейшем она будет вызываться в цикле обучения train_model = theano.function(inputs=, outputs=cost, updates=updates, givens={ x: train_set_x, y: train_set_y })


    Для быстрого сохранения и загрузки параметров нейросети можно использовать функции из пакета cPickle:
    import cPickle save_file = open("path", "wb") cPickle.dump(classifier.W.get_value(borrow=True), save_file, -1) cPickle.dump(classifier.b.get_value(borrow=True), save_file, -1) save_file.close() file = open("path") classifier.W.set_value(cPickle.load(save_file), borrow=True) classifier.b.set_value(cPickle.load(save_file), borrow=True)
    Несложно видеть, что процесс создания модели и определения ее параметров требует написания объемного и шумного кода. Библиотека является низкоуровневой. Нельзя не отметить ее гибкость, а также наличие возможности реализации и использования собственных компонент. На официальном сайте библиотеки имеется большое количество обучающих материалов на разные темы.

    Сравнение библиотек на примере задачи классификации рукописных цифр

    Тестовая инфраструктура

    В ходе экспериментов по оценке производительности библиотек использована следующая тестовая инфраструктура:
    1. Ubuntu 12.04, Intel Core i5-3210M @ 2.5GHz (CPU эксперименты).
    2. Ubuntu 14.04, Intel Core i5-2430M @ 2.4GHz + NVIDIA GeForce GT 540M (GPU эксперименты).
    3. GCC 4.8, NVCC 6.5.

    Топологии сетей и параметры обучения

    Вычислительные эксперименты проводились на полносвязной и сверточной нейронных сетях следующей структуры:

    Все веса инициализировались случайным образом согласно равномерному закону распределения в диапазоне (−6/(n_in + n_out), 6/(n_in + n_out)), где n_in, n_out – количество нейронов на входе и выходе слоя соответственно. Параметры стохастического градиентного спуска (SGD) выбраны, равными следующим значениям: learning rate - 0.01, momentum - 0.9, weight decay - 5e-4, batch size - 128, максимальное число итераций - 150.

    Результаты экспериментов

    Время обучения нейронных сетей, описанных ранее ( , ) с помощью четырех рассмотренных библиотек, представлено ниже (