Я реализовал многопроцессорность для оптимизации кода машинного обучения

Обучение моделей машинного обучения может занять время, много времени. Традиционные модели, в которых используются традиционные алгоритмы машинного обучения, такие как машина опорных векторов или наивный байесовский метод, могут занять меньше времени, но мы не будем говорить об этих алгоритмах. Поговорим о нейронных сетях.

Понимаете, последние несколько месяцев я работал над проектом с командой. Над чем я работал? Мы разрабатывали систему оценки упражнений в реальном времени, используя - как вы догадались, искусственные нейронные сети. LSTM и некоторые нейронные сети с прямой связью, если быть точным.

То, что мы хотели сделать, было довольно простым:

  1. Во-первых, нам нужен был многопозиционный классификатор, чтобы классифицировать тип упражнения в соответствии с исходной позицией нашего упражнения с использованием нейронной сети с прямой связью.
  2. Затем нам нужен двоичный классификатор, чтобы можно было определить, находится ли повторение упражнения в исходной позиции.
  3. После классификации исходной позиции нам нужно было оценить каждое повторение упражнения, убедившись, что подсчитали, сколько было найдено правильных повторений.

Все просто, правда? Звучит просто, но на самом деле нам нужно было собрать огромный объем данных для обучения наших сетей. Кроме того, нам также нужно было обучить не одну, не две, а девять моделей. Вот как работает математика: мы хотели классифицировать четыре типа упражнений. Таким образом, нам нужно восемь моделей, потому что каждое упражнение имеет бинарный классификатор позы и модель оценки позы в упражнении. Также нам понадобится дополнительная модель в качестве классификатора нескольких поз.

Ой.

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

Постойте, почему многопроцессорность?

Почему первая реакция в нашем сознании - это многопроцессорность? Поясню, наш проект - исследовательский. Нам нужно найти лучшую архитектуру нейронной сети. Нам также необходимо найти лучший гиперпараметр, соответствующий нашим потребностям. Мы использовали некоторые ссылки из предыдущих исследований, но, очевидно, мы не копировали их полностью. Архитектура нейронной сети предыдущего исследователя не совсем соответствует нашей.

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

Ответ - многопроцессорность.

Теперь фреймворки машинного обучения, такие как Keras и Tensorflow, действительно используют несколько ядер ЦП, когда они доступны. Но проблема не в том, что наши ядра используются должным образом, а в том, как мы выживаем из нашего оборудования все возможности, чтобы сэкономить драгоценное время.

Как вы реализовали многопроцессорность?

Позвольте мне первым сказать, что этот метод может работать не для всех, и я объясню почему. Наши модели, даже несмотря на то, что они имеют несколько доступных комбинаций, на самом деле не требуют большой вычислительной мощности для обучения.

Какую модель вы тренировали?

И наши двоичные, и многопозиционные классификаторы используют нейронные сети с прямой связью. Мы извлекаем наши данные из изображения с помощью предварительно обученной модели под названием OpenPose.

Затем мы извлекаем положение каждой ключевой точки из каждого кадра в виде массива (мы использовали около 14 доступных ключевых точек). Затем мы нормализовали данные и передали их в нашу нейронную сеть с прямой связью. Вы можете сказать, что наш метод обучения - простой.

Из-за небольшой вычислительной мощности, необходимой для обучения нейронной сети такого масштаба, мы попытались применить многопроцессорность в качестве нашего решения, чтобы ускорить работу. Хотя мы не так широко использовали многопроцессорность в моделях LSTM для оценки поз упражнений, как те, которые используют нейронные сети с прямой связью.

Причина в том, что LSTM требуют гораздо больше вычислительной мощности для обучения. Представьте себе 14 извлеченных ключевых точек и умножьте их на 24–48 кадров, каждая точка данных станет серией ключевых точек. Чтобы обучить это, требуется гораздо больше, чем эффективность многопроцессорной обработки.

Примеры кода

