
Код программных продуктов для машинного обучения часто бывает сложным и довольно запутанным. Обнаружение и ликвидация багов в нем — ресурсоемкая задача. Даже простейшие требуют серьезного подхода к сетевой архитектуре, инициализации весов, оптимизации сети. Небольшая ошибка может привести к появлению неприятных проблем.
Эта статья посвящена алгоритму отладки ваших нейронных сетей.
Skillbox рекомендует: Практический курс .
Напоминаем: для всех читателей «Хабра» — скидка 10 000 рублей при записи на любой курс Skillbox по промокоду «Хабр».
Алгоритм состоит из пяти этапов:
- простой старт;
- подтверждение потерь;
- проверка промежуточных результатов и соединений;
- диагностика параметров;
- контролирование работы.
Если вам что-то кажется более интересным, чем остальное, можете сразу переходить к этим разделам.
Простой старт
Нейронную сеть со сложной архитектурой, регуляризацией и планировщиком скорости обучения дебажить сложнее, чем обычную. Мы тут немного хитрим, поскольку сам пункт к отладке имеет опосредованное отношение, но это все же важная рекомендация.
Простой старт заключается в создании упрощенной модели и обучении ее на одном наборе (точке) данных.
Сначала создаем упрощенную модель
Для быстрого старта создаем небольшую сеть с единственным скрытым слоем и проверяем, чтобы все работало корректно. Затем постепенно усложняем модель, проверяя каждый новый аспект ее структуры (дополнительного слоя, параметра и т.п.), и двигаемся дальше.
Обучаем модель на единственном наборе (точке) данных
В качестве быстрой проверки работоспособности вашего проекта можно использовать для обучения одну или две точки данных, чтобы подтвердить, корректно ли работает система. Нейронная сеть должна показать 100% точности обучения и проверки. Если это не так, то либо модель слишком мала, либо у вас уже есть баг.
Даже если все хорошо, подготовьте модель к проходу одной или нескольких эпох прежде, чем идти дальше.
Оценка потерь
Оценка потерь — основной способ уточнить производительность модели. Вам необходимо убедиться, что потеря соответствует задаче, а функции потерь оцениваются по корректной шкале. Если вы используете больше одного типа потерь, то убедитесь в том, что все они одного порядка и правильно масштабированы.
Важно быть внимательным к начальным потерям. Проверьте, насколько близок реальный результат к ожидаемому, если модель стартовала со случайного предположения. В : «Убедитесь, что вы получаете результат, ожидаемый при начале работы с небольшим числом параметров. Лучше сразу проверить потерю данных (с установкой степени регуляризации на ноль). К примеру, для CIFAR-10 с классификатором Softmax мы ожидаем, что начальные потери будут 2.302, потому что ожидаемая диффузная вероятность составляет 0,1 для каждого класса (так как существует 10 классов), а потеря Softmax является отрицательной логарифмической вероятностью корректного класса как –ln (0.1) = 2.302».
Для бинарного примера просто делается аналогичный расчет для каждого из классов. Вот, к примеру, данные: 20% 0’s и 80% 1’s. Ожидаемая начальная потеря составит до –0,2ln (0,5) –0,8ln (0,5) = 0,693147. Если результат больше 1, это может указывать на то, что веса нейросети не сбалансированы должным образом или данные не нормализованы.
Проверяем промежуточные результаты и соединения
Для отладки нейросети необходимо понимать динамику процессов внутри сети и роль отдельных промежуточных слоев, поскольку они связаны. Вот типичные ошибки, с которыми вы можете столкнуться:
- неправильные выражения для обновлений градиента;
- не применяются обновления веса;
- исчезающие или взрывающиеся градиенты (exploding gradients).
Если значения градиента нулевые, это означает, что скорость обучения в оптимизаторе слишком мала, либо то, что вы столкнулись с некорректным выражением для обновления градиента.
Кроме того, необходимо следить за значениями функций активаций, весов и обновлений каждого из слоев. К примеру, величина обновлений параметров (весов и смещений) .
Существует явление, которое получило название “Dying ReLU” или , когда нейроны ReLU будут выводить ноль после изучения большого отрицательного значения (bias) смещения для его весов. Эти нейроны больше никогда не активируются ни в одном месте данных.
Вы можете использовать проверку градиента для выявления этих ошибок путем аппроксимации градиента с использованием численного подхода. Если он близок к рассчитанным градиентам, то обратное распространение было реализовано правильно. Чтобы создать проверку градиента, ознакомьтесь с этими замечательными ресурсами из CS231 и , а также с Эндрю Ына (Andrew Nga) по этой теме.
указывает три главных метода визуализации нейросети:
- Предварительные — простые методы, которые показывают нам общую структуру обученной модели. Они включают вывод форм или фильтров отдельных слоев нейронной сети и параметров в каждом слое.
- Основанные на активации. В них мы расшифровываем активации отдельных нейронов или группы нейронов, чтобы понять их функции.
- Основанные на градиентах. Эти методы имеют тенденцию манипулировать градиентами, которые формируются из прохода вперед и назад при обучении модели (включая карты значимости и карты активации класса).
Есть несколько полезных инструментов для визуализации активаций и соединений отдельных слоев, например, и .

