Не забываем корни, напоминаем про батчнорм 😉
Батч нормализация — неотъемлимая часть 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
Синтетические данные и OCR
Наверное вы слышали, что синтетика далеко не всегда хороший помощник. Но только не в задаче Optical Character Recognition (распознавание текста). Тут синтетика может сильно помочь.
Кейс из жизни: можно безошибочно распознавать (strmatch) 83% полей на паспортах СНГ с помощью сети, обученной только на синтетике.
В задаче OCR делайте этап предобучения на синтетике, а затем дообучайте на реальных данных. Результат вас обрадует 🙂
Напомним, как решают задачу распознавания текста (рис. 1)
0) на вход сети подают картинку со строкой или словом;
1) картинку делят по горизонтали на N частей;
2) классифицируют каждую часть, включая класс «пустота»;
3) результаты классификации схлопывают и получают предсказанный текст.
Как заполучить синтетику
Для генерации выборки нам надо научиться создавать картинки с текстом. В этом нам поможет библиотека PIL. С помощью PIL.ImageFont можно загрузить нужный шрифт и нанести текст поверх любого изображения (рис. 2). Но для лучшего результата надо постараться максимально приблизить домен сгенерированных данных к реальному.
Несколько лайфхаков, которые помогут это сделать:
1️⃣ Накладывайте текст на реальный фон. Например, разметьте прямоугольники с фоном на боевых картинках в сервисе для разметки (CVAT/LabelStudio/LabelBox/etc). А затем вырежьте прямоугольники с фоном по разметке и используйте как подложку для текста. (рис. 3) Заметим, что на этапе предобучения на синтетике совершенно не обязательно генерировать осмысленные слова. Здесь мы просто учим сеть отличать одни символы от других.
2️⃣ Сгенерируйте цветной прямоугольник (заливку), а с помощью PIL.ImafeFont «маску» с текстом, по которой будете переводить символы с цветного прямоугольника на ваш фон. Регулируя интенсивность «маски», вы сможете наносить полупрозрачный текст. А деформируя маску с помощью аугментаций, можно получить интересные преобразования. Например, комбинируя cutout и блюр, можно получить эффект потертого текста (рис. 4).
3️⃣ Наносите не весь текст целиком, а каждый символ по-отдельности. Варьируйте расстояние между символами, угол поворота, размер, смещение вдоль вертикали — это поможет получить более робастную модель.
4️⃣ Даже если у вас много настоящих картинок, может все равно встречаться сильный дисбаланс в символах. Например, твердый знак «Ъ» может встречаться очень редко, из-за чего сеть будет часто его путать с мягким «Ь». В таком случае докиньте в train синтетику слов с твердым знаком. Это поможет нивелировать дисбаланс, и сетка начнет лучше отличать «Ъ» от «Ь»👍🏻
5️⃣ Можно пойти еще дальше и генерировать кропы при помощи GAN. Например, обучить CycleGAN транслировать картинки между синтетическим доменом и реальным. А затем для синтеза кропов оставить только генератор “синтетика → реальные” (рис. 5).
Наверное вы слышали, что синтетика далеко не всегда хороший помощник. Но только не в задаче Optical Character Recognition (распознавание текста). Тут синтетика может сильно помочь.
Кейс из жизни: можно безошибочно распознавать (strmatch) 83% полей на паспортах СНГ с помощью сети, обученной только на синтетике.
В задаче OCR делайте этап предобучения на синтетике, а затем дообучайте на реальных данных. Результат вас обрадует 🙂
Напомним, как решают задачу распознавания текста (рис. 1)
0) на вход сети подают картинку со строкой или словом;
1) картинку делят по горизонтали на N частей;
2) классифицируют каждую часть, включая класс «пустота»;
3) результаты классификации схлопывают и получают предсказанный текст.
Как заполучить синтетику
Для генерации выборки нам надо научиться создавать картинки с текстом. В этом нам поможет библиотека PIL. С помощью PIL.ImageFont можно загрузить нужный шрифт и нанести текст поверх любого изображения (рис. 2). Но для лучшего результата надо постараться максимально приблизить домен сгенерированных данных к реальному.
Несколько лайфхаков, которые помогут это сделать:
1️⃣ Накладывайте текст на реальный фон. Например, разметьте прямоугольники с фоном на боевых картинках в сервисе для разметки (CVAT/LabelStudio/LabelBox/etc). А затем вырежьте прямоугольники с фоном по разметке и используйте как подложку для текста. (рис. 3) Заметим, что на этапе предобучения на синтетике совершенно не обязательно генерировать осмысленные слова. Здесь мы просто учим сеть отличать одни символы от других.
2️⃣ Сгенерируйте цветной прямоугольник (заливку), а с помощью PIL.ImafeFont «маску» с текстом, по которой будете переводить символы с цветного прямоугольника на ваш фон. Регулируя интенсивность «маски», вы сможете наносить полупрозрачный текст. А деформируя маску с помощью аугментаций, можно получить интересные преобразования. Например, комбинируя cutout и блюр, можно получить эффект потертого текста (рис. 4).
3️⃣ Наносите не весь текст целиком, а каждый символ по-отдельности. Варьируйте расстояние между символами, угол поворота, размер, смещение вдоль вертикали — это поможет получить более робастную модель.
4️⃣ Даже если у вас много настоящих картинок, может все равно встречаться сильный дисбаланс в символах. Например, твердый знак «Ъ» может встречаться очень редко, из-за чего сеть будет часто его путать с мягким «Ь». В таком случае докиньте в train синтетику слов с твердым знаком. Это поможет нивелировать дисбаланс, и сетка начнет лучше отличать «Ъ» от «Ь»👍🏻
5️⃣ Можно пойти еще дальше и генерировать кропы при помощи GAN. Например, обучить CycleGAN транслировать картинки между синтетическим доменом и реальным. А затем для синтеза кропов оставить только генератор “синтетика → реальные” (рис. 5).
🔥26👍8🐳2❤1
После запуска летнего потока курса немного выбились из колеи генерации постов)
Возвращаемся в строй💪🏻
Прервем молчание ответом на популярный вопрос👇🏻
Возвращаемся в строй💪🏻
Прервем молчание ответом на популярный вопрос👇🏻
🔥13👍1
Какую архитектуру взять в качестве бейзлайна и что докинуть в свою?
Вдохновимся статьёй из OpenAI и посмотрим какую сетку они используют в качестве feature extractor для картиночек. А там ResNet из статьи Bag Of Tricks и какой-то antialiased rect-2 blur pooling. Кто такие и почему?
• ResNet Bag Of Tricks это такая сборная статья в которой проверили и попробовали кучу всяких советов\триков\твиков\мудростей накопившихся для свёрточных сетей и соединили всё в одну модель ResNet-D (рис. 1). Статья выступает в роли такого бывалого коллеги сеньёра, который накидывает вам “А вот ты у батчнормов, которые в конце блока, гамму в ноль поставь, тогда у тебя сетка круто по началу сходится начнёт”. В ней подробно описано как учить, что менять в +- современном мире (конечно у нас уже трансформеры, потом собрали ConvNeXt, но Bag Of Tricks всё ещё актуален). Удобно это тем что можно кусочками к себе в пайплайн тянуть всякие улучшения, и не пересобирать всё своё решение.
• Антиалиасинг в нейронных сетях. Сетки которые мы используем не инварианты к сдвигу. Вот так вот, придумали свёртки с учётом, что они инвариантны к сдвигу, а сети у нас совсем не инварианты. Всё из-за коварного пулинга, который как и при обычном сжатии картинок даёт эффект алиасинга. Нам бы очень хотелось сгладить этот эффект, особенно это хочется сделать после того как мы посмотрим на графики зависимости score от сдвига (рис. 2). Решается это проблема обычным размытием перед пулингом.
Основное в ResNet Bag Of Tricks.
• Как скейлить learning rate, какой взять scheduler, кто такой warmup, какой батч сайз взять и прочие training strategy.
• Польза обучения в FP16 на современных видеокартах.
• Что поменять в дефолтной архитектуре ResNet чтобы стало лучше, на что заменить первые свёртки, как поменять Residual Block.
• Какие ауги зашли на ImageNet и у вас наверное сработают.
Это не статья откровение, возможно многое вы уже слышали или даже использовали, но когда всё в одном месте с красивыми табличками и подробно описано, то жить сразу как-то приятнее.
Основное в Making Convolutional Networks Shift-Invariant Again.
Всё что нужно сделать, это из официального репозитория достать реализацию BlurPool и по гайду вставить в свою сеть (рис. 3). В репозитории есть функции, которые это делают за вас, но надёжней просто в своём коде поменять, чтобы вы наверняка знали что у вас поменялось. А самое классное в том что сеть не надо учить заново, она не сильно изменится и можно со спокойной душой дотюнивать со своего претрейна.
#советы #nn #training
Вдохновимся статьёй из OpenAI и посмотрим какую сетку они используют в качестве feature extractor для картиночек. А там ResNet из статьи Bag Of Tricks и какой-то antialiased rect-2 blur pooling. Кто такие и почему?
• ResNet Bag Of Tricks это такая сборная статья в которой проверили и попробовали кучу всяких советов\триков\твиков\мудростей накопившихся для свёрточных сетей и соединили всё в одну модель ResNet-D (рис. 1). Статья выступает в роли такого бывалого коллеги сеньёра, который накидывает вам “А вот ты у батчнормов, которые в конце блока, гамму в ноль поставь, тогда у тебя сетка круто по началу сходится начнёт”. В ней подробно описано как учить, что менять в +- современном мире (конечно у нас уже трансформеры, потом собрали ConvNeXt, но Bag Of Tricks всё ещё актуален). Удобно это тем что можно кусочками к себе в пайплайн тянуть всякие улучшения, и не пересобирать всё своё решение.
• Антиалиасинг в нейронных сетях. Сетки которые мы используем не инварианты к сдвигу. Вот так вот, придумали свёртки с учётом, что они инвариантны к сдвигу, а сети у нас совсем не инварианты. Всё из-за коварного пулинга, который как и при обычном сжатии картинок даёт эффект алиасинга. Нам бы очень хотелось сгладить этот эффект, особенно это хочется сделать после того как мы посмотрим на графики зависимости score от сдвига (рис. 2). Решается это проблема обычным размытием перед пулингом.
Основное в ResNet Bag Of Tricks.
• Как скейлить learning rate, какой взять scheduler, кто такой warmup, какой батч сайз взять и прочие training strategy.
• Польза обучения в FP16 на современных видеокартах.
• Что поменять в дефолтной архитектуре ResNet чтобы стало лучше, на что заменить первые свёртки, как поменять Residual Block.
• Какие ауги зашли на ImageNet и у вас наверное сработают.
Это не статья откровение, возможно многое вы уже слышали или даже использовали, но когда всё в одном месте с красивыми табличками и подробно описано, то жить сразу как-то приятнее.
Основное в Making Convolutional Networks Shift-Invariant Again.
Всё что нужно сделать, это из официального репозитория достать реализацию BlurPool и по гайду вставить в свою сеть (рис. 3). В репозитории есть функции, которые это делают за вас, но надёжней просто в своём коде поменять, чтобы вы наверняка знали что у вас поменялось. А самое классное в том что сеть не надо учить заново, она не сильно изменится и можно со спокойной душой дотюнивать со своего претрейна.
#советы #nn #training
🔥35👍4❤1
Красивая картинка как Bag Of Tricks доминирует другие архитектуры в своё время.
Кстати, если хотите пост с более подробным разбором трюков из статьи Bag Of Tricks, нажмите китенка в реакции🐳 Если соберем 17 китят, подготовим отдельный пост 🙂
Кстати, если хотите пост с более подробным разбором трюков из статьи Bag Of Tricks, нажмите китенка в реакции🐳 Если соберем 17 китят, подготовим отдельный пост 🙂
🐳115🤔3