Как запустить эффективный поиск гиперпараметров в моделях глубокого обучения с конкретными наглядными примерами из Weights & Biases

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

Что такое гиперпараметрический поиск?

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

Методы: ручной, сеточный, случайный

Основное обещание алгоритмической или автоматической настройки гиперпараметров - это умнее выбирать следующий эксперимент для запуска. Если нам все равно нужно попробовать несколько разных значений для нескольких разных гиперпараметров, как мы можем оптимально выбрать следующую комбинацию - и проводить меньше экспериментов, тратить меньше вычислительных ресурсов и получать результаты еще быстрее? Стандартными методами для этого являются сетка, случайный, байесовский или байесовский (хотя вы услышите длинный хвост других терминов и стратегий в это пространство, особенно для оптимизации на основе моделей). Поиск по сетке пробует все возможные комбинации - представьте себе это как вложенный цикл for, где общее количество экспериментов будет порядка количества гиперпараметров, умноженного на количество возможных значений для каждого гиперпараметра. Это полезно, если у вас мало места для поиска и вы хотите гарантированно найти лучший вариант. Случайный поиск обычно выполняется быстрее и особенно рекомендуется, если у вас больше места для поиска, так как он будет выбирать более широкий диапазон комбинаций и дать вам представление о возможностях быстрее, чем поиск по сетке. Однако не всегда удается найти лучшую комбинацию.

Байесовский

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

Длинный хвост других методов

Другие методы включают оптимизацию на основе градиента для явного вычисления градиента относительно определенных гиперпараметров, раннюю остановку, чтобы не тратить время на бесперспективные прогоны, и эволюционную оптимизацию, применяемую к последовательным наборам выбранных гиперпараметров. Также существует обучение на основе популяций, при котором несколько независимых процессов одновременно изучают значения гиперпараметров и веса сети. Есть много вариантов - как алгоритмические детали, так и услуги по оптимизации черного ящика, которые я могу здесь описать. Как только вы изучите эти детали и компромиссы, я бы спросил себя, нахожусь ли я на той стадии, когда я обдумал конкретную модель, которую я настраиваю, и конкретную проблему, которую я решаю, и пришел к выводу, что нет ничего еще умный я могу сделать - я просто хочу бросить графические процессоры на эту задачу? Если да, я бы предложил использовать некоторую оптимизацию, например байесовскую, потому что это, скорее всего, будет работать быстрее, и подумайте о чем-нибудь другом. Но по моему опыту, более интересная, сложная и полезная работа по настройке гиперпараметров происходит до этого этапа, и у нас пока нет хороших алгоритмов для этого - и именно поэтому у многих из нас все еще есть вакансии в машиностроении. Итак, давайте погрузимся в эту часть!

Спектр гиперпараметров в код

Прежде чем начинать пробовать разные гиперпараметры, вы решаете, что составляет гиперпараметр. Существует важное различие между обычными параметрами сети, такими как веса модели и смещения, которые сами изучаются или итеративно улучшаются в процессе обучения, и гиперпараметры, которые настраиваются вне процесса обучения. и, как правило, фиксируется на его продолжительность (хотя некоторые из них могут быть адаптивными, например, скорость обучения). Для данной сети они могут включать количество эпох обучения, тип оптимизатора обучения, размер пакета, уменьшение веса и многое другое. Сама сетевая архитектура может быть гиперпараметром: начинаю ли я с хорошо известной базовой сети, такой как Inception или ResNet? Сколько слоев я заморозил по сравнению с точной настройкой? Если я проектирую сеть с нуля, то количество, размер, тип и схемы соединения слоев, а также размеры скользящего окна в свертках могут быть гиперпараметрами. Чтобы решить, сохранять ли данный гиперпараметр фиксированным или переменным, вы можете подумать о том, насколько хорошо вы можете заранее предсказать его влияние и как он повлияет на общее время выполнения и сложность вашего поиска.

Эпохи

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

Набор данных

Размер ваших обучающих данных и количество примеров, которые вы используете для проверки своего обучения, - это еще один хорошо изученный гиперпараметр. Предполагая, что ваши данные и разделение являются репрезентативными и беспристрастными выборками, чем больше набор данных, тем выше производительность - и, конечно же, тем больше времени требуется для проверки каждой из ваших гипотез. Я следую общепринятой точке зрения разделения 80/10/10, когда 10% данных хранятся до тех пор, пока не будут завершены все обучение и настройка, чтобы лучше понять возможности обобщения модели. В ручном режиме я тренируюсь на 80% и проверяю на 10% после каждой эпохи. На практике эксперимент с обучением на 80% и проверкой на 10% каждый раз может быть слишком медленным для поиска гиперпараметров. Я снижаю эти требования, беря около 20–50% каждого сплита в качестве стандарта для каждого эксперимента. Я стараюсь сократить время одного эксперимента до нескольких минут.

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

Итерационные развертки

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

Управляемое исследование