Для реализации многопроцессорности мы использовали модуль многопроцессорность в Python. Модуль многопроцессорности имеет очень чистый интерфейс. Реализовать многопроцессорность было довольно просто.

Сначала установите модуль.

pip3 install multiprocess

Теперь предположим, что мы хотим обучить четыре разных типа моделей с шестью комбинациями гиперпараметров для каждого типа.

У нас также есть функция под названием train_model. Функция исключает четыре параметра: тип упражнения, количество скрытых слоев, размер пакета и, наконец, данные обучения.

Итак, чтобы сэкономить время, мы хотим тренировать шесть комбинаций одновременно.

Пример можно увидеть выше. Это не кажется слишком сложным, к тому же его легко читать.

Результаты, достижения

При обучении нейронных сетей с прямой связью наша машина легко справляется с шестью процессами. Однако модель LSTM могла одновременно обрабатывать только три процесса. При применении многопроцессорной обработки для обучения моделей машинного обучения другой проблемой, которая может стать проблемой, будет оперативная память. Поскольку мы загружаем набор данных шесть раз в шесть разных процессов, мы сохранили его в ОЗУ. Давайте разберем результаты .

Спецификация устройства

Прежде чем я покажу результаты, позвольте мне сначала описать наши характеристики устройства:

  • Шестиядерный процессор AMD® Ryzen 5 2600
  • 16 ГБ оперативной памяти
  • Графический процессор GeForce GTX 1070 TI

Использование RAM

Для проекта мы с моей командой использовали ПК со скромным объемом оперативной памяти около 16 ГБ. Мы думали, этого будет достаточно, но мы ошибались! Видите ли, наряду с обучением нескольких гиперпараметров, чтобы найти лучшие ответы, мы также протестировали наши результаты, используя десятикратную перекрестную проверку, чтобы найти лучшие результаты.

Даже после реализации ручной сборки мусора после каждой эпохи в Keras использование оперативной памяти неуклонно увеличивалось, если мы не остановили все процессы. Мы достигли узкого места в использовании оперативной памяти. Хотя, честно говоря, использование ОЗУ одним процессом не сильно отставало от использования ОЗУ многопроцессорной обработки, хотя многопроцессорность увеличивала использование ОЗУ быстрее, чем однопроцессное.

Изображение показывает, что использование ОЗУ в начале тренировки не слишком сильно отличается друг от друга. Условия для моделей нейронных сетей с прямой связью и моделей LSTM аналогичны.

Примечание: было бы хорошо знать, что результаты для моделей с бинарными позами и с несколькими позами аналогичны из-за схожей архитектуры, а также схожих точек данных, используемых для обеих моделей.

использование процессора

Используя AMD Ryzen 5, мы смогли осуществить этот трюк. С процессором проблем не было. Это может быть связано с тем, что известно, что процессоры AMD лучше справляются с многозадачностью. Я считаю, что ЦП внес большой вклад в наш тренировочный процесс, особенно потому, что у Ryzen 5 было шесть выделенных ядер.

Однопроцессный режим поддерживает относительно низкую загрузку ЦП. Он редко выходит за рамки 40% использования более чем для одного процессора. В противном случае многопроцессорность редко опускалась ниже отметки использования 60–70%, и после остановки каждого процесса каждый ЦП медленно снижал коэффициент использования примерно до 9–15%.

Использование ЦП в модели LSTM отличает больше, чем использование ЦП в двоичной позе. Как я упоминал ранее, задача обучения модели LSTM требует больше вычислительной мощности. Таким образом, он не может иметь более трех процессов одновременно.

Использование однопроцессного ЦП показывает, насколько различаются требования к питанию для двух моделей. Использование ЦП в моделях бинарной позы редко превышает 30% для одного ЦП, не говоря уже о 40% для нескольких ЦП. Однако загрузка ЦП для одного процесса достигла более 40% при минимальном использовании ЦП в 35%.

