Библиотеки для глубокого обучения Theano/Lasagne |
||
МЕНЮ Искусственный интеллект Поиск Регистрация на сайте Помощь проекту ТЕМЫ Новости ИИ Искусственный интеллект Разработка ИИГолосовой помощник Городские сумасшедшие ИИ в медицине ИИ проекты Искусственные нейросети Слежка за людьми Угроза ИИ ИИ теория Внедрение ИИКомпьютерные науки Машинное обуч. (Ошибки) Машинное обучение Машинный перевод Реализация ИИ Реализация нейросетей Создание беспилотных авто Трезво про ИИ Философия ИИ Big data Работа разума и сознаниеМодель мозгаРобототехника, БПЛАТрансгуманизмОбработка текстаТеория эволюцииДополненная реальностьЖелезоКиберугрозыНаучный мирИТ индустрияРазработка ПОТеория информацииМатематикаЦифровая экономика
Генетические алгоритмы Капсульные нейросети Основы нейронных сетей Распознавание лиц Распознавание образов Распознавание речи Техническое зрение Чат-боты Авторизация |
2017-03-16 18:50 Параллельно с публикациями статей открытого курса по машинному обучению мы решили запустить ещё одну серию — о работе с популярными фреймворками для нейронных сетей и глубокого обучения. Я открою этот цикл статьёй о Theano — библиотеке, которая используется для разработки систем машинного обучения как сама по себе, так и в качестве вычислительного бекэнда для более высокоуровневых библиотек, например, Lasagne, Keras или Blocks. Theano разрабатывается с 2007 года главным образом группой MILA из Университета Монреаля и названа в честь древнегреческой женщины-философа и математика Феано (предположительно изображена на картинке). Основными принципами являются: интеграция с numpy, прозрачное использование различных вычислительных устройств (главным образом GPU), динамическая генерация оптимизированного С-кода. Будем придерживаться следующего плана:
Код с примерами из этого поста можно найти тут. Предисловие или лирическое отступление о библиотеках для глубокого обучения В настоящее время разработаны десятки библиотек для работы с нейронными сетями, все они, подчас существенно, различаются в реализации, но можно выявить два основных подхода: императивный и символьный. 1 Давайте посмотрим на примере, чем они различаются. Предположим, что мы хотим вычислить простое выражение Вот так оно выглядело бы в императивном изложении на языке python:
Интерпретатор исполняет код построчно, сохраняя результаты в переменных
Оба подхода имеют свои достоинства и недостатки. В первую очередь, императивные программы гибче, нагляднее и проще в отладке. Мы можем использовать все богатства используемого языка программирования, например, циклы и ветвления, выводить промежуточные результаты в отладочных целях. Такая гибкость достигается, в первую очередь, малыми ограничениями, накладываемыми на интерпретатор, который должен быть готов к любому последующему использованию переменных. С другой стороны, символьная парадигма накладывает больше ограничений, но вычисления получаются более эффективными, как по памяти, так и по скорости исполнения: на этапе компиляции можно применить ряд оптимизаций, выявить неиспользуемые переменные, выполнить часть вычислений, переиспользуя память и так далее. Отличительная черта символьных программ — отдельные этапы объявления графа, компиляции и выполнения. Мы останавливаемся на этом так подробно, потому что императивная парадигма знакома большинству программистов, в то время как символьная может показаться непривычной, и Theano, как раз, явный пример символьного фреймворка. Тем, кому хочется разобраться в этом вопросе подробнее, рекомендую почитать соответствующий раздел документации к MXNet (об этой библиотеке мы еще напишем отдельный пост), но ключевой момент для понимания дальнейшего текста заключается в том, что программируя на Theano, мы пишем на python программу, которую потом скомпилируем и выполним. Установка Для установки нам понадобятся: python версии старше 2.6 или 3.3 (лучше dev-версию), компилятор С++ (g++ для Linux или Windows, clang для MacOS), библиотека примитивов линейной алгебры (например ATLAS, OpenBLAS, Intel MKL), NumPy и SciPy. Для выполнения вычислений на GPU понадобится CUDA, а ряд операций, встречающихся в нейронных сетях, можно ускорить с помощью сuDNN. Начиная с версии 0.8.0, разработчики Theano рекомендуют использовать libgpuarray, что также даёт возможность использовать несколько GPU. Когда все зависимости установлены, можно установить Theano через
Настройка Theano можно настроить тремя способами:
Я обычно использую примерно такой конфигурационный файл:
Подробнее о конфигурации можно узнать в документации. Основы Первые шаги Теперь, когда всё установлено и настроено, давайте попробуем написать немного кода, например, вычислим значение многочлена в точке 10:
Здесь мы совершили 4 вещи: определили скалярную переменную Обратим внимание на тот факт, что переменные в Theano — типизированные, причем тип переменной содержит информацию как о типе данных, так и о их размерности, т.е. чтобы посчитать наш многочлен сразу в нескольких точках, потребуется определить
В данном случае нам нужно только указать количество измерений переменной при инициализации: размер каждого измерения вычисляется автоматически на этапе вызова функции. UPD: Не секрет, что аппарат линейной алгебры повсеместно используется в машинном обучении: примеры описываются векторами признаков, параметры модели записывают в виде матриц, изображения представляют в виде 3х-мерных тензоров. Скалярные величины, векторы и матрицы можно рассматривать как частный случай тензоров, поэтому именно так мы в дальнейшем будем называть эти объекты линейной алгебры. Под тензором будем понимать При несовпадении типов Theano выбросит исключение. Исправить это, кстати как и поменять многое другое в работе функций, можно, передав конструктору аргумент
Мы также можем вычислять несколько выражений сразу, оптимизатор в этом случае может переиспользовать пересекающиеся части, в данном случае сумму :
Для обмена состояниями между функциями используются специальные shared переменные:
Значения таких переменных, в отличие от тензорных, можно получать и модифицировать вне Theano-функций из обычного python-кода:
Значения в shared переменных можно «подставлять» в тензорные переменные:
Отладка Theano предоставляет ряд средств для отображения графа вычислений и отладки. Тем не менее, отладка символьных выражений по-прежнему остаётся задачей не из лёгких. Мы кратко перечислим тут наиболее употребимые подходы, подробнее об отладке можно прочитать в документации: http://deeplearning.net/software/theano/tutorial/printing_drawing.html Мы можем распечатать граф вычислений для каждой функции:
Заметьте, что сумма вычисляется только один раз:
Выражения можно выводить и в более лаконичной форме:
Или в виде графа:
К сожалению, читаемость таких графов резко падает с ростом сложности выражения. Фактически что-то понять можно только на игрушечных примерах. Машинное обучение на Theano Логистическая регрессия Давайте посмотрим на примере логистической регрессии, как с помощью Theano можно разрабатывать алгоритмы машинного обучения. Намеренно не будем вдаваться в подробности того, как устроена эта модель (оставим это до соответствующей статьи открытого курса), но напомним, что апостериорная вероятность класса имеет вид Давайте определим параметры модели, для удобства введём отдельный параметр для смещения:
И заведём символьные переменные для признаков и меток класса:
Давайте теперь определим выражения для апостериорной вероятности и предсказаний модели:
И определим функцию потерь вида:
Мы не стали выписывать выражения для сигмоиды и кросс-энтропии в явном виде, а воспользовались функциями из пакета Для оптимизации функции потерь давайте воспользуемся методом градиентного спуска, каждый шаг которого задаётся выражением: Давайте воплотим его в коде:
Здесь мы воспользовались замечательной возможностью Theano — автоматическим2 дифференцированием. Вызов Когда градиенты получены, нам остаётся лишь скомпилировать Theano-функции:
И запустить итеративный процесс:
Для сгенерированных мною данных процесс сходится к такой разделяющей прямой: Выглядит неплохо, но кажется, что для такой простой задачи 4000 итераций — это как-то многовато… Давайте попробуем ускорить оптимизацию и воспользуемся методом Ньютона. Этот метод использует вторые производные функции потерь и представляет собой последовательность таких шагов: где — матрица Гессе. Чтобы посчитать матрицу Гессе, создадим одномерные версии параметров нашей модели:
И определим шаг оптимизатора:
Хоть мы и пришли к тем же результатам, Пути обоих методов можно посмотреть на этом графике: SVC Так же мы без труда можем реализовать метод опорных векторов, для этого достаточно представить функцию потерь в следующем виде: В терминах Theano это можно написать с помощью замены нескольких строк в предыдущем примере:
это гиперпараметр, регуляризующий модель, а выражение просто переводит метки в диапазон Для выбранного С классификатор разделит пространство так: Нелинейные признаки Циклы являются одной из наиболее употребимых конструкций в программировании. Поддержка циклов в Theano представлена функцией scan. Давайте познакомимся с тем, как она работает. Думаю, читателям уже очевидно, что линейная функция от признаков — не лучший кандидат на разделение сгенерированных данных. Этот недостаток можно исправить, добавив полиномиальные признаки к исходным (этот приём подробно описан в другой статье нашего блога). Итак, хочется получить преобразование вида . В python мы могли бы реализовать его, например, так:
В Theano это выглядит следующим образом:
Первой в
Проиллюстрируем работу полученного выражения простым примером:
Чтобы воспользоваться плодами своих усилий, достаточно поменять определение модели и добавить параметров (ведь признаков стало больше):
Новые признаки позволяют значительно лучше разделить классы: Нейронные сети и Lasagne3 К этому моменту мы уже обсудили основные этапы создания систем машинного обучения на Theano: инициализация входных переменных, определение модели, компиляция Theano-функций, цикл с шагами оптимизатора. На этом можно было бы и закончить, но очень уж хочется познакомить читателей с Lasagne — замечательной библиотекой для нейронных сетей, работающей поверх Theano. Lasagne предоставляет набор готовых компонентов: слоёв, алгоритмов оптимизации, функций потерь, инициализаций параметров и т.д., при этом не скрывает Theano за многочисленными слоями абстракций. Рассмотрим, как может выглядеть типичный код на Theano/Lasagne на примере классификации MNIST'a. Примеры изображений из MNIST, если вы их еще не видели Сконструируем многослойный перцептрон с двумя скрытыми слоями по 800 нейронов, для регуляризации будем использовать dropout и разместим этот код в отдельной функции:
Получим вот такую простую полносвязную сеть: Инициализируем тензорные переменные и скомпилируем Theano-функции для обучения и валидации:
Теперь создадим цикл обучения:
Получившиеся кривые обучения: Нашей модели удаётся достичь точности более 98 %, что, несомненно, можно улучшить, используя, например, свёрточные нейронные сети, но эта тема уже выходит за рамки данной статьи. Сохранять и загружать веса удобно с помощью хелперов:
Документация к Lasagne доступна тут, масса примеров и предобученные модели находятся в отдельном репозитории. Заключение В этом посте мы довольно поверхностно ознакомились с возможностями Theano, узнать больше можно:
Большая благодарность bauchgefuehl за помощь в подготовке поста. 1. Граница между двумя подходами довольно размыта, и не всё сказанное ниже строго верно, всегда есть исключения и пограничные случаи. Наша задача тут — передать основную идею. 2. Разработчики Theano в техническом отчёте и документации называют дифференцирование символьным. Однако, использование этого термина в одной из предыдущих статей на Хабр вызвало обсуждение. Исходя из исходного кода Theano и определения на Википедии, автор считает, что правильный термин всё же «автоматическое дифференцирование». 3. Материал этого раздела по большей части основан на документации к Lasagne. Источник: habrahabr.ru Комментарии: |
|