Общая стратегия, особенно когда не хватает времени, - начать с простой архитектуры или лучшего из существующих решений, доступных для данной задачи. Выполните несколько ручных тестов, чтобы выбрать подходящее количество эпох и размер обучения / проверки. Попробуйте исследовать небольшой набор гиперпараметров (например, 3–10). Чем больше гиперпараметров вы начнете, тем дольше будет этот этап. Для каждого гиперпараметра выберите меньшее количество значений в более широком диапазоне - даже если некоторые прогоны завершатся неудачно, вы лучше почувствуете пространство поиска. Я бы не стал вдаваться в очень точные или необычные значения на данном этапе - общие значения по умолчанию хороши, например размеры пакетов в степени двойки, и опять же, не слишком много на гиперпараметр - я всегда могу сузить фокус при последующих анализах.

Первые кандидаты на настройку

Я считаю, что изучение динамики обучения - насколько медленно или быстро обучается сеть - является надежным первым шагом: здесь можно легко добиться успеха, попав в правильный диапазон. Например, с учетом скорости обучения и размера пакета я могу выбрать всего несколько значений, чтобы получить большую часть информации о том, насколько чувствительна сеть к этому гиперпараметру. Получение правильного порядка величины для скорости обучения: 0,01 против 0,001 против 0,0001, скажем, обычно гораздо эффективнее, чем получение идеального значения 0,0001 против 0,00015. Оптимизаторы будут сильно коррелировать со скоростью обучения и размером пакета, но они также могут иметь огромное влияние на конвергенцию и их удобно изучать (например, Адам отлично подходит для многих приложений, но я видел проекты, в которых SGD значительно превосходит Адама).

Следующие кандидаты на настройку

После того, как я установил несколько диапазонов для более простых кандидатов в динамике обучения, я выбрал несколько более сложных деталей, таких как размер слоя или количество фильтров. Общая сетевая архитектура хороша для изучения здесь, но я бы не стал вносить слишком много изменений за один раз или пытаться слишком много подробных гипотез за один цикл - опять же, потому что это приводит к гораздо большему количеству случаев для проверки. В качестве примера я бы построил две или более архитектуры, которые отражают общую разницу между моими идеями - скажем, обычную RNN и перенаправленную RNN, или CNN с максимальным и средним пулом, и использовать их в качестве категориальных переменных. Другой способ - параметризовать количество сверточных блоков. Но если один гиперпараметр - это количество сверточных блоков, другой - количество фильтров в каждом сверточном слое, третий - максимальное или среднее объединение, я сталкиваюсь с тем самым комбинаторным взрывом, которого я пытаюсь избежать, ограничивая эти развертки жесткими, управляемыми итерациями. . В этой заметке, отсев может быть хорошим для проверки, но обычно после того, как я уже хорошо учусь - когда я увеличиваю его слишком рано в процессе исследования, значительная часть моих пробежек вообще не учится многому. Здесь можно было бы добавить другие детали, такие как снижение веса, график скорости обучения, этапы обучения, количество слоев, которые нужно заморозить, и так далее. Возможности безграничны, и мой главный совет: не пытайтесь захватить слишком много слишком быстро - сначала придерживайтесь более простой развертки, чем вы могли бы захотеть, и посмотрите, что вы узнаете.

Няня и делается

Как узнать, насколько хорошо работает ваша развертка, и когда ее остановить? Я часто одержимо обновляю вывод своего терминала, чтобы увидеть медленно тикающую статистику. С таким инструментом, как Weights & Biases, эта часть намного приятнее, потому что вместо этого я могу наблюдать в реальном времени график моих потерь и точности. Тем не менее, это непродуктивное использование человеческих возможностей настройки гиперпараметров. Для любой модели, на которой я выполняю анализ гиперпараметров, я уже убедился, что потери при обучении и проверке в целом снижаются, а точность обучения и проверки (или любых других показателей производительности) в целом увеличивается. После того, как вы отладили код и убедились, что анализ работает правильно и где-то регистрируются результаты, я настоятельно рекомендую не обновлять его, если вы можете устоять перед соблазном улучшения показателей. В отличие от ручного режима исследования, эксперимент B больше не зависит от того, как гипотеза работает в эксперименте A. Вместо этого мы позволяем автоматической настройке гиперпараметров работать на нас. Час или несколько часов обычно достаточно времени для развертки, если предположить, что один запуск может быть ограничен несколькими минутами. С помощью Weights & Biases также легко масштабировать развертку. Выполните ту же команду запуска на другом компьютере, и логика, управляющая следующим выбором гиперпараметров, распараллеливается на обеих машинах или агентах. Это позволяет вам выполнять сканирование по как можно большему количеству графических процессоров, без когнитивных накладных расходов на отслеживание того, какой эксперимент на какой машине проводится.

Установка ограничений

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

Понимание ваших результатов

Теперь для анализа. Этот этап имеет решающее значение - изучите результаты и, в идеале, в письменной форме резюмируйте любые закономерности и особенно отношения, которые вы наблюдаете. Например, приводит ли снижение скорости обучения к повышению точности проверки? Помогает ли увеличение отсева, но только при наличии как минимум трех слоев? Подумайте, какие эксперименты подтвердят или опровергнут ваши наблюдения и что вы хотите попробовать дальше. Чем конкретнее я могу делать эти записи, тем легче мне действовать намеренно, а моему будущему - не говоря уже о товарищах по команде или более широкой аудитории - понимать, что, черт возьми, мое прошлое «я» пыталось сделать и почему.