Однако вызывает удивление то, что многопроцессорное использование ЦП в модели LSTM не превышает использования модели бинарной позы. Модель LSTM имеет 4 ЦП, которые достигают процента 70%, когда модель бинарной позы имеет 6. Однако можно сделать вывод, что одна модель бинарной позы использует меньше ЦП, чем одна модель LSTM, но 6 бинарных моделей позы используют больше мощности ЦП. чем 3 модели LSTM.

Примечание. Опять же, результаты для моделей с бинарной позой и с несколькими позами аналогичны из-за схожей архитектуры, а также схожих точек данных, используемых для обеих моделей.

Общее время, необходимое для каждого процесса

Самая важная метрика здесь - время. Потому что это единственная причина, по которой мы вообще потрудились над этим экспериментом. Ниже у меня есть два расписания, в которых описываются результаты как однопроцессного, так и многопроцессорного обучения.

Для каждой таблицы существует 6 различных комбинаций, разница заключается в скрытых слоях и размерах пакетов. В эксперименте с несколькими процессами выполнялись все комбинации одновременно, а в эксперименте с одним процессом выполнялись все комбинации соответственно.

Результаты между этими двумя таблицами могут привести к одному выводу. Многопроцессорность не повлияла на скорость обучения. Разница между двумя результатами для каждой комбинации не слишком велика. Кроме того, если мы сложим время, необходимое для обучения каждой модели отдельно в одном процессе, нам потребуется примерно 1212 секунд. В то время как в примере с многопроцессорной обработкой нам нужно максимум 372 секунды.

Благодаря многопроцессорности мы сэкономили 840 секунд обучения. Мы ускорили обучение в 3,25 раза.

Далее в нашем списке. Мы пытаемся реализовать эту технику в более сложной модели. LSTM. Потому что разница в вычислительной мощности, необходимой между двумя типами моделей, довольно велика. В итоге я запустил модель LSTM одновременно в трех процессах.

Для каждой таблицы есть три различных комбинации, разница заключается в скрытых слоях. Чтобы было ясно, каждая модель LSTM имеет четыре слоя, и каждый слой имеет разное количество скрытых слоев. В эксперименте с несколькими процессами выполнялись все комбинации одновременно, а в эксперименте с одним процессом выполнялись все комбинации соответственно.

Результаты между этими двумя таблицами можно рассматривать как аналогичные. Для каждой комбинации он не сильно отличается. Необычный результат состоит в том, что результаты одного процесса становятся быстрее с каждым увеличением скрытого уровня, тогда как результаты многопроцессорной обработки противоположны.

В конце концов, для обучения многопроцессорности требуется не более 6755 секунд. В то время как время однопроцессного обучения составляет около 15330 секунд.

В этом случае многопроцессорность сэкономила 8575 секунд времени обучения. Таким образом, время обучения сокращается в 2,26 раза.

Теперь эти результаты кажутся очень многообещающими. Имейте в виду, что используемые здесь модели все еще относительно просты по сравнению с тем, что может потребоваться в корпоративных продуктах. Используемые данные также исчислялись тысячами, в то время как у корпоративных ИИ обычно миллионы.

Заключение

В конце концов, многопроцессорные решения ускорили время обучения в 2,26 раза для модели LSTM и в 3,25 раза для нейронной сети с прямой связью. Возможности для использования в исследованиях безграничны. Компьютеры становятся мощнее с каждым годом. Используя эту технику, гиперпараметрическое тестирование будет проще простого.

Многопроцессорность сэкономила моей команде много времени. Я не могу себе представить, сколько времени нам пришлось бы ждать, если бы мы не реализовали его. Хотя я должен сказать, что многопроцессорность - не серебряная пуля. Он не ускоряет работу каждой модели в любых обстоятельствах. Нам повезло, что в нашем случае есть идеально подходящие условия.

Особая благодарность Кевину Джанада и фердинанду Яфне за предоставленное мне разрешение на использование данных из нашего проекта.

Редактировать примечание: статья изменена с многопоточности на многопроцессорность. Я перепутал эти две вещи. Извините за беспокойство. Спасибо, Мишо Крастев, что указал на это.