как понять что модель переобучена
Мы продолжаем знакомиться с теоретическими вопросами обучения НС, без которых невозможно их качественное построение. И это занятие начнем с очень важной темы – переобучения. Что это такое и чем это чревато? Давайте представим, что у нас есть два класса линейно-разделимых образов:
И из предыдущих занятий мы уже знаем, что для их различения достаточно одного нейрона. Но, что будет, если мы выберем сеть с большим числом нейронов, для решения этой же задачи?
В процессе обучения она способна формировать уже более сложную разделяющую линию, например, провести ее вот так:
Если мы продолжим увеличивать число нейронов скрытого слоя, то будем получать все более сложную закономерность разделения двух классов:
К чему это в итоге приведет? Да, на обучающем множестве все будет отлично, но в процессе эксплуатации такой сети будем получать массу ошибок:
Этот эффект и называется переобучением, когда разделяющая плоскость слишком точно описывает классы из обучающей выборки, и в результате теряется обобщающая способность НС.
Это можно сравнить с ленивым, но способным студентом (с прекрасной памятью), сдающим экзамен, допустим, по вышке, где предполагается решение экзаменационных задач. Ему проще выучить ход их решения не особо погружаясь в детали. Тогда, выбрав одну из них, он сможет быстренько вспомнить решение и записать его. А другой, не обладая хорошей памятью, но достаточно усидчивый, чтобы понять ход решения и запомнить их принцип, будет способен решать не только экзаменационные задачи, но и любые другие, сходные с ними. То есть, у него будет лучшая обобщающая способность.
Такой вывод может показаться несколько неожиданным. Казалось бы, чем больше нейронов в НС, тем качественнее она должна работать. Но на практике имеем обратный эффект: избыток нейронов ухудшает обобщающие способности. В идеале, число нейронов должно быть ровно столько, сколько необходимо для решения поставленной задачи. Но как определить, сколько их нужно? Здесь, опять же, нет универсального алгоритма. Это определяется опытным путем, подбирая минимальное число нейронов, при котором получается приемлемое качество решения задачи.
Рекомендация обучения №6:
Использовать минимальное необходимое число нейронов в нейронной сети.
Однако, мы все же можем контролировать этот эффект в процессе обучения. Для этого обучающая выборка разбивается на два множества: обучающее и валидации (проверочное):
На вход НС подаются наблюдения из обучающей выборки по схеме, которую мы рассматривали на предыдущем занятии. А, затем, после каждой эпохи, вычисляется критерий качества работы сети для обоих множеств: обучающего и проверочного. Получаем два графика:
Если с какой-то итерации графики начинают расходиться, то делается вывод, что НС переобучается и процесс обучения следует прервать. В этом случае, лучшие весовые коэффициенты соответствуют границе переобучения.
Здесь у вас может возникнуть вопрос: зачем мы разбиваем обучающую выборку, а не используем в качестве проверочного множества тестовое? Тестовое – это то, на котором как раз и проверяется качество работы сети:
Дело в том, что как только какая-либо выборка прямо или косвенно участвует в обучении, то она влияет на состояние весов НС. В результате выборка валидации тоже, отчасти, становится обучающей и нейросеть подстраивается и под нее. Поэтому для объективной проверки качества необходима третья выборка – тестовая. Отсюда получаем:
Рекомендация обучения №7:
Разбивать все множество наблюдений на три выборки: обучающую, валидации и тестовую.
Вот такие основные подходы существуют для предотвращения переобучения НС.
Критерии останова процесса обучения
Конечно, критерии останова могут быть и другими. Я здесь привел лишь распространенные варианты, которые чаще всего используются на практике. Но, в каждой конкретной ситуации могут быть сформулированы свои критерии останова обучения сети.
Видео по теме
Нейронные сети: краткая история триумфа
Структура и принцип работы полносвязных нейронных сетей | #1 нейросети на Python
Ускорение обучения, начальные веса, стандартизация, подготовка выборки | #4 нейросети на Python
Функции активации, критерии качества работы НС | #6 нейросети на Python
Как нейронная сеть распознает цифры | #9 нейросети на Python
Оптимизаторы в Keras, формирование выборки валидации | #10 нейросети на Python
Batch Normalization (батч-нормализация) что это такое? | #12 нейросети на Python
Как работают сверточные нейронные сети | #13 нейросети на Python
Делаем сверточную нейронную сеть в Keras | #14 нейросети на Python
Примеры архитектур сверточных сетей VGG-16 и VGG-19 | #15 нейросети на Python
Теория стилизации изображений (Neural Style Transfer) | #16 нейросети на Python
Делаем перенос стилей изображений с помощью Keras и Tensorflow | #17 нейросети на Python
Как нейронная сеть раскрашивает изображения | #18 нейросети на Python
Введение в рекуррентные нейронные сети | #19 нейросети на Python
Как рекуррентная нейронная сеть прогнозирует символы | #20 нейросети на Python
Делаем прогноз слов рекуррентной сетью Embedding слой | #21 нейросети на Python
Как работают RNN. Глубокие рекуррентные нейросети | #22 нейросети на Python
Как делать сентимент-анализ рекуррентной LSTM сетью | #24 нейросети на Python
Рекуррентные блоки GRU. Пример их реализации в задаче сентимент-анализа | #25 нейросети на Python
Двунаправленные (bidirectional) рекуррентные нейронные сети | #26 нейросети на Python
Автоэнкодеры. Что это и как работают | #27 нейросети на Python
Вариационные автоэнкодеры (VAE). Что это такое? | #28 нейросети на Python
Делаем вариационный автоэнкодер (VAE) в Keras | #29 нейросети на Python
Расширенный вариационный автоэнкодер (CVAE) | #30 нейросети на Python
Что такое генеративно-состязательные сети (GAN) | #31 нейросети на Python
Делаем генеративно-состязательную сеть в Keras и Tensorflow | #32 нейросети на Python
© 2021 Частичное или полное копирование информации с данного сайта для распространения на других ресурсах, в том числе и бумажных, строго запрещено. Все тексты и изображения являются собственностью сайта
Жизненный цикл ML-модели
Всем привет! Меня зовут Максим, и в Ситимобил я занимаюсь машинным обучением. Сегодня я расскажу вам, как мы разрабатываем устойчивые ML-модели в суровых условиях изменчивого мира.
Зачем моделям нужен жизненный цикл
Будем называть ML-моделью объект, возвращающий прогноз для входящего набора признаков. Пусть для простоты это будет модель бинарной классификации.
Представим, что модель уже разработана, метрика на out of time выборке (отложенной во времени) нас устраивает, и мы выкатываем модель в production. Получаем положительный результат в первый месяц работы, но потом качество сильно падает. Сколько нужно ждать, прежде чем предпринимать какие-либо действия в отношении модели? Стоит ли сразу же пытаться актуализировать её или же подождать, так как через день-два метрики снова станут стабильными? В идеальном мире ответ должен быть до развёртывания в production. И жизненный цикл поможет нам ответить на этот и другие вопросы по работе модели.
Когда вы начнёте искать информацию по планированию жизненного цикла модели, в большинстве случаев найдёте статьи по поддержке существующего алгоритма переобучения средствами DevOps и MLOps. Но как сделать алгоритм, который нужно поддерживать, переобучать и валидировать?
Принципы разработки жизненного цикла модели
Чтобы модель стабильно работала в будущем, нужно на этапе разработки эмулировать её работу на достаточно большом наборе данных. На каждой итерации можно менять один или несколько параметров. Этот процесс напоминает классический подбор гиперпараметров, поэтому нам нужно точно оценивать результат каждой отдельной симуляции по целевой метрике. Только в нашем случае гиперпараметры не типизированы и мы сами решаем, что именно менять в каждой конфигурации.
Какие параметры нужно учитывать, чтобы оценить жизненный цикл:
периодичность переобучения модели;
необходимый объём обучающей выборки;
поведение целевой метрики во времени в стабильных и экстремальных условиях;
как учитывать различные смещения целевой переменной и модельных признаков;
прочие вопросы, характерные для отрасли применения модели.
Рассмотрим отдельно каждый из этих пунктов.
Периодичность переобучения модели
Так как мир не стоит на месте и всё постоянно меняется, модель может устаревать и терять качество (в единицах целевой метрики). Поэтому нужно проверить, через сколько часов, дней, месяцев качество начинает ухудшаться. Для этого мы проводим симуляцию, в которой движемся скользящим окном по всем доступным датам и оцениваем модель на несколько интервалов вперед.
Так мы сможем оценить потенциальное ухудшение качества модели во времени и принять решение о частоте её переобучения.
Оценка объема обучающей выборки
По аналогии с изменением объёма тестовых данных мы можем менять объём обучающей выборки. Мотивация может быть разная:
на небольшом промежутке времени на обучающей выборке модель может переобучиться;
в распределении целевой переменной есть сезонность;
модель вносит смещение в распределение целевой переменной;
объёма данных может быть недостаточно для выявления ключевых зависимостей.
Чтобы понять, сколько данных нам достаточно для стабильной работы модели, нужно также пройтись скользящим окном по доступным датам, но уже в обратную сторону, постепенно увеличивая обучающий набор данных.
Итогом этой симуляции будет n оценок модели на одном и том же наборе тестовых данных, что позволит точно понять, какая конфигурация оказалась лучшей.
Изменение распределения целевой переменной
Часто бывает так, что поведение целевой переменной нестабильно во времени. Ещё больше нестабильности вносит тот факт, что модель прямо влияет на её распределение (в нашем примере).
Здесь видно, как зона распределения условной целевой переменной постепенно увеличивается с течением времени. Это означает, что применение ML-модели в новой области, которой не было в обучающей выборке, может быть непредсказуемо.
Частично эту проблему должно решать правило частоты переобучения модели. Но ещё на этапе моделирования мы можем оценить влияние нестабильного поведения предсказываемой переменной на целевую метрику. Для этого нужно провести симуляцию, в которой мы искусственно будем уменьшать или увеличивать на n% баланс положительного класса. Таким образом мы сможем сделать выводы о стабильности нашего жизненного цикла при нетипичном изменении (таком, которого не было в обучающей выборке) целевой переменной.
Прочие отраслевые вопросы
Самый простой пример: а что будет, если бизнес нашей компании вырастет на 20 % за n дней? Останется ли наш алгоритм стабильным, если завтра все входные признаки для модели увеличатся или уменьшатся на 20 %?
Алгоритм проверки аналогичен тому, что описан выше. Проводим симуляцию и проверяем, как увеличение или уменьшение того или иного признака влияет на стабильность целевой метрики. Если она ухудшается, то, возможно, стоит ещё раз пересмотреть частоту переобучения модели.
Все названные параметры могут как зависеть друг о друга, так и быть независимыми. Поэтому следует учитывать это при симуляции жизненного цикла. Идеальным решением подбора конфигурации будет оптимизация всех параметров сразу по сетке (как это происходит при подборе классических гиперпараметров).
Мы разработали правила жизненного цикла, что дальше?
Вот мы и получили набор правил работы ML-модели. Половина дела сделана, осталось запустить жизненный цикл в production и мониторить его работу.
Поскольку ещё на этапе моделирования мы предусмотрели большинство но не все потенциальных проблем, то можно ожидать стабильной работы модели некоторе время без внешнего вмешательства.
Простыми словами о методах решения проблем с переобучением
Я надеюсь, что после прочтения этого материала у вас сформируется более глубокое интуитивное понимание самой проблемы, а также вы сможете ориентироваться в методах ее решения и будете лучше понимать, что же сделали или не сделали ваши коллеги, которые разрабатывали модель машинного обучения.
Это особенно важно, поскольку переобучение «коварно», оно может возникнуть неявно и обнаружиться уже когда будет поздно, т.е. уже после внедрения модели в бизнес-процесс, когда ее результаты на новых данных окажутся существенно хуже, чем вы могли видеть во время ее разработки специалистами.
Здесь я постараюсь описать все максимально доступно, но буду рассчитывать, что у читателя есть самые базовые знания в области машинного обучения.
Итак, приступим. Когда я писал выше, что буду изъясняться максимально доступно, я имел ввиду, что буду стараться подбирать аналогии знакомые каждому и по возможности не вводить более строгие математические формулировки. Мне кажется такой подход самым верным, как минимум в рамках данной статьи, поскольку на мой взгляд, именно так оно зачастую и происходит при создании новых понятий и методов.
Математика, как и любая наука, это один из способов формального описания окружающего нас мира, а конкретные ее понятия – это удобные «инструменты» для этого описания.
Для машинного обучения, как для дисциплины из раздела прикладной математики, это работает еще сильнее, поскольку оно изначально создавалось как раз для решения реальных задач. Что особенно интересно, многие методы машинного обучения так или иначе пытаются воссоздать логику человека (почему их и относят к методам искусственного интеллекта), и именно в таком ключе я буду описывать проблему переобучения.
Что такое переобучение?
Многие элементарные для человека задачи очень часто оказываются не столь очевидными для алгоритмов машинного обучения.
К примеру, мы легко можем отличить рыбу от птицы, птицу от млекопитающего и так далее. Можем мы это сделать за счет многих-многих знаний, приобретенных за нашу жизнь, проще говоря в процессе обучения, при этом под обучением тут я имею ввиду вообще любой опыт может быть источником знаний.
На основе этих знаний мы делаем обобщения и, когда увидим животное, которое раньше не встречали, допустим, алмазного фазана, мы легко поймем, что это птица. Мы поймем это по клюву, перьям, ножкам, тому насколько он похож на других птиц и т.д.
Благодаря тому, что мы можем строить такие сложные зависимости, определить, какое животное перед нами для нас не составляет труда.
Но что, если бы мы не могли работать с такими сложными взаимосвязями? Или у нас не было бы такого объема знаний? Или за всю нашу жизнь мы бы видели целую тысячу разных птиц и всего десять собак, как бы тогда мы их отличали друг от друга?
Ровно с такими проблемами сталкиваются модели машинного обучения.
Теперь рассмотрим другой пример, допустим у нас есть данные по некоторым объектам (в нашем случае – опять по животным), под данными я имею ввиду различные признаки, например, вес, окрас, где обитает, что умеет, чем питается каждое животное и так далее.
Наша задача на основе этих данных и собственно разметки (знания, полученного извне или от учителя о том, каким животным является каждый конкретный экземпляр) вывести некое обобщающее правило, которым мы сможем пользоваться в дальнейшем, чтобы уже самостоятельно различать (классифицировать) животных.
Выше изображены и размечены наши объекты, красным – рыбы, зеленым – птицы.
Так как по условию мы изначально ничего не знаем про рыб и птиц, а учимся с нуля, вполне вероятно, что мы выведем правило вроде «кто умеет плавать – тот рыба». И будем в каком-то смысле правы, потому что по такому правилу на этих данных мы не ошибемся ни разу.
Однако, что же произойдет, когда мы встретимся с новым животным и как мы его классифицируем?
Как видим, мы ошибочно определили всех новых животных, но в чем же природа такой ошибки?
В данном случае очевидно, что мы вывели такое правило, которое имеет место только на обучающей выборке. Такая ситуация и называется проблемой переобучения (overfitting).
Выражаясь чуть более формально, переобучение – это явление, когда качество модели на обучающей выборке существенно превосходит качество модели на тестовой выборке.
И если в данном случае понятно, что изначально было выбрано очень сомнительное правило, то когда счет объектов идет на тысячи, число признаков на десятки или сотни, и при этом реальные модели часто оказываются трудно интерпретируемыми (что вообще говоря, зависит от алгоритма), то переобучение можно заметить, уже только сравнивая качество модели во время обучения и теста.
Подробнее про переобучение и как с ним бороться
«Неправильное» обобщающее правило – довольно общая фраза, на самом деле природа таких «неправильных» правил тоже отличается друг от друга, и в зависимости от нее надо предпринимать соответствующие шаги.
Самый очевидный – увеличить объем обучающей выборки. Для примера выше, если бы у нас были данные не по шести животным, а, скажем, по тысяче (при условии их разнообразия), то мы скорее всего выбрали какое-то более разумное правило, просто потому, что «кто плавает – тот рыба» не работало для некоторых птиц (утках, лебедях и т.д.) уже на этапе обучения, но зато работало бы что-то вроде «у кого жабры – тот рыба».
Опять же, при этом важно разнообразие выборки. Если модель машинного обучения изучит тысячу одинаковых объектов – не стоит ожидать, что ее качество существенно улучшится. Возвращаясь к правилу «кто плавает – тот рыба», будь у нас в обучающей выборке тысяча птиц, но ни одна из них не умела бы плавать – мы бы все равно могли выбрать его.
В общем, данных должно быть много, и они должны быть разнообразными.
Регуляризация
Теперь рассмотрим, пожалуй, основной и самый универсальный метод борьбы с переобучением – регуляризацию.
Для этого представим следующую задачу. Теперь мы в роли судьи и за годы нашего опыта мы придумали строгое правило, по которому можем автоматизированно выносить приговор, для простоты – лишить свободы или оправдать человека (сюда же отнесем условное наказание).
Под строгим правилом мы понимаем чисто математическое выражение приговора через какие-то факты, и если сумма этих фактов больше определенного порога (для простоты — 50), то будем считать человека виновным.
Это может выглядеть так:
Т.е. подсудимый совершил ограбление, найдены улики, к тому же он рецидивист. При этом есть некоторые смягчающие обстоятельства, но их веса недостаточно, чтобы оправдать или отделаться условным сроком:
Теперь представим, что за все время работы судьей мы ни разу не оправдали/не давали условный срок по делам кражи. Тогда модель машинного обучения может решить, что любой обвиняемый по делу кражи, т.е. факту обвинения в краже будет дан такой большой вес, что все остальные факты окажутся незначительными, например, как на рисунке ниже.
Фактически мы понимаем, что при отсутствии улик, показаний свидетелей и т.п. мы не сможем осудить человека. Но, повторюсь, ранее по всем делам кражи подсудимые были признаны виновными. Т.е. у нас просто нет опыта, который бы подтвердил такую логику.
К счастью, как раз для таких случаев существует регуляризация – метод, который не позволяет отдельным фактам/признакам получать слишком большие веса.
Чтобы лучше понять, что это значит, уточним, на что ориентируется модель, когда обучается.
Модели машинного обучения в процессе обучения всегда делают одно – минимизируют свои ошибки на обучающей выборке. Говоря точнее, минимизируют даже не ошибки, а функцию потерь – некоторое количественное выражение допущенных ошибок.
Чем больше ошибок – тем больше значение функции потерь.
Когда мы добавляем регуляризацию – наша функция потерь меняется, теперь важны не только ошибки, но и веса отдельных фактов/признаков, на которые мы опираемся, причем, чем больше веса – тем больше значение функции потерь.
Формально, без регуляризации имеем следующую функцию потерь:
Где L– функция потерь, которая зависит от весов ;
f– просто некоторая функция, которая дает количественное выражение совершенных ошибок;
Y – целевая переменная, в данном примере – «виновен» или «невиновен»;
С регуляризацией — такую:
То есть, теперь мы учитываем сумму всех весов.
Примечание: фактические берется немного другая сумма, но не будем излишне усложнять, поскольку смысл этого слагаемого не меняется – мы «штрафуем» модель за слишком большие веса.
Что получаем? Вспомним условие примера с кражей – на нашем опыте по всем кражам подсудимые были признаны виновными. До этого сам факт кражи уже был достаточным для того, чтобы посадить подсудимого, по крайней мере так считала модель. Но если мы введем регуляризацию, модель не сможет так «сжульничать», выбрав слишком простое обобщающее правило (на самом деле может быть и наоборот, когда модель выбирает слишком «сложное» правило), и будет вынуждена искать более сложные (или наоборот, более простое). Однако, скорее всего возрастет и ошибка, но в любом случае рассмотрим, как это можем выглядеть:
Модель | f (Y, h (x)) | ||
С большими весами | 0 | 1000 | 1000 |
С небольшими весами | 100 | 100 | 200 |
То есть, несмотря на то что модель с небольшими весами ошибается больше, общее значение функции потерь оказывается меньше, а значит, модель с небольшими весами окажется предпочтительнее.
Соответственно, веса примут примерно такие значения, и мы вынесем следующий приговор:
Проще говоря, регуляризация «заставляет» модель искать более взвешенные решения, а не основанные на одном-двух признаках. Как и мы, модель с регуляризацией старается принимать решения, учитывая все возможные факторы и не упускать ничего из виду.
Пример
Теперь попробуем показать более конкретный случай. Задача сделана по мотивам одного из уроков курса mlcourse.ai Юрия Кашницкого, который в свою очередь ссылается на Стэнфордский курс по машинному обучения от Andrew Ng.
В этой задаче у нас есть массив данных для 118 микрочипов, два признака – тест 1 и тест 2. По результатам этих двух тестов принимается решение браковать или выпускать очередной микрочип – это и есть наша целевая переменная, то есть мы решаем задачу бинарной классификации.
Поскольку у нас всего два признака, очень просто будет визуализировать наши данные.
Важное примечание, тут признаки уже центрированы (т.е. из них вычли среднее значение соответствующего признака по всем объектам).
Что же от нас требуется? Нам надо каким-то образом, основываясь на данных двух признаках научится отличать «красные» точки от «синих». Результатом этого будет какое-то правило «разделяющее» точки между собой. Это правило так и называется – «разделяющая гиперплоскость» и выглядит примерно так:
То есть для двумерного признакового пространства – это просто прямая.
Это пример плохой модели, которая разделяет точки неправильно. Немного ее улучшив (использовав полиномиальные признаки), мы получим что-то вроде такого:
Мы видим, что новая линия намного лучше разделяет точки, но возникает другая проблема. Если бы мы могли просто нарисовать эту линию рукой, мы бы скорее всего нарисовали овал или круг, но линия, построенная моделью, оказалась куда более сложной. То, что модель вывела такие «слишком» сложные закономерности в данных, говорит о том, что она переобучилась.
Теперь посмотрим, что будет, если мы воспользуемся регуляризацией:
Вот это уже больше похоже на правду. Хотя с виду модель, кажется, ошибается больше, но теперь у нас не возникает сомнений в «адекватности» правила, которое она выводит.
Теперь то, о чем мы говорили до этого чисто теоретически рассмотрим на этом примере.
Во-первых, мы говорили, что переобученная модель ищет слишком простое или, наоборот, слишком сложное правило – главное, что «слишком». На языке модели это значит, что она дает отдельным признакам слишком большие веса, при построении прогноза. Если мы будет сравнивать веса модели «без» и «с» регуляризацией, то мы увидим следующую картину:
Примечание: может возникнуть вопрос – откуда столько признаков? Как мы упомянули ранее, мы использовали полиномиальные признаки (7-й степени), что дает нам суммарно 36 признаков.
Веса признаков с регуляризацией как правило не больше +/- единицы, в то время как веса признаков без регуляризации сильно разбросаны, но в основном они выходят далеко за пределы единичного круга.
И последнее, я уже показывал, как может выглядеть выбор лучшей модели с учетом регуляризации «по идее», посмотрим, что получилось на практике и сравним эти две:
Модель | f (Y, h (X) | ||
Без регуляризации | 32,30 | 141,49 | 173,78 |
С регуляризацией | 65,56 | 2,75 | 68,31 |
Хотя модель без регуляризации меньше ошибается (значение функционала ошибки во втором столбце), разница в весе признаков оказывается более существенной, поэтому модель с регуляризацией для нас будет предпочтительнее.
Заключение
В заключение надо сказать, что, конечно, существуют и другие, специфичные для конкретных алгоритмов машинного обучения способы борьбы с регуляризацией, но эти являются, пожалуй, основными и самыми универсальными.
Надеюсь, я помог вам интуитивно понять — что же такое проблема переобучения, от чего зависит и к чему приводит, и как мы можем с этим бороться.