Понятное руководство по установке разных версий (CPU/GPU) для разных языков и под разные устройства появилось относительно недавно. Подготовительные этапы типа установки драйверов и CUDA/cuDNN были рассмотрены в этом сообщении, повторяться не будем. Для Python, кстати, можно ничего не собирать из исходников, а просто ставить командой pip install mxnet --pre. В ситуации, когда ядер CPU относительно много, а ОЗУ относительно мало, при сборке из исходников можно столкнуться с нехваткой памяти. В таком случае следует запустить сборку в однопоточном режиме: make -j1. Библиотеку можно использовать также в коде на языках Julia, Scala и, внезапно, Perl. А еще заявлена поддержка работы на Raspberry Pi 3. Создадим искусственный набор данных из 10000 наблюдений (num_examples) с двумя признаками (num_inputs) и одной целевой переменной (num_outputs). Истинная форма зависимости между предикторами и целевой переменной задана функцией real_fn(), к сгенерированных при помощи этой функции значениям добавлен небольшой гауссовский шум 0.01 * rnorm(num_examples): За обучение нейросетей прямого распространения отвечает функция mx.model.FeedForward.create(). Список принимаемых ею параметров выглядит следующим образом: Создадим итератор по массиву (матрице) данных: Функция принимает на вход массив или матрицу признаков (в данном случае, как уже было сказано, матрицу нужно транспонировать), массив со значениями целевой переменной и размер батча. Также мы включили перемешивание наблюдений опцией shuffle = TRUE. Список всех доступных итераторов выглядит так: Сейчас мы не будем рассматривать ни остальные варианты, ни написание собственных итераторов. Архитектура сети описывается путем последовательных вызовов функций семейства mx.symbol.*, каждая из которых добавляет к модели абстрактные представления слоев: полносвязного, сверточного, пулингового и других. Слоев доступно очень много: Для создания простой линейной модели, решающей задачу регрессии, служит следующий код: Нарисуем получившуюся архитектуру: Инициализатор определяет, с каких начальных значений стартует обучение нейросети. Поскольку наша сеть очень простая и неглубокая, достаточно инициализировать веса случайными значениями, имеющими нормальное распределение: Единственным принимаемым параметров в данном случае является стандартное отклонение. Также имеется инициализатор mx.init.uniform(), единственным параметром которого является граница диапазона, из которого генерируются значения. Для глубоких сетей правильная инициализация весов имеет большое значение, поэтому мы бы воспользовались вариантом mx.init.Xavier(). Эта схема инициализации весов была придумана в 2010 году Йошуа Бенджио и Ксавье Глоро (Xavier Gloro), в честь которого метод и получил свое название. В настоящий момент используется повсеместно под разными именами, например, в Keras можно найти glorot_normal glorot_uniform. Библиотека для Python содержит также множество других инициализаторов, недоступных в варианте для R. Например, отсутствует возможность использовать предпочтительный вариант инициалиализции весов нейронов с функцией активации ReLU — инициализацию Хе. Параметры функции mx.init.Xavier(): Если rnd_type = "uniform" и factor_type = "avg" (по умолчанию), веса будут инициализированы случайными значениями из диапазона , где ,  — число нейронов на входе (т.е. в предыдущем слое),  — число нейронов на выходе (т.е. в следующем слое). Если rnd_type = "uniform" и factor_type = "in, то . Аналогично, при rnd_type = "uniform" и factor_type = "out" получим . При rnd_type = "gaussian" и factor_type = "avg" веса будут извлекаться из нормального распределения со стандартным отклонением . Оптимизатор определяет способ обновления весов сети. Доступные варианты: sgd, rmsprop, adam, adagrad и adadelta. Создать оптимизатор с нужными настройками можно при помощи общей функции mx.opt.create(): Чтобы узнать о параметрах каждого из оптимизаторов, которые будем передавать в вызов mx.opt.create(), воспользуемся справкой: Сами эти функции привычным способом вызвать нельзя (но к ним можно получить доступ: mxnet:::mx.opt.adagrad). Параметры mx.opt.sgd() Параметры mx.opt.rmsprop() Параметры mx.opt.adadelta(): Обратите внимание: для скорости обучения параметр не предусмотрен.  Оптимизатор Adadelta похож на RMSprop, но Adadelta делает вторую поправку с изменением единиц и хранением истории обновлений, а RMSprop просто использует корень из среднего от квадратов градиентов. Следующий алгоритм — Adagrad — использует сглаженные версии среднего и среднеквадратичного градиентов. Подробнее обо всем этом можно прочитать в книге Глубокое обучение, которая рекомендуется к прочтению целиком. Параметры mx.opt.adagrad(): Параметры mx.opt.adam(): Сохранять историю обучения будем при помощи соответствующей callback-функции: После обучения объект logger будет содержать информацию вида Другие колбэки: mx.callback.early.stop() отвечает за раннюю остановку, mx.callback.log.speedometer() выводит скорость обработки с заданной частотой, mx.callback.save.checkpoint() сохраняет модель через заданные промежутки в файл с заданным префиксом. Обучение запускается вызовом описанной выше функции mx.model.FeedForward.create(): Изобразим историю обучения: Проверим, как работает наша модель: Все работает, можно переходить к более серьезному примеру! Рассмотрим решение задачи регрессии на примере прогнозирования степени проникаемости (по сути — скорости пассивной диффузии) вещества через монослой клеток исходя из известных свойств этого вещества (подробнее см. здесь). Существует особая процедура регистрации генерических лекарственных препаратов — так называемый биовейвер. Она подразумевает оценку биоэквивалентности путем проведения тестов на растворимость и проникаемость (in vitro) вместо сравнительных фармакокинетических/фармакодинамических/клинических испытаний (in vivo). В качестве стандартной модели для оценки проникаемости веществ используется монослой клеток линии Caco2. Если научиться заранее предсказывать степень проникаемости, появится возможность более осознанно подходить к выбору веществ-кандидатов, проверяемых в ходе экспериментов.  Описанной задаче посвящена работа ADME evaluation in drug discovery. 5. Correlation of Caco-2 permeation with simple molecular properties. В ней приводится таблица, содержащая характеристики 77 различных по структуре веществ, а также экспериментальные данные по проникаемости этих веществ. Следует отметить, что данные, полученные для одного и того же вещества в ходе разных экспериментов, могут значительно варьировать. Но мы не будем углубляться в этот аспект проблемы, а просто возьмем те данные, с которыми работали авторы публикации. Загрузим данные при помощи кода, созданного полезной функцией dump(): Целевой переменной является log_P_eff_exp — логарифм скорости диффузии (которая измеряется в см/с). Список предикторов: Рассмотрим распределения предикторов, а также их парные корреляции: Переменные rgyr и rgyr_d, а также HCPSA и TPSA предсказуемо сильно коррелируют, поскольку в обоих случаях пары переменных представляют собой разные способы расчета одной и той же физической величины. Обучим такую же нейронную сеть, как и в предыдущем примере. На этот раз разобъем выборку на обучающую и проверочную, и в этот раз обойдемся без итераторов. Посмотрим, как менялась метрика RMSE на обучающей и проверочной выборке: В следующем сообщении мы решим задачу классификации на реальных данных, а также рассмотрим другие метрики качества и использование ранней остановки. Биостатистик