Поиск по сайту Поиск

Стэнфордский курс: лекция 8. ПО для глубокого обучения

В предыдущих главах мы познакомились с основами обучения нейросетей и выяснили, чему при этом стоит уделять больше внимания. Сегодня вы отдохнёте от математики и узнаете о популярных фреймворках и библиотеках машинного обучения, а также о том, зачем для работы с нейросетями нужны GPU.

Предыдущие лекции:

Лекция 1. Введение
Лекция 2. Классификация изображений
Лекция 3. Функция потерь и оптимизация
Лекция 4. Введение в нейронные сети
Лекция 5. Свёрточные нейронные сети
Лекция 6. Обучение нейросетей, часть 1
Лекция 7. Обучение нейросетей, часть 2

GPU vs CPU

Если вы когда-нибудь пробовали собирать компьютер, то наверняка знаете, что внутри него находится множество компонентов. «Сердцем» любой вычислительной машины является центральный процессор (CPU) — небольшой чип, обычно спрятанный под охлаждающим вентилятором в центре материнской платы. Графический процессор (GPU) отвечает за обработку изображений. Иногда графическое ядро может быть интегрировано в CPU, поэтому не совсем корректно ставить знак равенства между GPU и видеокартой.

Если вы используете компьютер для запуска игр или тяжёлых программ, то, скорее всего, в нём есть дискретная видеокарта с GPU. Она занимает куда больше места и обычно требует отдельного охлаждения. Так как же все эти вещи используются в машинном обучении?

Компьютер изнутри

Одна из главных тем споров в IT-сфере — предпочтение оборудования или ПО того или иного производителя. Наверняка вы сталкивались с дебатами «текстовый редактор Vim против Emacs», «процессоры Intel против AMD», «видеокарты NVIDIA против Radeon». Изначально GPU создавались для рендеринга компьютерной графики, поэтому те, кто часто играет в компьютерные игры, наверняка могут высказать своё мнение о том или ином производителе графических карт. Мы в основном будем фокусироваться на GPU от NVIDIA ввиду их большей распространённости в области машинного обучения.

В чём же разница между CPU и GPU? И то, и другое — вычислительные единицы, выполняющие программы и произвольные инструкции. Но, тем не менее, они существенно отличаются друг от друга.

CPU состоят из небольшого числа ядер, в настоящее время обычно не превышающего десяти. Технология гиперпоточности (hyperthreading) позволяет каждому ядру работать в несколько потоков. Упрощённо говоря, CPU с 10-ю ядрами и 20-ю потоками может выполнять 20 задач одновременно. Это не так много, но на самом деле потоки CPU очень мощные, и одна их инструкция способна включать множество процессов. 

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

Новое поколение GPU выходит примерно раз в полтора года. Поэтому опытные исследователи активно переходят в облако и постоянно имеют доступ к новейшим графическим ускорителям. За их обновление, администрирование и поддержку отвечает провайдер, а клиенты могут сэкономить приличные суммы. Например, использование сервера с топовой на сегодняшний день GPU NVIDIA Tesla V100 в REG.RU выйдет дешевле, чем покупка аналогичной видеокарты в магазине, особенно если она нужна вам на ограниченный срок.

Ещё одно существенное отличие между CPU и GPU — использование памяти. CPU в основном расходует оперативную память системы (ОЗУ или RAM), размер которой достигает нескольких десятков гигабайт. GPU имеет собственную встроенную видеопамять (VRAM). В графическом ядре запись и чтение из памяти осуществляются последовательно — например, при обработке пикселей они будут считываться друг за другом, в то время как в CPU доступ к памяти организован более сложным образом.

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

Как мы помним, в свёрточных архитектурах умножение матриц происходит постоянно, поэтому GPU — незаменимый инструмент для обучения нейросетей.

Для того, чтобы запускать код прямо на GPU, NVIDIA разработала ускорители CUDA. Написание CUDA-кода — достаточно сложный процесс, требующий глубокого погружения в архитектуру графических ускорителей. Поэтому для удобства можно использовать более высокоуровневые библиотеки: cuBLAS, cuFFT, cuDNN и другие. Также существует фреймворк openCL, оптимизированный для любых GPU (даже от AMD). Но он, как правило, показывает более медленные результаты.

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

