Pull to refresh

Comments 10

Для питонистов, сишарперов и прочих обладателей нормальной рефлексии это может звучать дико, но таков уж старина C++.

Проблема не в С++, проблема в криворуких С++-разработчиках, которые пишут говнокод.

Полностью согласен. С++ это такая каша из всего вообще. От С до Swift. И вполне можно напороться в одном проекте на дефайны с лямбдами и адом из шаблонов. Java и С# сразу заставляют писать OOP/OOD, а не разводить кашу из С.

О, спасибо за наводку — выглядит вменяемо по документации И поддерживает GPU. Почему она мне не попадалась при поиске в Гугле?!
О, это прямо моя тема! Я недавно перебирал всякие либы для ML на C++. Итак, по порядку:

FANN — не C++, а C. Проставя в сборке, простая в использовании. Только CPU, причём без нормального распараллеливания по ядрам, кажется. Но самое худшее — нежданчики внутри, например параметр activation steepness, который судя по докам влияет лишь на скорость обучения, а в реальности — жестоко портит способность сетки различать разные входы, если их много, так как устанавливает жёсткий и низкий потолок на макс. сумму на входе нейрона. Да и вообще, в коде много подозрительных мест и магических чисел. Я ей сначала пользовался, но потом отказался.

tiny_dnn — пока остановился на ней. Довольно удобный интерфейс, сборки вообще не требуется, на CPU использует векторизацию вычислений и сама параллелит на все ядра. К сожалению, не умеет GPU, но обещают скоро научить.

TensorFlow C++ API — жуткий монстр. Собирается 30-40 минут на хорошей машине, при малейшей ошибке почему-то весь проект начинает пересобираться с нуля. Собирается (CMake, Bazel под Windows не вариант) только если строго следовать инструкциям, даже в тех местах, где они звучат как идиотизм (out of source build? Неа, не работает). В процессе сборки жрёт память гигабайтами, и у меня таки не собралось в конце концов с полным набором ядер. Сборка с неполным набором ядер — просто сломана. Ах, да, и даже если получится это всё собрать — нет способа выдрать из гигантского репозитория только либу и нужные хидера, потому что как обычно у Гугла (см. Breakpad) всё лежит огромной бессмысленной кашей. Но всё это можно было бы стерпеть, если бы не тот факт, что на C++ не реализовано пока что обучения (в планах вроде есть, но когда?). Точнее, оно как бы есть, но его как бы нет — придётся много кода писать руками, как я понял.

Microsoft CNTK. Поставляется в сборке, что радует. Только Release, без PDB, что не радует. При попытке собрать их собственный тест из репозитория — падает на первой же строчке. Документация отсутствует полностью («читайте хидер на X тысяч строк!»), примеры и тесты противоречивы, нет хелпер-функций для конструирования сетей, точнее, они есть, но только в рамках тестов, откуда их хорошо бы себе скопировать…

MxNet — честно говоря, не стал пробовать — очень запутанная терминология у них :( Почему нельзя как в tiny_dnn — сетка, слой, слой, слой, функция ошибки?! Нет, навыдумывали каких-то «Символов»… C++ API заявлен, но вроде как в «инкубаторе», так что можно юзать, или нет — не понятно толком.

Caffe — поддержка C++ заявлена в том плане, что «ну, у нас внутри всё написано на C++, поэтому линкуйтесь с нашей либой, и читайте исходники caffe.cpp, чтобы понять, как всё это работает». Пробовать не стал.

OpenNN тоже пробовал, но в самом начале пути, и возможно ступил — мне показалось, что в её парадигме невозможно реализовать Q-Learning, а мне был нужен именно он.

А есть какая-нибудь простенькая библиотека для обучения с подкреплением?

На Питоне я сам пробовал достаточно простую штуку keras-rl (https://github.com/matthiasplappert/keras-rl), там много примеров, включая классику жанра с играми на Атари (https://github.com/matthiasplappert/keras-rl/blob/master/examples/dqn_atari.py).

На C++ не встречал. В доке CNTK есть упоминание RI (https://github.com/Microsoft/CNTK/tree/master/Examples/ReinforcementLearning), но там вроде Keras и питон.
Простенькой лично я не видел, но простейший алгоритм самому написать недолго, если есть библиотека, реализующая базовый функционал (создание сетки, forward/backward pass, разные loss-функции).

А вообще, есть вот такая штука: github.com/samindaa/RLLib (для C++). С виду прям что-то очень мощное, десятки разных алгоритмов… Но я не разбирался в подробностях, как это всё использовать. У меня такое ощущение, что она реализует именно только алгоритмы RL, а базовый функционал сети ей нужен отдельно, но возможно я неправильно понимаю.

Немного запоздало, но всё же внесу свои 5 копеек.
Тоже, как и коментаторы выше остановился на tiny-dnn.
Простой и логичный интерфейс. Если какие-то вещи не документированы, то действительно легко (а не как в Caffe) найти их в исходниках.
Например, автор поста упоминает отсутствие возможности остановки обучения. Тоже сталкивался с этой проблемой. Пять минут обзора исходников и вуаля:


network<sequential>::stop_ongoing_training()

Использовать его можно как то так:


    net.fit<mse>(optimizer, train_src, train_targ, batch_size, epochs,
        []() {/*..*/},
        [&net]() {
            /*...*/
            net.stop_ongoing_training();
            /*...*/
        }
    );

Ещё tiny-dnn легко расширяется. Можно создавать свои функции ошибки, свои слои и т.п.
Из недостатков можно отметить жутко большое время компиляции; отсутствие GPU.
Некоторые архитектурные решения показались мне спорными. Но в сравнении с тем, что есть в других фреймворках, они всё равно на голову выше.
Очень удобная возможность загружать свои модели в json.
Особенно, когда приходится работать с ансамблями моделей и отбором моделей.
Для многих задач машинного обучения все недостатки с лихвой компенсируются простотой и удобством.

Стоит взглянуть и на Intel DAAL, пожалуй одна из самых быстрых библиотек для CPU: векторизует и параллелит на все ядра. Кроме нейронных сетей есть большой набор классических алгоритмов машинного обучения.
Sign up to leave a comment.

Articles