Привет! Меня зовут Женя. В начале карьеры я был Data Scientist, когда это еще не было мэйнстримом. Потом переключился на чистую T-SQL разработку, которая под конец успела перерасти в бизнес-аналитику. Теперь я — технологический евангелист в Microsoft с очевидным упором на платформу данных, хотя это не мешает мне заниматься в свободное время другими классными темами, как, например, Docker контейнеры или Mixed Reality.
Недавно я общался с одним из партнеров и он спросил меня, почему мы почти не рассказываем о преимуществах CNTK на Хабре. Сначала мы подумали, что может быть банальнее, чем рассказа в блоге компании и преимуществах продукта этой же компании. Но потом решили, что это отличная возможно узнать ваше мнение и пообщаться. Приглашаю под кат всех, кому интересна тема CNTK и TensorFlow.
Microsoft Cognitive Toolkit (CNTK) — бесплатный общедоступный набор инструментов с открытым исходным кодом для глубинного обучения. Если в качестве мерила взять звезды GitHub, то сегодня это третий по популярности специализированный пакет для глубинного обучения после TensorFlow и Caffe, который оставил позади такие платформы, как MxNet, Theano, Torch и так далее.
Disclaimer! Эта статья не претендует на единственную истину, но раскрывает ключевые особенности CNTK. Будем рады узнать ваше мнение в комментариях.
CNTK и TensorFlow: Кратко
Итак, переходим к сути. В чём разница между CNTK и TensorFlow:
- Скорость. CNTK в целом работает быстрее, чем TensorFlow, а в рекуррентных сетях дает вплоть до пяти- и десятикратного выигрыша в производительности.
- Точность. На сегодняшний день CNTK обладает одной из самых высоких точностей для обучения моделей глубинного обучения.
- Структура API. CNTK имеет гибкий и мощный API для C++ и предлагает как низкоуровневые, так и простые в использовании высокоуровневые Python API на основе парадигмы функционального программирования.
- Масштабируемость. CNTK легко масштабируется и в случае вычислительно требовательных задач может выполняться хоть на тысячах графических процессоров.
- Скоринг. В CNTK есть производительный Eval API для C++, .NET, Java и Python, для упрощения интеграции нейронных сетей в свои приложения.
- Расширяемость. CNTK легко расширяется благодаря возможности использования Python для определения собственных слоев и процедур обучения.
- Встроенные модули считывания. В CNTK есть нетребовательные к памяти встроенные средства чтения данных, поддерживающие распределенное обучение.
Если предыдущие краткие аргументы у вас вызвали вопросы и сомнения, дальше мы остановимся подробнее на каждом из них.
CNTK и TensorFlow: Подробно
Скорость
При глубинном обучении обрабатываются огромные объемы данных, что требует больших вычислительных ресурсов. Если вы разрабатываете приложение или готовите научную статью, успех во многом зависит от скорости проведения экспериментов.
Результаты исследования HKBU и эта статья показали, что во всех протестированных сетях CNTK обеспечивает более высокую производительность, чем TensorFlow, с точки зрения как CPU, так и графических процессоров. На самом деле, если брать в расчет только запуск на графических процессорах, CNTK показал наилучшие результаты среди всех протестированных пакетов.
При работе с изображениями CNTK обычно обеспечивает прирост производительности в два-три раза по сравнению с TensorFlow. Что касается рекуррентных нейронных сетей, то здесь CNTK является безоговорочным лидером (как говорится в вышеупомянутой статье, при запуске на CPU «CNTK показывает гораздо лучшую производительность (до 5-10 раз), чем Torch и TensorFlow»). А при выполнении на графических процессорах, «CNTK продемонстрировал на порядок лучшие результаты, чем остальные инструменты».
Выигрыш в скорости — не просто результат удачного стечения обстоятельств. CNTK изначально разрабатывался командой специалистов по распознаванию речи в Microsoft Research и был оптимизирован для обработки последовательностей. Например, он используется при построении модели распознавания естественного языка с обучающей выборкой в более, чем 4 миллиардами примеров.
Если в вашем проекте используется обработка последовательностей, например, для распознавания речи, обеспечения понимания естественного языка, машинного перевода и так далее, то CNTK будет для вас оптимальным выбором в плане производительности. Также, поробуйте CNTK, если вы занимаетесь обработкой видео и распознаванием образов.
Точность
Если вы разбираетесь в теме глубинного обучения, наверняка знаете, насколько сложно разрабтывать наборы инструментов. Ошибки в коде инструментария могут оказаться незаметными и во многих случаях не блокировать получение высокоэффективных моделей. Но, такие ошибки часто не позволяет раскрыть полные возможности архитектуры сети и искусственно занижают результаты. Поэтому наши коллеги, занимающиеся разработкой CNTK, уделяют большое внимание выявлению ошибок, гарантируя, что инструментарий позволяет обучать модели с нуля и достигать высочайшей точности.
В качестве примера можно привести историю с сетью Inception V3, разработанную несколькими исследователями в Google. Специалисты TensorFlow предложили скрипт обучения Inception V3 и предварительно обученную модель для скачивания и проверки. Однако переобучить модель с нуля и добиться аналогичной точности не получалось, поскольку для этого требовались дополнительные сведения, в том числе о предварительной производимой обработке данных. Максимальная точность, достигнутая третьей стороной (в данном случае это Keras), примерно на 0,6 % ниже той, что указали разработчики в своей статье. В результате экспериментов исследователям из команды CNTK удалось обучить модель CNTK Inception V3 с максимальной ошибкой 5,972 %, что оказалось даже лучше указанного в оригинальной статье показателя. Вы можете сами убедиться в этом результате, сценарий обучения доступен на GitHub.
В дополнение отметим, что алгоритм автоматической пакетной обработки CNTK позволяет упаковывать последовательности различной длины и достигать высокой эффективности выполнения для рекуррентных нейронных сетей. Более того, он улучшает рандомизацию данных для обучения и часто повышает точность на 1-2% по сравнению с упаковкой данных на основе других методов. Благодаря такому подходу исследователи из Microsoft Research впервые научили компьютер распознавать речь не хуже, чем это удается человеку.
Структура API
Мы с самого начала предполагали, что неотъемлемой частью приложений будет не только скоринг уже готовых моделей. Средства обучения также могут быть тесно интегрированы в «интеллектуальные» приложения, например, Office или Windows. Практически вся функциональность CNTK пишется на C++. Это не позволяет не только улучшить быстродействие, но и использовать его в качестве C++ API, готового к интеграции в любые приложения. Кроме того, это упрощает добавление дополнительных обвязок, таких как Python, Java, .NET и так далее.
Также необходимо отметить, что Python API в CNTK имеет низкоуровневую и высокоуровневую реализации. Python API высокого уровня основан на парадигме функционального программирования, он очень компактен и интуитивно понятен, это особенно заметно при работе с рекуррентными нейронными сетями. В этом главное отличие от Python API в TensorFlow, который большинство специалистов считают «слишком низкоуровневым».
Масштабируемость
В рамках современных задач глубинного обучения применяются миллиарды примеров для обучения. Поэтому необходимо реализовать возможность запуска на нескольких графических процессорах и нескольких компьютерах. Многие наборы инструментов умеют работать с несколькими графическими процессорами, но только на одном компьютере. Масштабирование с увеличением количества машин возможно, но для его реализации, чаще всего, потребуются немалые усилия.
CNTK, напротив, проектировался с идеей распределенного обучение в своей основе. Перейти от обучения на одном графическом процессоре к конфигурации с несколькими графическими процессорами на нескольких компьютерах очень просто, это всего несколько строк кода, что подтверждается примерами из репозитория CNTK. Исследователи Microsoft запускали обучение задач с помощью CNTK на сотнях графических процессоров и множестве компьютеров. Дополнительно во фреймворк включены несколько высокоэффектиных схем параллельного обучения: 1-bit SGD и Block-Momentum SGD. Эти алгоритмы значительно оптимизировали настройку гиперпараметров, что ускорило подготовку более качественных моделей, в результате чего, например, специалистам подразделения Microsoft Research удалось значительно улучшить качество распознавания естественного языка, превзойдя человека на тестовой выборке телефонных разговоров Switchboard.
Скоринг
TensorFlow обеспечивает превосходное возможности скоринга. Платформа поддерживает несколько версий моделей, сохраняет их в формате оптимизированной для исполнения, а использование различных метаграфов внутри одной модели обеспечивает поддержку различныx типов устройств. Кроме того, благодаря XLA AoT компиляции TensorFlow может преобразовывать модель в исполняемый файл, что значительно уменьшает размер модели для мобильных и встроенных устройств и минимизирует задержки.
В отличие от TensorFlow, CNTK больше ориентируется на непосредственную интеграцию CNTK Eval в пользовательские приложения. В дополнение к Python и C++ CNTK поддерживает C#/.NET и Java для скоринга. В основе этих API лежит все тот же C++ API, что позволяет при использовании получить все тот же уровень производительности. Если вы создаете приложение .NET и хотите выбрать набор инструментов для глубинного обучения и извлечения сведений, CNTK может оказаться более удобным вариантом.
CNTK поддерживает параллельное использование обученных моделей, причем нагрузка на память в таком сценарии увеличивается незначительно. Это открывает большие возможности для развертывания моделей в виде служб, например, в веб-приложении или REST API. CNTK также поддерживает развертывание на периферийных устройствах на базе Intel или ARM.
Расширяемость
TensorFlow — очень гибкий инструментарий, позволяющий реализовать практически любую модель. Однако если вы в настоящее время используете Caffe, то преобразовать легко существующий сценарий в сценарий TensorFlow не получится. Придется переписывать все с нуля. Аналогичным образом, для того, чтобы опробовать новый слой, созданный другим разработчиком с помощью другого набора инструментов, вам придется реализовать его самостоятельно.
На фоне этого CNTK можно назвать высоко расширяемым набором инструментов. Абстракция UserFunctions позволяет реализовать любой оператор средствами Python. Используя массив NumPy в качестве посредника между CNTK и своим расширением, вы просто реализуете прямой и обратный проход, после чего вновь созданный оператор можно сразу включать в структуру сети. Более того, граф из другого набора инструментов часто можно поместить напрямую в CNTK UserFunction, тем самым значительно ускорив портирование проектов, позволив себе использовать уникальные для CNTK возможности.
Это относится и к процедурам градиентного обновления весов. В поставку CNTK уже входит большинство алгоритмов, например, RMSProp или Adam, но тем не менее вы можете реализовать новые подходы к обучению, используя чистый Python.
Встроенные модули считывания
Вполне очевидный факт: чем больше данных для обучения у нас будет, тем лучшие результаты мы получим. В некоторых ситуациях объем данных настолько велик, что они не помещаются в ОЗУ, а иногда им может не хватить ресурсов одного компьютера. Даже когда данные в ОЗУ помещаются, в рамках цикла обучения часто тратится слишком много времени на передачу данных из ОЗУ в память GPU.
Встроенные модули считывания CNTK решают вышеперечисленные проблемы, предоставляя высокоэффективные возможности итераций по набору данных, без помещения их в ОЗУ. Работать можно как с одним диском, так и с распределенной файловой системой, например HDFS. Широкое применение предварительных выборок исключает простои графического процессора. Считыватели CNTK также гарантируют, что модель всегда получает данные в хорошо перемешанном виде (что улучшает сходимость), даже если базовый набор данных был упорядочен. Наконец, все эти возможности доступны и нынешним, и пользовательским считывателям. Даже если вы пишете считыватель для собственного нестандартного формата, можете не беспокоиться о реализации процедур формирования предварительной выборки.
В завершении, будем рады услышать ваши комментарии как под этой статьёй, так и получить pull request'ы, чтобы вместе превратить CNTK в самый крутой и удобный инструмент глубинного обучения.
P.s. Благодарим Константина Кичинского (Quantum Quintum) за иллюстрацию к этой статье.
Автор: evgri