Фреймворки для глубокого обучения

Число различных программ и библиотек для глубокого обучения растёт с каждым годом. К самым известным относятся TensorFlow, Caffe, PyTorch, также развиваются Paddle от Baidu, CNTK от Microsoft, MXNet от Amazon и многие другие. И хотя каждая библиотека содержит свои отличительные функции, некоторые особенности присутствуют во всех фреймворках:

— в них легко строить большие вычислительные графы;

— легко вычислять градиенты для вычислительных графов;

— они эффективно используют GPU.

Примеры тарифов на облачные GPU в REG.RU

По этим причинам применять готовые библиотеки чаще всего гораздо продуктивнее и удобнее, чем писать собственный код. Попробуем заглянуть внутрь приложений и подробнее рассмотрим, для каких задач подходят фреймворки TensorFlow, PyTorch и Caffe.

TensorFlow

В качестве последующих примеров будем использовать двухслойную полносвязную нейросеть с функцией активации ReLU. Мы попробуем обучить её на случайных данных и вычислить потери L2. На самом деле наша нейросеть не будет делать ничего полезного, но её код поможет вам узнать о некоторых важных функциях TensorFlow.

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

Объекты tf.placeholder используются для передачи входных данных в вычислительный граф, а метод tf.maximum вводит нелинейность ReLU.

Сначала мы выполняем матричное умножение переменных x и w1 (данных и параметров), а затем вычисляем потери L2 между прогнозируемыми (y_pred) и истинными (y) значениями с помощью базовых тензорных операций. Как вы могли заметить, у нас пока нет никаких данных и на самом деле этот код ничего не делает. 

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

При запуске графа мы генерируем данные с помощью np.random, чтобы передать конкретные значения в ранее созданные placeholders. Вызов метода tf.Session().run начинает выполнение вычислений. В качестве первого аргумента мы указываем параметры, которые хотим посчитать: потери loss и градиенты grad_w1, grad_w2. Второй аргумент feed_dict содержит в себе передаваемые в граф данные. После выполнения этой строки TensorFlow запустит граф и вычислит все необходимые значения.

Код пока не обучает нейросеть: для этого достаточно добавить всего несколько строк с реализацией градиентного спуска и обновлением весов:

Построив график потерь, мы увидим, что нейросеть действительно обучается и потери уменьшаются:

Но в этом примере есть небольшая загвоздка. Дело в том, что мы каждый раз передаём в граф массивы NumPy, вычисляем градиенты и возвращаем их значения обратно. Если запускать код на CPU, то в этом нет особой проблемы, но при использовании GPU нам придётся каждый раз копировать данные из памяти CPU в память GPU. Поэтому если нейросеть будет очень большой, это существенно замедлит процесс её обучения.

К счастью, в TensorFlow есть готовое решение проблемы. Вместо того, чтобы использовать веса в виде tf.placeholder, мы объявим их как tf.Variable. Variable — это значение, которое находится внутри вычислительного графа и сохраняется при каждом его запуске.

Теперь нам не нужно каждый раз обновлять веса и градиенты, поскольку они уже находятся в графе. Мы отправляем на вход только данные и метки, а на выходе получаем потери. Чтобы обновление выполнялось внутри графа, добавим оптимизатор optimizer для вычисления градиентов и будем минимизировать их с помощью переменной updates, которая использует метод minimize и передаётся в tf.Session:

Дополнив код выше и построив график, вы увидите, что потери уменьшаются — значит, обучение нейросети снова прошло успешно, и на этот раз нам не пришлось копировать данные из одной памяти в другую.

Несколько слов о Keras

Keras — высокоуровневое API, которое обычно используется «поверх» Tensorflow и позволяет создавать и обучать нейросети с помощью простых и понятных команд. Он отлично подойдёт для построения базовых моделей и знакомства с Machine Learning. Если вам не терпится попробовать написать код для своей первой по-настоящему рабочей нейросети, рекомендуем ознакомиться с нашей статьёй Как начать работу с Keras, Deep Learning и Python.

PyTorch

В PyThorch существует понятие трёх уровней абстракции. Для каждой из них можно найти аналогичные объекты в TensorFlow:

