Эффективность экспериментов базируется на организационной и технической стороне работы. Начинающие инженеры, которые занимаются нейросетями и обучают модели, совершают достаточно типовые ошибки. Например, увлекаясь перебором и тюнингом моделей машинного обучения, упускают важнейший этап подготовки данных, не задумываются о том, как сделать эксперименты воспроизводимыми, а этап программирования быстрым. Давайте поговорим об этом - как эффективно проводить эксперименты с нейросетями.
Пара слов про контекст. Проекты бывают исследовательские и прикладные. В аналитических проектах машинное обучение играет вспомогательную роль, тогда как в продуктовых оно ключевое, и без них этого продукта не было бы. Проекты отличаются имеющимися временными и человеческими ресурсами, свободой в выборе подхода и характеристиками данных. Но, во всем этом многообразии, общие подходы примерно одинаковые - отличаются только приоритеты.
В нейросетях есть своя специфика: модели очень долго учатся, требуют много ресурсов. Информация будет скорее справочной, будет много ключевых слов без глубокого погружения: что у нас есть и как с этим работать, как правильно искать и самостоятельно изучать.
Давайте подробнее остановимся на некоторых из перечисленных шагов.
Сначала есть принятие решения на уровне бизнеса и решение относительно бюджета проекта. Мы не будем касаться этой стороны вопроса. Будем считать, что задача поставлена
Начинается работа инженера. Тут надо исследовать информационное поле (baselines), то есть изучить, какие решения уже есть и какие подходы применяются
Затем формулируются метрики - критерии, которые покажут, насколько хорошо мы сделали работу
Когда мы поняли, как будем оценивать результат, мы формируем набор данных, на котором эти метрики будем рассчитывать. Эти данные должны максимально близко отражать сценарий использования модели
Мы разрабатываем простую утилитку - бенчмарк, - которая позволяет оценивать любые предсказания по этим метрикам на этих данных. То есть мы автоматизируем процесс оценки качества
Следующим шагом мы должны оценить результат существующих решений (baselines) на нашей тестовой выборке и проанализировать ошибки
Тут мы приближаемся к тому, чтобы начать обучать свои модели. До этого обучать модели неэффективно: всегда сначала нужно смотреть, как и что делалось ранее, насколько это было эффективно. Может быть, нас устроит уже существующее решение и не нужно будет вообще ничего обучать. Но если все же нужно, то дальше мы собираем обучающие данные. Это отдельный большой вопрос, как это делать, но в этой статье мы его касаться не будем
Программируем наш pipeline, то есть создаем небольшую питоновскую библиотечку, которая позволит нам очень быстро и легко запускать новые эксперименты, и которая делает наши выводы по экспериментам надежными
Исследование. Мы строим модели, выдвигаем гипотезы, смотрим на ошибки и пытаемся эти ошибки исправить
Когда запас времени и ресурсов на исследование исчерпан, мы должны сформировать отчет и показать результаты. А на самом деле, будет лучше если демонстрация результатов будет периодическая - чтобы собирать обратную связь, приоритезировать разные типы ошибок и замечать проблемы в разработке как можно раньше
Обзор существующих проектов - baselines
Ищем baselines:
научные статьи, где описывается метод
готовые репозитории с кодом
коммерческие продукты, когда код закрыт, но мы можем через интерфейс понять: хорошо ли оно работает?
Для каждого бейзлайна необходимо понять:
насколько легко адаптировать его для наших потребностей
нашу ли задачу он решает
можем ли мы, дописав поверх немного кода, сделать то, что нам нужно, вообще без обучения?
Ключевые ресурсы, по которым имеет смысл искать существующие решения:
Paperswithcode.com – это крупнейший сборник статей со ссылками на реализации на github
Сам github.com, там часто есть списки по нужным темам. Например, отличный список репозиториев по семантической сегментации
scholar.google.com, специализированный поисковик по научным статьям. Научные тексты он ищет чуть лучше, чем Google по всему вебу
Выбор метрик
Надо понимать, что модель часто нельзя оценить по одной метрике. Не надо бояться, что придется считать много метрик. Даже если метрики противоречат друг другу, как например, полнота и точность классификации, но зато именно они понятны для менеджеров и заказчиков. Есть метрики более сложные для понимания неспециалистами в анализе данных: ROC AUC, например, но они удобны тем, что одним числом многогранно характеризуют качество работы модели и облегчают процесс ее оптимизации.
Избегайте использовать не общепринятые метрики! Там могут быть подводные камни и сложнее будет показать преимущества вашего решения.
Часто важно выбрать какой-то ориентир по метрикам. Тут нужно быть осторожным и ориентироваться на среднее качество конкурентов. И даже если у вас 50 метрик, вам все равно стоит предусмотреть отдельную выборку, на которой вы будете сравнивать модели «на глаз», чтобы понимать, насколько критично модель ошибается на субъективном уровне.
Составление тестовой выборки – «золотого стандарта»
Здесь самое главное, чтобы данные были близки к production, чтобы они реально отражали сценарий использования модели. Полезно иметь разбивку датасета на группы по вариантам использования или по сложности и считать метрики на каждой группе по отдельности, чтобы оценка качества была многогранна.
Например, для сегментации это могут быть какие-то узкие и вытянутые объекты или большие объекты, фотографии, сделанные днем или ночью. Соответственно, метрики надо считать, как по всей тестовой выборке сразу, так и по подвыборкам в отдельности. И как я уже сказал, имеет смысл предусмотреть отдельную подвыборку для визуальной оценки качества. Это полезно для генерации новых гипотез, хотя метрики на маленькой выборке считать не стоит.
Чтобы получить качественную модель, «золотой стандарт» должен быть качественным, то есть его нужно разметить вручную! Сюда надо реально вложиться. Да, размечать дорого, скучно, сложно, долго, но это нужно сделать.
Разработка бенчмарка
Когда мы поняли, как и на чем будем оценивать модель, мы автоматизируем эту работу - создаем benchmark. Это простая программа, питоновский скрипт, который принимает на вход тестовую выборку. В процессе работы над проектом тестовая выборка может меняться: поступят новые требования от заказчика или мы поймем, что неправильно составили выборку. Скрипт должен позволять подставлять другие выборки. Например, он принимает на вход ссылку и выдает метрики, посчитанные по всем подгруппам тестовой выборки. Таким способом наш бенчмарк задает способ оценки моделей и способ хранения предсказаний моделей. Это удобно, уменьшает путаницу и позволяет стандартизировать работу.
Оценка качества бейзлайнов на тестовой выборке
У нас есть инструмент для оценки качества моделей. Теперь берем бейзлайны, которые нашли, применяем их, сохраняем результаты и прогоняем через benchmark. Смотрим на ошибки и пытаемся понять: где же бейзлайны хорошо работают, а где плохо? Наша дальнейшая работа в первую очередь должна быть нацелена на те места, где бейзлайны работают плохо, потому что если они уже хорошо работают, то мы их просто берем. Не надо дублировать работу, важно смотреть на ошибки.
Сбор обучающих данных
На слайде приведены разные варианты подходов для сбора обучающих данных. Тут необходимо помнить, что обучающие данные часто важнее, чем архитектуры и сложные функции. Сложные функции потерь часто придумывают, чтобы лучше работать с «грязными» данными. То есть. это «костыль», который помогает работать, когда нет хороших данных. Поэтому, если есть возможность получить хорошие данные, обязательно нужно сосредоточиться на них и только потом садиться за перебор архитектур, либо чередовать этапы улучшения модели и очистки данных.
Разработка pipeline для экспериментов
Что такое pipeline? Это среда, в которой мы будем программировать все эксперименты. То есть мы будем описывать архитектуры, задавать функции потерь, конфигурировать это все, запускать, обучать, смотреть на метрики, сохранять модели, загружать модели, предсказывать.
Pipeline должен обеспечивать две вещи:
Позволять быстро работать программистам: каждая гипотеза должна быть запрограммирована не более чем за пару дней. Если вы целую неделю только программируете, и нейросеть еще неделю будет учиться, то это провал. Если на программирование уходит много времени, надо декомпозировать гипотезу на более простые фрагменты. Часто можно выделить упрощённую версию гипотезы и запустить её обучаться почти мгновенно.
Должен обеспечивать воспроизводимость и надежность выводов. Если вы обучили новые модели, получили прирост метрик, отложили на время, через неделю вернулись и еще раз обучили то же самое, а прироста уже нет — это очень плохая ситуация и pipeline должен помогать нам в нее не попадать.
Очень часто, особенно начинающие, используют Jupyter notebook. Это классная среда, она очень удобна только для того, чтобы взять данные, один раз на них посмотреть и порисовать графики. Еще она хороша, чтобы делать обучающий курс – это удобно. Но если вы собираетесь делать проект, ориентированный на результат, он может затянуться и тогда лучше делать библиотеку, в которой понятна точка входа и архитектура внутри, налажены оценка качества, сохранение, загрузка. То есть это как бы регламент того, как вы работаете, только оформленный в виде программы.
Исследования: строим модели, оцениваем качество, сравниваем
Исследование - это итерационный процесс. Обучение — процесс долгий. Нужно сделать так, чтобы не было задержек на его старте, то есть мы должны быстро программировать, и чтобы сам процесс быстро шел. Некоторые гипотезы можно проверить без обучения: просто взять существующую модель, как-то нарушить ее данные на входе и понять, чувствительна она к изменениям или нет? В качестве примера можно привести аналогию: инженер, который работает с нейросетями, на самом деле менеджер. Он формулирует задачи, раздает их сотрудникам, и они уходят работать на неделю. Сотрудники — это видеокарты, они уходят считать надолго и задача менеджера — это с одной стороны сделать так, чтобы ни один сотрудник не простаивал, а с другой стороны сотрудники не должны делать лишней работы. Мы не должны запускать ненужных экспериментов и наш код для экспериментов не должен содержать ненужных шагов.
В заключение
Несколько рекомендаций начинающим инженерам на основе моего опыта и мнения коллег. На слайде приведены важные компетенции и о них многие говорят.
Я хочу остановиться на паре паттернов поведения, которых начинающему инженеру надо избегать, когда он приходит работать в компанию.
Первое - геройство. Не надо следовать позыву “ребята, я сейчас сам все сделаю, а вы все удивитесь”. Это приводит к тому, что решение задачи затягивается. С этим, наверное, можно спорить, но мне кажется, главное, что должен уметь Junior инженер - это надежно программировать и хорошо тестировать. Лучше сделать меньше и создать простой и надежный алгоритм, чем взять более сложную задачу и в которой некий corner case будет плохо работать. В машинном обучении это напрямую влияет на достоверность выводов: незамеченная ошибка на раннем этапе проекта может иметь катастрофические последствия в конце проекта.
Второе - не замыкаться, не пропадать, продолжать общаться. То есть вы вроде бы взяли задачу, начали ее решать и понимаете, что не получается, а прийти и сказать, что не сделал - сложно. Нет ничего страшного в том, чтобы прийти и рассказать о возникших проблемах. Это абсолютно нормально. Вполне вероятно, что это не вы не можете решить, а просто задача такая. Возможно, взгляд со стороны или подсказка коллег позволит или легко обойти сложности в решении задач или оставить их и двигаться по другому пути.
Роман Суворов,
ведущий инженер Центра Искусственного интеллекта Samsung в Москве,
автор курса по обработке текстов на Stepik
В этом посте рассказана только первая часть видеолекции "Как эффективно проводить эксперименты" цикла Samsung Innovation Campus. Во второй части видеоверсии лекции Романа Суворова дополнительно рассмотрены некоторые tips&tricks по обучению нейросетей, а также практические вопросы создания pipeline: как организовать код и удобно конфигурировать, как хранить и загружать данные, как визуализировать.
Все лекции цикла Samsung Innovation Campus - AI можно посмотреть в плейлисте на YouTube канале «IT Академии Samsung». Они посвящены вопросам разработки нейронных сетей и их применения для решения практических задач. На данный момент опубликованы 16 лекций от специалистов московского Центра искусственного интеллекта Samsung, Института системного программирования РАН, Сбербанка и вузов-партнеров.
Лекции проходят по средам и сегодня, 28 апреля, в 14-00 (по московскому времени) начнется очередная трансляция: Иван Лазаревский, преподаватель IT Академии Samsung в МГТУ СТАНКИН расскажет об автоматической суммаризации (реферировании) текстов.
Приглашаем всех желающих!