График с параллельными координатами

Очень полезно визуализировать, как все гиперпараметры взаимодействуют с целевой метрикой. График параллельных координат весов и смещений - особенно удобный способ сделать это. В крайнем правом столбце отображается метрика результата (например, точность проверки, потеря проверки) каждого прогона в развертке. Волнистая линия соединяет этот результат со всеми соответствующими значениями гиперпараметров для этого конкретного эксперимента: это точки, в которых волнистая линия пересекает каждую из других вертикальных числовых линий (например, скорость обучения, размер партии, выпадение). Таким образом, каждая волнистая линия представляет один эксперимент и окрашена в соответствии с результатом (например, более фиолетовым, если точность ниже, и более желтым, если она выше). Это позволяет сразу увидеть корреляции. В приведенном ниже примере промежуточные значения импульса лучше, а установка высоких значений скорости обучения и импульса приводит к снижению точности проверки. Вы можете узнать больше и изучить этот график в интерактивном режиме здесь, а также в этом более подробном отчете о количественной оценке значимости при поиске по гиперпараметрам.

Панель важности параметра

Панель важности параметров Weights & Biases делает эти визуальные корреляции более конкретными. Он запускает случайный лес по вашему прогрессу сканирования (то есть, какие значения гиперпараметров привели к каким результатам), чтобы вычислить важность и корреляцию каждого гиперпараметра с метрикой результата. В качестве бонуса, эта метрика не обязательно должна быть той, которую вы пытались оптимизировать в ходе самого анализа. Ниже я показываю график параллельных координат и две панели важности параметров для UNet, обученного в Fastai для семантической сегментации в сценах вождения (идентифицируйте каждый пиксель как принадлежащий автомобилю, человеку, велосипеду, зданию, тротуару и т. Д. Для 20 классов. общий). Моя метрика производительности - долговая расписка: пересечение по объединению, усредненное по всем моим классам, которое будет наивысшим, когда области, предсказанные моей моделью, идентично перекрываются с аннотациями наземной истины, и ниже, когда мои предсказанные регионы не соответствуют истинной действительности. Первый график ясно показывает, что ResNets являются лучшими кодировщиками, чем Alexnet для увеличения долговых обязательств, в то время как эффект скорости обучения неубедителен.

Когда я просматриваю панель важности параметров по общим долговым обязательствам по классам (левая диаграмма ниже), я вижу, что скорость обучения имеет сильную отрицательную корреляцию: я должен установить более низкую скорость обучения, чтобы увеличить среднюю долговую расписку. Однако, если я запрашиваю важность параметра в отношении человеческих долговых расписок - долговых расписок только для класса людей - я вижу, что использование Alexnet в качестве кодировщика гораздо важнее, и это лучший выбор, если мой цель - обнаружить людей. Вы можете прочитать этот отчет для более подробной информации: в основном Alexnet имеет тенденцию предсказывать более крупные ложноположительные области, улучшая долговые обязательства для такого редкого класса, как люди, но снижая производительность в целом.

Разверните, визуализируйте, повторите

После того, как вы проанализировали свою развертку, задокументировали свои выводы и составили план следующих шагов, вы можете запустить еще несколько ручных тестов или попробовать еще одну проверку. Я бы порекомендовал расширить окно в рекомендуемом направлении (например, если более низкая скорость обучения увеличивает точность проверки, попробуйте еще более низкие значения) или увеличьте точность (выборка более близка к лучшему значению) для более эффективных гиперпараметров. Если какие-либо настройки гиперпараметров явно хороши, обратите внимание на это и рассмотрите возможность преобразования их в константы: сохранение этих уже хорошо настроенных значений фиксированными, возможно, с комментарием в коде, чтобы объяснить, почему. С другой стороны, если какие-либо настройки нарушают ваш скрипт из-за выбросов (например, слишком большой размер пакета вызывает ошибку OOM), сузьте диапазон для будущих запусков. Вы также можете добавить несколько новых гиперпараметров для изучения, и вы готовы повторить этот процесс! В Весах и смещениях вы даже можете начать развертку из существующих прогонов: отметить некоторые из ваших лучших прогонов из только что завершенной развертки, чтобы использовать их в качестве вдохновения или чернового наброска вашей следующей конфигурации развертки. Они будут учтены при создании развертки, а их конфигурация не будет повторяться при выполнении следующей развертки.

Я надеюсь, что этот обзор поможет вам настроить модели глубокого обучения немного быстрее, независимо от того, какой фреймворк или инструменты вы используете. На высоком уровне я рекомендую ограниченное исследование (больший диапазон значений для меньшего количества гиперпараметров) и как можно больше ужесточить ваш цикл обратной связи (более короткие эксперименты, меньшие развертки, выполнение большего количества итераций). Вот дополнительные ресурсы, чтобы начать работу с анализом весов и смещений. Я хотел бы услышать от вас, как мы можем сделать работу W&B Sweeps еще лучше для ваших сценариев использования.