Мы не будем подробно останавливаться на деталях и сразу рассмотрим код двухслойной нейросети с оптимизатором Adam, реализацию которой мы использовали выше. В PyTorch он будет выглядеть примерно следующим образом:

Модуль nn, как вы могли догадаться, содержит в себе готовые функции для работы с нейросетями. Помимо него в библиотеке есть множество полезных инструментов: например, метод DataLoader позволяет удобно импортировать наборы данных, разбивать их на мини-пакеты, перемешивать и использовать собственные классы датасетов. А с дополнительной утилитой TorchVision можно быстро загружать предварительно обученные популярные модели: AlexNet, VGG16, ResNet и другие.

Совершить подробную и занимательную экскурсию по PyTorch можно, прочитав эту статью.

Caffe

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

Весь алгоритм работы с Caffe можно охарактеризовать следующими шагами:

  1. Сконвертируйте данные в формат HDF5 или LMDB с помощью готовых скриптов;
  2. Задайте настройки для нейросети (отредактируйте prototxt);
  3. Настройте solver (оптимизацию) (отредактируйте prototxt);
  4. Запустите обучение (готовый скрипт).

Caffe доступен и в Python. Лучше всего использовать новую версию Caffe2, которая интегрирована в PyTorch: она хорошо подходит для работы с массивами NumPy, извлечения признаков из данных, настройки и обучения моделей, а также обеспечивает поддержку мобильных платформ iOS, Android и других.

Что же использовать?

На наш взгляд, TensorFlow — наилучший вариант для большинства проектов. Он не идеален, но имеет огромное сообщество и очень широко применяется в самых разных сферах. К тому же, его можно использовать с более высокоуровневой оболочкой (Keras, Sonnet и другие).

PyTorch лучше всего подходит для исследований, а Caffe2 — для развёртывания готовых моделей и их адаптации на мобильных устройствах.

⌘⌘⌘

Если вы просмотрели все предыдущие лекции, спешим поздравить — мы вместе прошли уже половину курса. Расскажите в комментариях, интересны ли вам материалы, какие темы показались наиболее полезными и важными. Задавайте вопросы, если столкнулись с чем-то непонятным — мы обязательно ответим.

Следующие лекции (список будет дополняться по мере появления материалов):

Лекция 9. Архитектуры CNN
Лекция 10. Рекуррентные нейронные сети

С оригинальной лекцией можно ознакомиться на YouTube.

Как установить Python на Windows 10: пошаговая инструкция

Python давно стал одним из самых популярных инструментов для программирования. Если вы решили освоить этот язык или планируете использовать его...
Read More

КПП для ИП: есть ли код у индивидуального предпринимателя

Многие индивидуальные предприниматели, заполняя документы для налоговой, сталкивались со строкой «КПП». Разбираемся, как ее заполнять и что указывать, если КПП...
Read More

Воронка продаж: как ее построить и проанализировать, чтобы она работала

Воронка продаж — это путь клиента, который он проходит от первого соприкосновения с продуктом до его приобретения. На этом пути...
Read More

Бриф в маркетинге: как составить, зачем нужен, образец использования

Создание брифа помогает выработать более точную и качественную стратегию маркетинговой кампании. (далее…)
Read More

Сделка: что это такое и как ее правильно оформить

Со сделками мы сталкиваемся буквально каждый день. Любая покупка в магазине  — уже сделка. Устные договоренности, даже если они не...
Read More

Как внедрить CRM-систему для подбора персонала в облаке и ускорить наем: кейс DIY Service

В кейсе рассказываем, как маркетинговое агентство DIY Service автоматизировало подбор и передачу кандидатов на вакансии в операционный отдел и оптимизировало...
Read More

Нулевой РСВ: нужно ли сдавать отчетность при отсутствии штата

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

Гарант сделки: посредники, сервисы и правильное составление договора

Иногда для обеспечения безопасности сделок нужны дополнительные гарантии. Они обеспечивают защиту интересов всех участников. Кто и в каких случаях может...
Read More

Некоммерческие организации: какие бывают и чем полезны

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

Кто такие ЛПР в продажах, как их найти и зачем это делать

Рассказываем, кто такие лица, принимающие решения, и почему каждый продажник мечтает до них добраться. (далее…)
Read More