Ответ на вопрос с собеседования💼
Вы могли заметить, что вопрос не предполагает единственно верного ответа🙂 Мне всегда интересно, как кандидат умеет рассуждать, задавать вопросы и “решать вопросики”. Вопросы на знаю/не знаю обычно не задаю. Как по мне, это бесполезно. Да и скучно. Если человек не знает ответ на вопрос типа "чем LayerNorm отличается от GroupNorm", то он, сказав "не знаю", может расстроиться, поплыть и не проявить свои лучшие качества. Вопросы на конкретные знания можно задавать незаметно, между делом, и про себя отмечать, ответил ли кандидат.
Например, в задаче про кошек некоторые кандидаты сразу говорят: "а зачем нам для задачи сегментации и таких простых объектов 1000 картинок? Там с претрейна и на 500 хорошо завестись должно!". И это очень хороший поинт! Это означает, что кандидат примерно понимает, сколько картинок хватает для разных задач. В таком случае мы меняем условия на некомфортное для него количество картинок и решаем задачу с новым сетапом. Заметьте, если кандидат не сказал “что-то многовато картинок“, то он от этого не поплывет, и это не помешает ему показать все свои знания😉
Вариантов решения задачи тьма. Опишу один из них, который "принимается":
Перед нами задача семантической сегментации с мультилейбл таргетом (пиксель может быть одновременно и кошкой и животным). Поэтому сетку будем учить с BCE-лоссом по каждому каналу. В таком случае лосс считается в каждом пикселе независимо, а затем усредняется. Выберем среди 1000 размеченных картинок с кошками 500 картинок и отдадим их на доразметку класса животных. В итоге получим 500 картинок, на которых размечены оба класса и 500 картинок, на которых только кошки. При обучении сети не будем считать лосс по каналу с животными, если на картинке не размечен этот класс.
При таком подходе мы максимально использовали исходную большую разметку (1000 фоток) и новую разметку. Также у нас есть картинки, на которых размечены оба класса. И сделали это всего одним ифом!
Кстати, это хорошо работающий подход, когда у вас есть гигантский датасет, и нужно научиться предсказывать на нем что-то новое. И чтобы выучить это новое, вам не нужен весь размеченный миллиард картинок. Размечаем часть и только на этой части прокидываем "новые" градиенты. Профит!🙂
Эта задачка хороший старт, попутно ее можно развивать множеством вопросов, например:
* Пусть картинок не 1000 и 500, а 10000 и 100. Что поменяется?
* Как можно попытаться ускорить процесс разметки, чтобы успеть получить, скажем, не 500, а 900 размеченных фоток?
* А как выбрать из 1000 фоток 500 фоток для доразметки? А как быть, если в исходной выборке из 1000 фоток совсем не было фоток других животных?
* Позже заказчик приходит и просит ещё маски для самолетов. До дедлайна совсем немного времени и вы понимаете, что не успеете доразметить и получить новую модель. Ваши действия?
И ещё миллион других вариантов вопросов, которыми можно продолжить задачу🙂 Но ими не нужно "пулять" подряд, а вкидывать между делом при диалоге.
Вы могли заметить, что вопрос не предполагает единственно верного ответа🙂 Мне всегда интересно, как кандидат умеет рассуждать, задавать вопросы и “решать вопросики”. Вопросы на знаю/не знаю обычно не задаю. Как по мне, это бесполезно. Да и скучно. Если человек не знает ответ на вопрос типа "чем LayerNorm отличается от GroupNorm", то он, сказав "не знаю", может расстроиться, поплыть и не проявить свои лучшие качества. Вопросы на конкретные знания можно задавать незаметно, между делом, и про себя отмечать, ответил ли кандидат.
Например, в задаче про кошек некоторые кандидаты сразу говорят: "а зачем нам для задачи сегментации и таких простых объектов 1000 картинок? Там с претрейна и на 500 хорошо завестись должно!". И это очень хороший поинт! Это означает, что кандидат примерно понимает, сколько картинок хватает для разных задач. В таком случае мы меняем условия на некомфортное для него количество картинок и решаем задачу с новым сетапом. Заметьте, если кандидат не сказал “что-то многовато картинок“, то он от этого не поплывет, и это не помешает ему показать все свои знания😉
Вариантов решения задачи тьма. Опишу один из них, который "принимается":
Перед нами задача семантической сегментации с мультилейбл таргетом (пиксель может быть одновременно и кошкой и животным). Поэтому сетку будем учить с BCE-лоссом по каждому каналу. В таком случае лосс считается в каждом пикселе независимо, а затем усредняется. Выберем среди 1000 размеченных картинок с кошками 500 картинок и отдадим их на доразметку класса животных. В итоге получим 500 картинок, на которых размечены оба класса и 500 картинок, на которых только кошки. При обучении сети не будем считать лосс по каналу с животными, если на картинке не размечен этот класс.
При таком подходе мы максимально использовали исходную большую разметку (1000 фоток) и новую разметку. Также у нас есть картинки, на которых размечены оба класса. И сделали это всего одним ифом!
Кстати, это хорошо работающий подход, когда у вас есть гигантский датасет, и нужно научиться предсказывать на нем что-то новое. И чтобы выучить это новое, вам не нужен весь размеченный миллиард картинок. Размечаем часть и только на этой части прокидываем "новые" градиенты. Профит!🙂
Эта задачка хороший старт, попутно ее можно развивать множеством вопросов, например:
* Пусть картинок не 1000 и 500, а 10000 и 100. Что поменяется?
* Как можно попытаться ускорить процесс разметки, чтобы успеть получить, скажем, не 500, а 900 размеченных фоток?
* А как выбрать из 1000 фоток 500 фоток для доразметки? А как быть, если в исходной выборке из 1000 фоток совсем не было фоток других животных?
* Позже заказчик приходит и просит ещё маски для самолетов. До дедлайна совсем немного времени и вы понимаете, что не успеете доразметить и получить новую модель. Ваши действия?
И ещё миллион других вариантов вопросов, которыми можно продолжить задачу🙂 Но ими не нужно "пулять" подряд, а вкидывать между делом при диалоге.
🔥41👍17🤔9❤4❤🔥1
Рубрика «Вопрос с собеседования»💼
Вы натренировали гениальную нейросеть, которая умеет отличать котов от собак. У вас даже есть прод!
Люди с телефона посылают картинки в ваше API, которое под капотом дергает нейросеть (рис. 1). Сначала всё было хорошо, но ваше приложение стало очень популярным, и теперь ваше API иногда рвётся от нагрузки (рис. 2). Какие минусы есть у изначального решения? Как выдержать бо́льшую нагрузку, не разоряясь на покупку новых карточек? (предполагаем, что бутылочное горлышко системы — инференс нейросети)
По традиции перед публикацией ответа даём несколько часов на подумать😉
Вы натренировали гениальную нейросеть, которая умеет отличать котов от собак. У вас даже есть прод!
Люди с телефона посылают картинки в ваше API, которое под капотом дергает нейросеть (рис. 1). Сначала всё было хорошо, но ваше приложение стало очень популярным, и теперь ваше API иногда рвётся от нагрузки (рис. 2). Какие минусы есть у изначального решения? Как выдержать бо́льшую нагрузку, не разоряясь на покупку новых карточек? (предполагаем, что бутылочное горлышко системы — инференс нейросети)
По традиции перед публикацией ответа даём несколько часов на подумать😉
🔥23🤔7👍4❤🔥1❤1
Ответ на вопрос с собеседования 💼
У изначального решения большой минус: картинки предсказываются синхронно по одной. Думаю, всем известно, что предсказать 64 картинки по одной выйдет гораздо дольше, чем предсказать один батч из 64 картинок. Но как организовать батчинг, когда картинки приходят к нам с клиента по одной?
Добавим немного асинхронщины. Введем промежуточную очередь! (рис.3). Также введем два параметра:
1) batch_size — размер батча, с которым хотим предсказывать;
2) interval — допустимое время "простоя".
Раньше мы сразу отправляли картинку в нейросеть. А сейчас позволим себе немного подождать, пока накопится батч.
После того, как картинка пришла в API, она сразу сбрасывается в очередь (это быстро!). Каждые interval ms мы "выгребаем" N картинок из очереди. N = min(len(queue), batch_size). (рис. 4)
Можно поступать умнее: если в очереди >= batch_size картинок, то после предикта будем сразу брать новую пачку.
Теперь должно стать понятнее, откуда берутся параметры у TorchServe.
Но в реальных задачах лучше не заниматься написанием собственного батчинга, а использовать готовые inference-сервера. Например, TorchServe или Triton от Nvidia.
Паттерн с введением промежуточной очереди, в которую можно что-то по-быстрому скинуть и которую мы разгребаем в удобном для нас темпе, появился конечно же не из мира DL 🙂Это очень популярный паттерн для highload-задач. Он позволяет бороться со всплесками и легко скейлиться под изменчивую нагрузку. Прочесть про него можно здесь.
У изначального решения большой минус: картинки предсказываются синхронно по одной. Думаю, всем известно, что предсказать 64 картинки по одной выйдет гораздо дольше, чем предсказать один батч из 64 картинок. Но как организовать батчинг, когда картинки приходят к нам с клиента по одной?
Добавим немного асинхронщины. Введем промежуточную очередь! (рис.3). Также введем два параметра:
1) batch_size — размер батча, с которым хотим предсказывать;
2) interval — допустимое время "простоя".
Раньше мы сразу отправляли картинку в нейросеть. А сейчас позволим себе немного подождать, пока накопится батч.
После того, как картинка пришла в API, она сразу сбрасывается в очередь (это быстро!). Каждые interval ms мы "выгребаем" N картинок из очереди. N = min(len(queue), batch_size). (рис. 4)
Можно поступать умнее: если в очереди >= batch_size картинок, то после предикта будем сразу брать новую пачку.
Теперь должно стать понятнее, откуда берутся параметры у TorchServe.
Но в реальных задачах лучше не заниматься написанием собственного батчинга, а использовать готовые inference-сервера. Например, TorchServe или Triton от Nvidia.
Паттерн с введением промежуточной очереди, в которую можно что-то по-быстрому скинуть и которую мы разгребаем в удобном для нас темпе, появился конечно же не из мира DL 🙂Это очень популярный паттерн для highload-задач. Он позволяет бороться со всплесками и легко скейлиться под изменчивую нагрузку. Прочесть про него можно здесь.
🔥46👍4❤1
Не забываем корни, напоминаем про батчнорм 😉
Батч нормализация — неотъемлимая часть CNN. Основная цель этого слоя — корректировать распределение фичей во время обучения нейронной сети. Главная формула в этом слое — (1). Она применяется к каждому каналу в батче. То есть для фичей размерности [B, H, W, C] считается C средних E(X) и C выборочных дисперсий Var(X).
Получается, в слое батч нормализации есть два статистических параметра — среднее и выборочная дисперсия и два обучаемых — γ и β. Если статистические параметры неудачно нормализуют фичи, то обучаемые параметры позволят сети самой подкорректировать интенсивность и сдвиг фичей на выходе. При необходимости, сеть выучит параметры γ и β таким образом, чтобы на выходе получались исходные фичи без нормализации. Также важно запомнить: во время инференса среднее и выборочная дисперсия не рассчитываются, используются их экспоненциально сглаженные оценки (2), которые считаются во время тренировки.
Батч нормализация — неотъемлимая часть CNN. Основная цель этого слоя — корректировать распределение фичей во время обучения нейронной сети. Главная формула в этом слое — (1). Она применяется к каждому каналу в батче. То есть для фичей размерности [B, H, W, C] считается C средних E(X) и C выборочных дисперсий Var(X).
Получается, в слое батч нормализации есть два статистических параметра — среднее и выборочная дисперсия и два обучаемых — γ и β. Если статистические параметры неудачно нормализуют фичи, то обучаемые параметры позволят сети самой подкорректировать интенсивность и сдвиг фичей на выходе. При необходимости, сеть выучит параметры γ и β таким образом, чтобы на выходе получались исходные фичи без нормализации. Также важно запомнить: во время инференса среднее и выборочная дисперсия не рассчитываются, используются их экспоненциально сглаженные оценки (2), которые считаются во время тренировки.
🔥31👍7🙏1
Какие плюсы даёт слой батч нормализации:
• Ускорение обучения. За счёт сохранения распределения фичей между слоями, нейронная сеть обучается быстрее. Например, в исходной статье авторам удалось добиться ускорения обучения в 14 раз.
• Можно использовать больший learning rate. Батч нормализация сглаживает ландшафт функции ошибки, тем самым позволяя использовать бо́льший lr без опаски проскочить локальный минимум.
• Регуляризация. Статистики считаются на батче и экспоненциального сглаживаются — появляется эффект регуляризации.
• Ёмкость сети не тратится понапрасну. Так как для основных слоёв сети распределение фичей практически не меняется, им не нужно тратить ману на заучивание распределений, а можно сконцентрироваться на поиске новых важных фичей.
• Ускорение обучения. За счёт сохранения распределения фичей между слоями, нейронная сеть обучается быстрее. Например, в исходной статье авторам удалось добиться ускорения обучения в 14 раз.
• Можно использовать больший learning rate. Батч нормализация сглаживает ландшафт функции ошибки, тем самым позволяя использовать бо́льший lr без опаски проскочить локальный минимум.
• Регуляризация. Статистики считаются на батче и экспоненциального сглаживаются — появляется эффект регуляризации.
• Ёмкость сети не тратится понапрасну. Так как для основных слоёв сети распределение фичей практически не меняется, им не нужно тратить ману на заучивание распределений, а можно сконцентрироваться на поиске новых важных фичей.
🔥28👍12🤔3
Стандартной схемой использования батч нормализации является Conv -> BN -> ReLU. Заметим, что на момент инференса слой батч нормализации является линейным. Таким образом, если этот слой используется в паре с другим линейным слоем, например свёрткой, то эти слои можно сплавить (fusion) в один, что сохранит параметры сети и ускорит её (3). Прочесть с выводом можно здесь.
Батчнормы очень чувствительны к сдвигам в данных. Все будет грустно даже если вы просто забыли перемешать данные между классами. Потому что вместо оценки для среднего всего датасета, батчнорм будет выдавать среднее по какому-то классу. Можно держать в голове простой пример (4): пусть при обучении сети будут идти подряд 100к жёлтых картинок, а затем 100к красных. Что будет, когда на инференсе придет жёлтая картинка? Кажется, что ничего хорошего🙂 Если сменили домен, попробуйте прогнать его через сеть для вычисления новых статистик. Это может значительно поднять качество.
Батчнормы очень чувствительны к сдвигам в данных. Все будет грустно даже если вы просто забыли перемешать данные между классами. Потому что вместо оценки для среднего всего датасета, батчнорм будет выдавать среднее по какому-то классу. Можно держать в голове простой пример (4): пусть при обучении сети будут идти подряд 100к жёлтых картинок, а затем 100к красных. Что будет, когда на инференсе придет жёлтая картинка? Кажется, что ничего хорошего🙂 Если сменили домен, попробуйте прогнать его через сеть для вычисления новых статистик. Это может значительно поднять качество.
🔥26👍10
Об асинхронности вычислений на карточке
Вычисления на карточке на самом деле проходят асинхронно. Мы "сбрасываем" на нее тензора и идём дальше, не блокируя основной поток программы (рис. 1). Когда результат понадобится, тогда его и спросим (проведем синхронизацию). Благодаря этому наш код ускоряется, так как пока тензора молотятся на GPU, мы можем заняться полезным на CPU или скинуть ещё данных на свободную часть GPU.
Если забыть про асинхронность, можно получать неправильные бенчмарки (рис. 2). При бенчмарках нас спасает
Также для бенчмарков можно пользоваться
Думаю, у каждого хоть раз вылетала такая ошибка:
Вычисления на карточке на самом деле проходят асинхронно. Мы "сбрасываем" на нее тензора и идём дальше, не блокируя основной поток программы (рис. 1). Когда результат понадобится, тогда его и спросим (проведем синхронизацию). Благодаря этому наш код ускоряется, так как пока тензора молотятся на GPU, мы можем заняться полезным на CPU или скинуть ещё данных на свободную часть GPU.
Если забыть про асинхронность, можно получать неправильные бенчмарки (рис. 2). При бенчмарках нас спасает
torch.cuda.synchronize() , который заблокирует основной поток до тех пор, пока операции на карточке не завершатся.Также для бенчмарков можно пользоваться
torch.utils.benchmark (рис. 3).Думаю, у каждого хоть раз вылетала такая ошибка:
CUDA error 59: Device-side assert triggered. Чаще всего она происходит, когда что-то напутали с шейпами. С кем не бывает 🙂 Обычно трейсбек этой ошибки показывает на строчку, которая не имеет отношения к реальной проблеме и в нём непонятно, что конкретно поломалось. Это как раз из-за асинхронности. В потоке программы мы уже убежали вперед, а ошибка от CUDA из прошлого нас догнала. Обычно при этой ошибке советуют перевести все вычисления на CPU, отдебагать, а потом опять перевести на GPU. Но если вам лень лезть в код/конфиг и что-то поправлять или вы сожалеете о каждой секунде жизни, которую у вас отняли вычисления на CPU, то есть простой хак. Запустите код с нужной переменной окружения: CUDA_LAUNCH_BLOCKING=1 python your_code.py. При ней все CUDA-вычисления станут синхронными, а ошибка трейсбека начнет указывать на нужную строчку кода 😉 Но эту переменную прокидываем только при дебаге! Принудительная синхронизация замедляет вычисления👍42🔥7❤4
Рубрика «Вопрос не с собеседования, но на подумать» 🤔
В обучении сеток часто работает правило Парето. На небольшом наборе данных сеть уже показывает результаты, которые сильно лучше рандома. Но чтобы пробить целевые метрики, мы должны добывать новую разметку снова и снова.
Для ускорения процесса разметки часто делают следующий трюк: текущей версией нейросети предсказывают новую пачку картинок, которую нужно разметить. Тогда при разметке нужно будет только поправлять за сеткой (рис. 1). Это сильно быстрее и дешевле.
Для разметки часто используют краудсорсинг-сервисы. В них большое количество людей за небольшое количество денег размечают ваши данные 🙂 В этих сервисах попадаются нечестные люди. От них вы получите мусор, а не разметку. Один из методов отлова таких обманщиков и отбора качественной разметки - проверка согласованности (рис. 2). Мы показываем одну и ту же картинку нескольким людям. Если разметка от кого-то из них явный выброс, мы ее не принимаем. Если от человека много таких выбросов, мы его баним.
Рассмотрим сетап с предразметкой. У разметчиков появляется отличная схема: можно вообще ничего не поправлять за нейросетью (рис. 3). Почти на всех картинках они будут отвечать правильно и при этом их ответы будут согласоваться. Для них это бесплатные (наши!) деньги. Но нас это "почти" не устраивает, мы воюем за каждый процент качества!
Какой механизм отсева обманщиков вы бы предложили? Кто хорошо знаком с крауд-сервисами — не подсказывайте 😉
В обучении сеток часто работает правило Парето. На небольшом наборе данных сеть уже показывает результаты, которые сильно лучше рандома. Но чтобы пробить целевые метрики, мы должны добывать новую разметку снова и снова.
Для ускорения процесса разметки часто делают следующий трюк: текущей версией нейросети предсказывают новую пачку картинок, которую нужно разметить. Тогда при разметке нужно будет только поправлять за сеткой (рис. 1). Это сильно быстрее и дешевле.
Для разметки часто используют краудсорсинг-сервисы. В них большое количество людей за небольшое количество денег размечают ваши данные 🙂 В этих сервисах попадаются нечестные люди. От них вы получите мусор, а не разметку. Один из методов отлова таких обманщиков и отбора качественной разметки - проверка согласованности (рис. 2). Мы показываем одну и ту же картинку нескольким людям. Если разметка от кого-то из них явный выброс, мы ее не принимаем. Если от человека много таких выбросов, мы его баним.
Рассмотрим сетап с предразметкой. У разметчиков появляется отличная схема: можно вообще ничего не поправлять за нейросетью (рис. 3). Почти на всех картинках они будут отвечать правильно и при этом их ответы будут согласоваться. Для них это бесплатные (наши!) деньги. Но нас это "почти" не устраивает, мы воюем за каждый процент качества!
Какой механизм отсева обманщиков вы бы предложили? Кто хорошо знаком с крауд-сервисами — не подсказывайте 😉
🤔18🔥12👍2
Ответ на вопрос 💼
Один из вариантов, который может прийти в голову: если на картинке (на пачке картинок) разметка не поменялась относительно предсказания сети — баним человека. Вариант даже рабочий, но не до конца🙂. Пусть вы отгрузили на крауд сто фотографий и на всех них ваша сеть была ну просто восхитительна. Люди честно за ней не исправляли, потому что зачем. Мы забанили кучу хороших людей. Плохо.
Так как поймать обманщика? Приманим его! (honeypot) Пусть мы хотим доразметить 100 картинок. Подмешаем к ним десять картинок, в которых специально сделаем разметку корявенькой (рис. 4). Если человек привык ничего не поправлять за сетью, то он обязательно попадется в нашу ловушку. Таких людей будем банить и ничего не будем им платить.
Ханипоты — это простой, мощный и почти бесплатный (а при проверке согласованности трёх разметчиков нам нужно заплатить трём разметчикам!) инструмент отлова недобросовестных исполнителей.
Уйдем от сетапа с предразметкой. Тогда можно ловить обманщиков на картинки, которые у нас хорошо размечены. Кто часто сильно мажет мимо эталона — бан.
За такими ханипотами нужно ухаживать. Если на каком-то ханипоте часто ошибаются — проверь, всё ли с ним хорошо. Мы могли накосячить и сделать плохую приманку. Либо мы могли изменить правила разметки, а приманку не поправили и она протухла.
Один из вариантов, который может прийти в голову: если на картинке (на пачке картинок) разметка не поменялась относительно предсказания сети — баним человека. Вариант даже рабочий, но не до конца🙂. Пусть вы отгрузили на крауд сто фотографий и на всех них ваша сеть была ну просто восхитительна. Люди честно за ней не исправляли, потому что зачем. Мы забанили кучу хороших людей. Плохо.
Так как поймать обманщика? Приманим его! (honeypot) Пусть мы хотим доразметить 100 картинок. Подмешаем к ним десять картинок, в которых специально сделаем разметку корявенькой (рис. 4). Если человек привык ничего не поправлять за сетью, то он обязательно попадется в нашу ловушку. Таких людей будем банить и ничего не будем им платить.
Ханипоты — это простой, мощный и почти бесплатный (а при проверке согласованности трёх разметчиков нам нужно заплатить трём разметчикам!) инструмент отлова недобросовестных исполнителей.
Уйдем от сетапа с предразметкой. Тогда можно ловить обманщиков на картинки, которые у нас хорошо размечены. Кто часто сильно мажет мимо эталона — бан.
За такими ханипотами нужно ухаживать. Если на каком-то ханипоте часто ошибаются — проверь, всё ли с ним хорошо. Мы могли накосячить и сделать плохую приманку. Либо мы могли изменить правила разметки, а приманку не поправили и она протухла.
👍33❤3
Как приручить GAN. Советы от Димы, куратора курса Ракета в CV
GAN'ы всё ещё доминируют в генеративных задачах, потому что ближайший конкурент в лице диффузионных моделей пока слишком медленный и на прод его не потащишь.
Кто такой GAN:
• Есть моделька генератор. Она берёт на вход некоторый вектор x. В векторе x может быть что угодно: случайный вектор, осмысленный эмбеддинг, картинка. А выплёвывает генератор на выходе некоторый вектор y. Обычно y — картинка, но может быть и каким-нибудь вектором.
• Есть моделька дискриминатор. Дискриминатор учится на классификацию и отделяет изображения из реального домена от изображений из генератора.
GAN по пунктикам (рис)
1. Генератор генерирует картинку;
2. Полученная картинка идёт в дискриминатор. Считается classification-loss
3. Генератор делает градиентный шаг так, чтобы обмануть дискриминатор. (сдвинуть предсказание дискриминатора в сторону ошибки);
4. Через дискриминатор прогоняется реальная картинка. Считается classification-loss;
5. Дискриминатор делает градиентный шаг, чтобы минимизировать сумму наших classification-loss. Так дискриминатор учится различать реальные и синтетические изображения;
6. Повторять пока не сойдётся.
Проблемки
Из-за этой жесткой конкурентной борьбы генератора и дискриминатор, GAN'ы очень тяжко сходятся. Чтобы ганы чаще добирались до прода, вот пачка советов.
Советики
• У меня на практике лучший лосс для GAN'ов это Least Square Gan (LSGAN). Мы просто берём логиты с дискриминатора (до сигмоиды) и тянем их по MSE к 1. Да, делаем классификацию через регрессию, и ганы от этого только лучше учатся. Сверху можно добавить ещё и Relativistic GAN;
• Дискриминатор может выдавать не одно число, а например сетку 7x7 как в PatchGAN. Благодаря этому выдается скор реалистичности не для всей картинки, а для регионов. Этот трюк почти всегда улучшает сходимость и качество сети. Можно взять гига-чада от мира дискриминаторов - UnetGAN, который выдаёт скор для каждого пикселя (в топовом RealESRGAN например так). Но там начинаются проблемы со стабильностью. Поэтому уважаемые ресёрчеры учили всё это с moving average 0.999 на веса модели;
• Стартовать с какого-нибудь простого претрейна лучше, чем учить GAN с нуля. Можно сначала предобучить генератор с L1-лоссом и получить мыльный результат, а затем дотюнивать вместе с дискриминатором.
• Вспомогательные лоссы вообще всегда помогают не разбежаться сетке. Только скор реалистичности далеко не всегда приведёт вас куда надо. Для картинок попробуйте использовать ContentLoss и L1 лосс в добавок. Это будет держать ваш GAN в рамках дозволенного;
• Не пытайтесь подбирать число шагов для генератора и дискриминатора. Сильно крутить learning rate, как правило, тоже бесполезно. Можно подобрать порядок, но не упарываться в десятых знаках после запятой. Все пытались и я пытался (ганы прунил, а оно потом не дотюнивалось), и вы будете пытаться. В обучении GANов ваш бро это ADAM, он сам со всем разберётся (почти);
• Батчнормы чаще всего зло, генерит артефакты;
• Прочитайте StyleGAN и StyleGANv2 там очень много трюков, их часто можно утянуть и к себе в пайплайн.
GAN'ы всё ещё доминируют в генеративных задачах, потому что ближайший конкурент в лице диффузионных моделей пока слишком медленный и на прод его не потащишь.
Кто такой GAN:
• Есть моделька генератор. Она берёт на вход некоторый вектор x. В векторе x может быть что угодно: случайный вектор, осмысленный эмбеддинг, картинка. А выплёвывает генератор на выходе некоторый вектор y. Обычно y — картинка, но может быть и каким-нибудь вектором.
• Есть моделька дискриминатор. Дискриминатор учится на классификацию и отделяет изображения из реального домена от изображений из генератора.
GAN по пунктикам (рис)
1. Генератор генерирует картинку;
2. Полученная картинка идёт в дискриминатор. Считается classification-loss
3. Генератор делает градиентный шаг так, чтобы обмануть дискриминатор. (сдвинуть предсказание дискриминатора в сторону ошибки);
4. Через дискриминатор прогоняется реальная картинка. Считается classification-loss;
5. Дискриминатор делает градиентный шаг, чтобы минимизировать сумму наших classification-loss. Так дискриминатор учится различать реальные и синтетические изображения;
6. Повторять пока не сойдётся.
Проблемки
Из-за этой жесткой конкурентной борьбы генератора и дискриминатор, GAN'ы очень тяжко сходятся. Чтобы ганы чаще добирались до прода, вот пачка советов.
Советики
• У меня на практике лучший лосс для GAN'ов это Least Square Gan (LSGAN). Мы просто берём логиты с дискриминатора (до сигмоиды) и тянем их по MSE к 1. Да, делаем классификацию через регрессию, и ганы от этого только лучше учатся. Сверху можно добавить ещё и Relativistic GAN;
• Дискриминатор может выдавать не одно число, а например сетку 7x7 как в PatchGAN. Благодаря этому выдается скор реалистичности не для всей картинки, а для регионов. Этот трюк почти всегда улучшает сходимость и качество сети. Можно взять гига-чада от мира дискриминаторов - UnetGAN, который выдаёт скор для каждого пикселя (в топовом RealESRGAN например так). Но там начинаются проблемы со стабильностью. Поэтому уважаемые ресёрчеры учили всё это с moving average 0.999 на веса модели;
• Стартовать с какого-нибудь простого претрейна лучше, чем учить GAN с нуля. Можно сначала предобучить генератор с L1-лоссом и получить мыльный результат, а затем дотюнивать вместе с дискриминатором.
• Вспомогательные лоссы вообще всегда помогают не разбежаться сетке. Только скор реалистичности далеко не всегда приведёт вас куда надо. Для картинок попробуйте использовать ContentLoss и L1 лосс в добавок. Это будет держать ваш GAN в рамках дозволенного;
• Не пытайтесь подбирать число шагов для генератора и дискриминатора. Сильно крутить learning rate, как правило, тоже бесполезно. Можно подобрать порядок, но не упарываться в десятых знаках после запятой. Все пытались и я пытался (ганы прунил, а оно потом не дотюнивалось), и вы будете пытаться. В обучении GANов ваш бро это ADAM, он сам со всем разберётся (почти);
• Батчнормы чаще всего зло, генерит артефакты;
• Прочитайте StyleGAN и StyleGANv2 там очень много трюков, их часто можно утянуть и к себе в пайплайн.
👍26❤3🔥1🤯1
Предыдущим постом навеяно
Задачка по математике на GAN'ы
(много букаф иностранных и символов, поэтому картинкой)
Задачка по математике на GAN'ы
(много букаф иностранных и символов, поэтому картинкой)
🤔13🤯3❤2🔥1
💡Решение задачки
Но к сожалению, такой трюк одно лечит, а другое калечит. Ловите хорошую обзорную статью, где про это есть подробнее🙂
Но к сожалению, такой трюк одно лечит, а другое калечит. Ловите хорошую обзорную статью, где про это есть подробнее🙂
🔥16🤔2❤1
Приходите к нам учиться!🤗
12 июля, во вторник, стартует летний поток нашего курса “Ракета в Computer Vision”. На нем вы научитесь решать полный стек задач в CV при поддержке опытных инженеров.
Полную программу вы найдете на сайте курса, но если коротко то вы научитесь:
- обучать сети под разные задачи, логируя и версионируя эксперименты;
- облегчать сети, ускорять их обучение и инференс;
- собирать дешевые и чистые данные на Толоке;
- разрабатывать сервисы;
- настраивать CI и автоматизировать деплой своих приложений;
- мониторить сервисы;
- и другое 🙂
Все вебинары проходят в zoom, поэтому вы всегда сможете задать вопрос по ходу лекции или задержаться в кулуарах со спикером. Почти все наши студенты — практики с разным бэкграундом и разным уровнем. А это значит, что вы сможете перенять опыт не только от кураторов курса, но и от коллег-студентов во время групповых заданий.
Курс длится 12 недель. Вас ждет 16 вебинаров, 2 семинара, 4 домашних задания с code-review на каждый merge request и приятная атмосфера 🙂
Оставляйте заявку на сайте, чтобы познакомиться с одним из кураторов лично и задать все ваши вопросы! До встречи🚀
12 июля, во вторник, стартует летний поток нашего курса “Ракета в Computer Vision”. На нем вы научитесь решать полный стек задач в CV при поддержке опытных инженеров.
Полную программу вы найдете на сайте курса, но если коротко то вы научитесь:
- обучать сети под разные задачи, логируя и версионируя эксперименты;
- облегчать сети, ускорять их обучение и инференс;
- собирать дешевые и чистые данные на Толоке;
- разрабатывать сервисы;
- настраивать CI и автоматизировать деплой своих приложений;
- мониторить сервисы;
- и другое 🙂
Все вебинары проходят в zoom, поэтому вы всегда сможете задать вопрос по ходу лекции или задержаться в кулуарах со спикером. Почти все наши студенты — практики с разным бэкграундом и разным уровнем. А это значит, что вы сможете перенять опыт не только от кураторов курса, но и от коллег-студентов во время групповых заданий.
Курс длится 12 недель. Вас ждет 16 вебинаров, 2 семинара, 4 домашних задания с code-review на каждый merge request и приятная атмосфера 🙂
Оставляйте заявку на сайте, чтобы познакомиться с одним из кураторов лично и задать все ваши вопросы! До встречи🚀
🔥17