Диагностика параметров
У нейросетей масса параметров, которые взаимодействуют друг с другом, что усложняет оптимизацию. Собственно, этот раздел — предмет активных исследований специалистов, поэтому предложения ниже должны рассматриваться лишь как советы, начальные точки, от которых можно отталкиваться.
Размер пакета (batch size) — если необходимо, чтобы размер пакета был достаточно большим для получения точных оценок градиента ошибки, но достаточно малым, чтобы стохастический градиентный спуск (SGD) мог упорядочить вашу сеть. Небольшие размеры пакетов приведут к быстрому схождению за счет шума в процессе обучения и в дальнейшем — к трудностям оптимизации. Подробнее это описано .
Скорость обучения — слишком низкая приведет к медленной конвергенции или риску застрять в локальных минимумах. В то же время высокая скорость обучения вызовет расхождение оптимизации, поскольку вы рискуете «прыгнуть» через глубокую, но при этом узкую часть функции потери. Попробуйте использовать планирование скорости, чтобы снизить ее в процессе обучения нейросети. В курсе CS231n .
Gradient clipping — обрезка градиентов параметров во время обратного распространения по максимальному значению или предельной норме. Полезно для решения проблем с любыми взрывающимися градиентами, с которыми вы можете столкнуться в третьем пункте.
Пакетная нормализация — используется для нормализации входных данных каждого слоя, что позволяет решить проблему внутреннего ковариатного сдвига. Если вы используете Dropout и Batch Norma вместе, .
Стохастический градиентный спуск (SGD) — существует несколько разновидностей SGD, которые используют импульс, адаптивные скорости обучения и метод Нестерова. При этом ни у одной из них нет явного преимущества как по эффективности обучения, так и по обобщению ().
Регуляризация — имеет решающее значение для построения обобщаемой модели, поскольку добавляет штраф за сложность модели или экстремальные значения параметров. Это способ снизить дисперсию модели без существенного увеличения ее смещения. Более .
Чтобы самому все оценить, необходимо отключить регуляризацию и проверить градиент потери данных самостоятельно.
Выпадение — еще один метод упорядочения вашей сети для предотвращения перегрузки. Во время обучения выпадение осуществляется только поддержанием активности нейрона с некоторой вероятностью p (гиперпараметр) или установкой его на ноль в обратном случае. В результате сеть должна использовать другое подмножество параметров для каждой обучающей партии, что уменьшает изменения определенных параметров, которые становятся доминирующими.
Важно: если вы используете как выпадение, так и пакетную нормализацию, будьте осторожны с порядком этих операций или даже с их совместным использованием. Все это еще активно обсуждается и дополняется. Вот две важных дискуссии по этой теме и .
Контроль работы
Речь идет о документировании рабочих процессов и экспериментов. Если ничего не документировать, можно забыть, например, какая используется скорость обучения или вес классов. Благодаря контролю можно без проблем просматривать и воспроизводить предыдущие эксперименты. Это позволяет снизить количество дублирующихся экспериментов.
Правда, ручное документирование может стать сложной задачей в случае большого объема работ. Здесь приходят на помощь такие инструменты, как Comet.ml, помогающие автоматически логировать наборы данных, изменения кода, историю экспериментов и производственные модели, включая ключевые сведения о вашей модели (гиперпараметры, показатели производительности модели и сведения об окружении).
Нейронная сеть может быть весьма чувствительной к небольшим изменениям, а это приведет к падению производительности модели. Отслеживание и документирование работы — первый шаг, который стоит предпринять для стандартизации среды и моделирования.

Надеюсь, что этот пост сможет стать отправной точкой, с которой вы начнете отладку вашей нейросети.
Skillbox рекомендует:
- Двухлетний практический курс .
- Онлайн-курс .
- Практический годовой курс .
Источник: habr.com
