Привет, Хабр! Меня зовут Женя. В начале карьеры я был 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) за иллюстрацию к этой статье.

Комментарии (17)


  1. rotor
    05.09.2017 11:42
    +4

    Ребят, сделайте нормальную документацию к C++ API и люди к вам потянутся.
    Отрасль уже готова выйти за рамки Питона и Луа.
    Вы сравниваете CNTK с TensorFlow. Но все кто хоть немного поработал в отрасли уже знают о больячках TensorFlow. И это сравнение не выглядит убедительным.
    Сейчас CNTK — просто ещё один фреймворк на Питоне и, внезапно, BrainScript.
    Киллер-фич по сравнению с Torch, Caffe или тем же Teano не видно.
    И опять, нет ясной и удобной документации C++, а это как раз то, чего не хватает остальным мейнстримовым фреймворкам.


    1. gaploid
      05.09.2017 15:10
      +1

      Похоже, основная фича у CNTK это скорость на LSTM сетях, нашел пару бенчмарков arxiv.org/abs/1608.07249 и minimaxir.com/2017/06/keras-cntk на обучении до 3-5 раз быстрее чем TF.


      1. evgri Автор
        05.09.2017 15:49
        +1

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


    1. evgri Автор
      05.09.2017 15:58
      +2

      На GitHub есть соответствующий issue на тему документации C++. Команда CNTK говорит, что она занимается ее улучшение. Будет хорошо, если вы поддержите это начинание комментарием, чтобы показать ее важность.

      Также C# Binding для обучения сейчас находится в разработке. :)


  1. Arseny_Info
    05.09.2017 12:54
    +9

    Статья в духе «у нас есть всякое хорошее и нет ничего плохого», попахивает классическим маркетинговым булшитом. Не хватает более конкретных примеров, кусков кода и т.п. Сравните, например, с недавней статьей про Pytorch.


  1. UndeadDragon
    05.09.2017 13:15
    +5

    Точность. На сегодняшний день CNTK обладает одной из самых высоких точностей для обучения моделей глубинного обучения.


    Что такое точность Фреймворка и как вы ее сравнивали с другими?

    Результаты исследования HKBU и эта статья показали, что во всех протестированных сетях CNTK обеспечивает более высокую производительность, чем TensorFlow, с точки зрения как CPU, так и графических процессоров.

    image
    На сайте все тесты на CPU медленнее у CNTK, чем у TF. А вы говорите, что «во всех протестированных...». А производительность на CPU это крайне важно для продакшена — мобильные платформы в этом очень нуждаются.

    В общем многовато голословных заявлений в статье. Кроме того, зачем ваш фреймворк нужен не сформулировано. Как правильно отметили выше — нету киллерфич. Если нужна простота пртотипирования и экспериментов — есть PyTorch. Если нужны плюсы и минимум кода, готовые модели — Caffe. Скорость на CPU (да и на GPU неплох) и Си — LuaTorch. Низкоуровневость и гибкость — TF. Какое тут место занимает CNTK? Я боюсь, что он занимает скорее маркетологическое место. Что мол Майкрософт не отстает от жизни.


    1. evgri Автор
      05.09.2017 16:22
      +2

      Подправил фразу в разделе про производительность, чтобы не вводить в заблуждение.

      Идея утверждения про точность состоит в том, что на базе CNTK удалось показать большую точность на той же архитектуре, чем при использовании TensorFlow. С учетом специфик алгоритмов и процедур обучения, «багов» разные фреймворки могут показывать разную максимальную точность одной и той же сети на одних и тех же данных. Это позволяет в некоторой мере говорить о таком понятии как «точность Фреймворка.»


      1. UndeadDragon
        05.09.2017 17:08

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


    1. shwars
      05.09.2017 16:44
      +1

      На самом деле почти все фреймворки реализуют одну и ту же функциональность и дублируют друг друга. При этом они создают здоровую конкуренцию, что хорошо. Из описанных преимуществ CNTK самым важным, на мой взгляд, является сквозное многоуровневое API на C++, которое позволяет описывать архитектуру сети на низком уровне, как в TF, или же на высокоуровневом функциональном API, как в Keras. Реализация обучения в виде C++ API, масштабирование на кластеры из GPU в разных конфигурациях, эффективная и удобная поддержка RNN — вот, наверное, основные преимущества. Тянут ли они на killer feature — вопрос скорее терминологический.

      Кстати, поддержка Keras недавно тоже добавилась, поэтому если вы используете Keras — можно просто попробовать CNTK как другой бэкенд и посмотреть на разницу. Если у кого-то будет такой опыт — поделитесь с нами!


  1. gedd
    05.09.2017 14:58
    -11

    Лично меня пока бесит нетрадиционная pyton ориентация, вообще нет совместимости с C# на котором пишет большинство разработчиков… то есть большинство нейросетевых фрейворков просто не возможно использовать… это в полной мере касается CNTK. Убедите меня примером на C# если я не прав.


    1. shwars
      05.09.2017 15:48
      +2

      На самом деле нетрадиционная ориентация неслучайна — Python является стандартом де-факто для Data Science. Именно поэтому Microsoft добавил Python API. Изначально (и именно в таком режиме CNTK использовался внутри компании) идея была в том, чтобы тренировать сетки на BrainScript, а использовать — через API (в т.ч. C#/.NET). Пример использования на .NET есть тут: github.com/Microsoft/CNTK/tree/master/Examples/Evaluation

      Однако что выгодно отличает CNTK от Tensorflow (и что обеспечивает прирост в скорости) — это тот факт, что API для обучения также реализовано на C++ (в отличие от Python в случае TF). Это позволяет достаточно просто перейти к обучению сетей также из языков типа C# — и сейчас такая работа ведется. Вот тут github.com/Microsoft/CNTK/issues/2194 например обещают предварительное API для обучения на C# к середине сентября. Другое дело, что обучать на C# будет не так комфортно, как на Python, поскольку нет таких мощных библиотек для работы с матрицами, как numpy.


      1. gedd
        05.09.2017 17:38
        +1

        вообще нужен не интерфейс в c#,
        а общий интерфейс для подключения из сторонних программ что то типа подключаемой dll


        1. shwars
          05.09.2017 17:59
          +1

          Так оно и будет, по сути дела речь идёт о расширении .NET interop dll, чтобы она включала в себя функции обучения, а не только evaluation. Просто примеры логичнее всего делать на C# (или F#)


          1. gedd
            05.09.2017 18:03

            о я буду очень ждать :-)


  1. gedd
    05.09.2017 16:56
    +1

    >Вот тут github.com/Microsoft/CNTK/issues/2194 например обещают предварительное API для обучения на C# к середине сентября
    было бы здорово… и скорее бы… так как фреймворки нейронных сетей и c# что то ни как не могут состыковаться

    >обучать на C# будет не так комфортно, как на Python, поскольку нет таких мощных библиотек для работы с матрицами, как numpy
    что мешает сделать так чтобы было комфортно и что мешает добавить необходимые библиотеки?


  1. N01Z3
    05.09.2017 17:02
    +3

    Выглядит как маркейтинг. Где графики, где бенчмарки, где точные цифры?
    Сплошные «CNTK в целом работает быстрее, чем TensorFlow» и «Точность выше». Где пример как «всего несколько строк кода» распараллеливает обучение на 4 видюхи?


    1. gedd
      05.09.2017 17:19

      >CNTK в целом работает быстрее, чем TensorFlow
      это не первая и не единственная статья о том что TensorFlow медленнее, но я думаю что скорость важна, но не совсем главное, главное: удобство, документированность и совместимость со всем и вся