Приходите к нам учиться!🤗
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 и приятная атмосфера 🙂
Оставляйте заявку на сайте, чтобы познакомиться с одним из кураторов лично и задать все ваши вопросы! До встречи🚀
Синтетические данные и 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).
После запуска летнего потока курса немного выбились из колеи генерации постов)
Возвращаемся в строй💪🏻
Прервем молчание ответом на популярный вопрос👇🏻
Возвращаемся в строй💪🏻
Прервем молчание ответом на популярный вопрос👇🏻
Какую архитектуру взять в качестве бейзлайна и что докинуть в свою?
Вдохновимся статьёй из 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
Красивая картинка как Bag Of Tricks доминирует другие архитектуры в своё время.
Кстати, если хотите пост с более подробным разбором трюков из статьи Bag Of Tricks, нажмите китенка в реакции🐳 Если соберем 17 китят, подготовим отдельный пост 🙂
Кстати, если хотите пост с более подробным разбором трюков из статьи Bag Of Tricks, нажмите китенка в реакции🐳 Если соберем 17 китят, подготовим отдельный пост 🙂
По количеству китов поняли, что тема интересна, поэтому не будем откладывать до будних дней! Спасибо всем за ваши реакции! Ниже более подробный разбор статьи, как и обещали👇
Разбираем статью Bag of Tricks for Image Classification with Convolutional Neural Network
В какой-то момент разработки модели начинаются упражнения с тем, чтобы слегка поднять метрики до целевых. Один из любимых методов уважаемых дип лёрнинг ресёрчеров это вставлять разные модные и не очень штуки в свой пайплайн, чтобы в один момент что-то из этого хорошо так накинуло. И потом можно было гордо ходить по офису\конференциям и рассказывать как удалось внести важный вклад в свой продукт.
Классный способ набираться подобных трюков и знаний — это читать обзорные статьи, где за вас уже проверили и актуализировали много подходов. Bag Of Tricks — как раз одна из таких работ. Несмотря на то что в названии статьи указано “Image Classification” и авторы изначально экспериментировали с ResNet-50, перечисленные трюки помогают также в других задачах и с другими архитектурами. В конце статьи авторы также указали результаты успешных экспериментов на задачах детекции и сегментации (рис. 0).
Основная идея всей работы — авторы собрали в большую пачку кучу триков\твиков\уловок которые накопились в комьюнити, проверили их эффективность и подняли точность резнета на ImageNet с 75% до 79%.
Последуем примеру авторов и разобьем советы на 3 части:
- Train Stratedy
- Model Tweaks
- Training Tricks
Сегодня опубликуем первые две, а завтра третью, чтобы не высыпать слишком много букав за один раз)
И так, погнали👇
В какой-то момент разработки модели начинаются упражнения с тем, чтобы слегка поднять метрики до целевых. Один из любимых методов уважаемых дип лёрнинг ресёрчеров это вставлять разные модные и не очень штуки в свой пайплайн, чтобы в один момент что-то из этого хорошо так накинуло. И потом можно было гордо ходить по офису\конференциям и рассказывать как удалось внести важный вклад в свой продукт.
Классный способ набираться подобных трюков и знаний — это читать обзорные статьи, где за вас уже проверили и актуализировали много подходов. Bag Of Tricks — как раз одна из таких работ. Несмотря на то что в названии статьи указано “Image Classification” и авторы изначально экспериментировали с ResNet-50, перечисленные трюки помогают также в других задачах и с другими архитектурами. В конце статьи авторы также указали результаты успешных экспериментов на задачах детекции и сегментации (рис. 0).
Основная идея всей работы — авторы собрали в большую пачку кучу триков\твиков\уловок которые накопились в комьюнити, проверили их эффективность и подняли точность резнета на ImageNet с 75% до 79%.
Последуем примеру авторов и разобьем советы на 3 части:
- Train Stratedy
- Model Tweaks
- Training Tricks
Сегодня опубликуем первые две, а завтра третью, чтобы не высыпать слишком много букав за один раз)
И так, погнали👇
Train Strategy
1. Линейный скейлинг learning rate.
Эмпирически заметили, что с ростом batchsize модель начинает сходиться медленнее. Если мы просто увеличим batchsize, то за тоже количество эпох модель сойдётся хуже. Что в целом логично, при увеличении batchsize уменьшается итоговое число шагов, при этом математическое ожидание стохастического градиента (т.е. оценка градиента для модели на каком-то батче) не изменится, уменьшится лишь дисперсия. Для решения этой проблемы просто увеличивают градиент во столько раз, во сколько изменили размер батча. Например, авторы предлагают брать такую формулу 0.1 * (batchsize / 256), считаем что для batchsize 256 оптимальный lr будет 0.1. Похожий трюк следует применять и при обучении на нескольких GPU: используете 8 GPU — увеличивайте lr в 8 раз (ведь батч стал больше в 8 раз).
2. Learning rate warmup.
В начале обучения сеть ещё очень далека от финального решения и слишком большой lr может привести к нестабильности. Авторы предлагают в начале обучения стартовать с нулевого lr и постепенно линейно от батча к батчу увеличивать lr на протяжении, например, 5 эпох. То есть на 5-ой эпохе уже будет ваш выбранный lr. Для оптимизатора Adam это особенно важно. Он капризный в начале обучения, потому что статистики ещё не стабилизовались. А трансформеры вообще отказываются сходиться без warmup.
3. Инициализировать гамму батчнорма нулём.
Блок Resnet можно представить как x + block(x). И после каждого слоя свёртки у нас идёт слой батчнорма. Если в конце каждого block мы будем инициализировать обучаемый параметр gamma нулём (который скейлит распределение после нормализации), то каждый блок в ResNet будет просто возвращать свой вход. Таким образом, в начале обучения сеть будет вести себя так, будто у неё намного меньше параметров. А это благоприятно влияет на сходимость во время первых эпох.
4. Не использовать регуляризацию для баесов.
Использование регуляризации позволяет бороться с оверфитом, но регуляризация нужна только для весов. Для баесов, обучаемых beta и gamma в батчнорме регуляризации не нужны и ухудшают метрики.
5. Обучение сети во float16.
Современные GPU намного шустрее во float16. Например, Tesla V100 в fp32 выдаёт 14 TFLOPS, а в fp16 больше 100 TFLOPS. Главное помнить, что fp16 сильно экономит на битах в экспоненте, что сильно влияет на ошибку вблизи нуля. Предлагается хранить и применять обновления к весам во float32, а делать forward pass и считать градиенты во float16. Также советуют скелить лосс, чтобы не так страдать от проблем рядом с нулём. В pytorch есть отличный гайд для этого. А ещё придумали bfloat16, у которого экономят на битах не в экспоненте, а в мантисе — там нужно значительно меньше упражнений, но не все GPU поддерживают данный формат.
6. Cosine Learning Rate Decay.
Вместо того чтобы ступеньками уменьшать LR в процессе обучения, или экспоненциально вниз, авторы предлагают использовать Cosine Annealing.
Результаты экспериментов указаны на рис. 1
1. Линейный скейлинг learning rate.
Эмпирически заметили, что с ростом batchsize модель начинает сходиться медленнее. Если мы просто увеличим batchsize, то за тоже количество эпох модель сойдётся хуже. Что в целом логично, при увеличении batchsize уменьшается итоговое число шагов, при этом математическое ожидание стохастического градиента (т.е. оценка градиента для модели на каком-то батче) не изменится, уменьшится лишь дисперсия. Для решения этой проблемы просто увеличивают градиент во столько раз, во сколько изменили размер батча. Например, авторы предлагают брать такую формулу 0.1 * (batchsize / 256), считаем что для batchsize 256 оптимальный lr будет 0.1. Похожий трюк следует применять и при обучении на нескольких GPU: используете 8 GPU — увеличивайте lr в 8 раз (ведь батч стал больше в 8 раз).
2. Learning rate warmup.
В начале обучения сеть ещё очень далека от финального решения и слишком большой lr может привести к нестабильности. Авторы предлагают в начале обучения стартовать с нулевого lr и постепенно линейно от батча к батчу увеличивать lr на протяжении, например, 5 эпох. То есть на 5-ой эпохе уже будет ваш выбранный lr. Для оптимизатора Adam это особенно важно. Он капризный в начале обучения, потому что статистики ещё не стабилизовались. А трансформеры вообще отказываются сходиться без warmup.
3. Инициализировать гамму батчнорма нулём.
Блок Resnet можно представить как x + block(x). И после каждого слоя свёртки у нас идёт слой батчнорма. Если в конце каждого block мы будем инициализировать обучаемый параметр gamma нулём (который скейлит распределение после нормализации), то каждый блок в ResNet будет просто возвращать свой вход. Таким образом, в начале обучения сеть будет вести себя так, будто у неё намного меньше параметров. А это благоприятно влияет на сходимость во время первых эпох.
4. Не использовать регуляризацию для баесов.
Использование регуляризации позволяет бороться с оверфитом, но регуляризация нужна только для весов. Для баесов, обучаемых beta и gamma в батчнорме регуляризации не нужны и ухудшают метрики.
5. Обучение сети во float16.
Современные GPU намного шустрее во float16. Например, Tesla V100 в fp32 выдаёт 14 TFLOPS, а в fp16 больше 100 TFLOPS. Главное помнить, что fp16 сильно экономит на битах в экспоненте, что сильно влияет на ошибку вблизи нуля. Предлагается хранить и применять обновления к весам во float32, а делать forward pass и считать градиенты во float16. Также советуют скелить лосс, чтобы не так страдать от проблем рядом с нулём. В pytorch есть отличный гайд для этого. А ещё придумали bfloat16, у которого экономят на битах не в экспоненте, а в мантисе — там нужно значительно меньше упражнений, но не все GPU поддерживают данный формат.
6. Cosine Learning Rate Decay.
Вместо того чтобы ступеньками уменьшать LR в процессе обучения, или экспоненциально вниз, авторы предлагают использовать Cosine Annealing.
Результаты экспериментов указаны на рис. 1
Model Tweaks
За основу авторы взяли “самую популярную реализацию ResNet-50” (рис. 2, слева). И ссылаются на две статьи, в которых были внесены правки в эту архитектуру. Первую правку они обозначили как ResNet-B, вторую ResNet-C. И, вдохновившись этими идеями, протестировали еще одно изменение прямо в своей статье, обозначив новую архитектуру как ResNet-D (рис. 2).
ResNet-B — Передвинем stride=2 из первой свёртки блока во вторую, потому что из-за этого stride мы отбрасываем 3/4 входящей информации. Помним, что ядро шагает и по вертикали, и по горизонтали. И если мы применяем ядро 1х1, шагая через пиксель, то для фичи со spatial size 4х4 свернем лишь 4 пикселя.
ResNet-C — Заменяем первую свёртку 7х7, на 3 свёртки 3х3, у первой будет stride=2. Это будет только чуть-чуть дороже, зато неплохо добавит к точности и мощности сети.
ResNet-D — на скипах из-за свёртки 1х1 опять теряется 3/4 информации, уберём из свёртки stride=2 и перед ней добавим average pool (практическим путем выявили, что это докидывает).
За основу авторы взяли “самую популярную реализацию ResNet-50” (рис. 2, слева). И ссылаются на две статьи, в которых были внесены правки в эту архитектуру. Первую правку они обозначили как ResNet-B, вторую ResNet-C. И, вдохновившись этими идеями, протестировали еще одно изменение прямо в своей статье, обозначив новую архитектуру как ResNet-D (рис. 2).
ResNet-B — Передвинем stride=2 из первой свёртки блока во вторую, потому что из-за этого stride мы отбрасываем 3/4 входящей информации. Помним, что ядро шагает и по вертикали, и по горизонтали. И если мы применяем ядро 1х1, шагая через пиксель, то для фичи со spatial size 4х4 свернем лишь 4 пикселя.
ResNet-C — Заменяем первую свёртку 7х7, на 3 свёртки 3х3, у первой будет stride=2. Это будет только чуть-чуть дороже, зато неплохо добавит к точности и мощности сети.
ResNet-D — на скипах из-за свёртки 1х1 опять теряется 3/4 информации, уберём из свёртки stride=2 и перед ней добавим average pool (практическим путем выявили, что это докидывает).
Training Tricks
И последняя часть советов из статьи Bag Of Tricks
1. Label Smoothing.
В классическом Cross Entropy Loss оптимальным значением логита (то что до софтмакса) будет inf, что приводит к очень сильному разрыву для top1 логита, что может легко привести к оверфиту. Авторы предлагают использовать label smoothing. Проще говоря, вместо того чтобы тянуть верный лейбл к 1, мы будем тянуть его к 0.9 (оставшийся ε = 0.1 скор равномерно распределим по остальным К классам) (рис. 3)
В результате на валидации наш gap (расстояние между top1 и top2) будет сконцентрирован вокруг теоретического оптимума (рис. 4) и будет значительно меньше случаев с overconfidence. При ε = 0.1 и К = 1000, этот теоретичиский оптимум будет равен 9.1, который считается по формуле на рис. 5.
2. Knowledge Distillation.
Выучим предварительно большую сеть которая будет выдавать крутые метрики, а потом используем её в качестве сети учителя при обучении нашей сетки поменьше. В процессе обучения “ученика” будем также тянуть его выходы к выходам учителя, передавая таким образом Dark Knoweledge — скрытые распределения в датасете, которые выучила большая сетка.
Итоговая функция потерь будет выглядеть вот так (рис. 6). Параметр T — параметр температуры, который позволяет сгладить распределения ученика и учителя при дистилляции. Такой трюк помогает ученику больше внимания обращать на top2 и top3 классы и лучше обучаться на dark knoweledge.
3. Mixup Training.
Интересная ауга, которая предлагает вам линейно сблендить два изображения и учиться на этом новом изображении (рис. 7). Усредняем 2 картинки и усредняем их GT лейблы. Накидывает практически 1 процент на imagenet, крутота.
Результаты экспериментов указаны на рис. 8
И последняя часть советов из статьи Bag Of Tricks
1. Label Smoothing.
В классическом Cross Entropy Loss оптимальным значением логита (то что до софтмакса) будет inf, что приводит к очень сильному разрыву для top1 логита, что может легко привести к оверфиту. Авторы предлагают использовать label smoothing. Проще говоря, вместо того чтобы тянуть верный лейбл к 1, мы будем тянуть его к 0.9 (оставшийся ε = 0.1 скор равномерно распределим по остальным К классам) (рис. 3)
В результате на валидации наш gap (расстояние между top1 и top2) будет сконцентрирован вокруг теоретического оптимума (рис. 4) и будет значительно меньше случаев с overconfidence. При ε = 0.1 и К = 1000, этот теоретичиский оптимум будет равен 9.1, который считается по формуле на рис. 5.
2. Knowledge Distillation.
Выучим предварительно большую сеть которая будет выдавать крутые метрики, а потом используем её в качестве сети учителя при обучении нашей сетки поменьше. В процессе обучения “ученика” будем также тянуть его выходы к выходам учителя, передавая таким образом Dark Knoweledge — скрытые распределения в датасете, которые выучила большая сетка.
Итоговая функция потерь будет выглядеть вот так (рис. 6). Параметр T — параметр температуры, который позволяет сгладить распределения ученика и учителя при дистилляции. Такой трюк помогает ученику больше внимания обращать на top2 и top3 классы и лучше обучаться на dark knoweledge.
3. Mixup Training.
Интересная ауга, которая предлагает вам линейно сблендить два изображения и учиться на этом новом изображении (рис. 7). Усредняем 2 картинки и усредняем их GT лейблы. Накидывает практически 1 процент на imagenet, крутота.
Результаты экспериментов указаны на рис. 8
Давно хотели завести рубрику “повторяем теорию”🤓 И кажется, что вторник отлично для нее подходит😉 Ранее мы вспоминали Batch Normalization, поэтому сперва закончим с нормализацией в рамках новой рубрики, а после пойдем дальше.
В этот раз для удобства написали пост в формате статьи в телеграфе: там можно вставлять картиночки между текстом, а на телефоне меньше скроллить и оставаться в приложении телеграма.
Если вы хотите вспомнить, какие проблемы есть у батчнорма, и какие “аналоги” были призваны их решить: Layer Norm, Instance Norm и Group Norm — то читайте нашу статью в телеграфе 🙂
#повторяем_теорию #нормализация
В этот раз для удобства написали пост в формате статьи в телеграфе: там можно вставлять картиночки между текстом, а на телефоне меньше скроллить и оставаться в приложении телеграма.
Если вы хотите вспомнить, какие проблемы есть у батчнорма, и какие “аналоги” были призваны их решить: Layer Norm, Instance Norm и Group Norm — то читайте нашу статью в телеграфе 🙂
#повторяем_теорию #нормализация
Записали для вас видео про ускорение инференса! 🚀
В нем Дима Чудаков рассказал как быстро и дешево ускорить инференс ваших сетей при помощи фьюзинга и дистилляции, а также оставил несколько советов по их применению.
Это наш дебют на ютубе! Будем рады поддержке) Подписывайтесь и ставьте лайки если вам понравилось видео в подобном формате👍
Переходите по ссылке, чтобы посмотреть: https://youtu.be/6UJn0J1Sul4
В нем Дима Чудаков рассказал как быстро и дешево ускорить инференс ваших сетей при помощи фьюзинга и дистилляции, а также оставил несколько советов по их применению.
Это наш дебют на ютубе! Будем рады поддержке) Подписывайтесь и ставьте лайки если вам понравилось видео в подобном формате👍
Переходите по ссылке, чтобы посмотреть: https://youtu.be/6UJn0J1Sul4
YouTube
Ускорение инференса: фьюзинг и дистилляция
При высокой нагрузке или вычислениях на смартфонах, скорость работы сети становится критической метрикой.
В данном видео Дима Чудаков, куратор курса "Ракета в Computer Vision", расскажет как можно ускорить вашу нейросеть за несколько простых действий с помощью…
В данном видео Дима Чудаков, куратор курса "Ракета в Computer Vision", расскажет как можно ускорить вашу нейросеть за несколько простых действий с помощью…
Сегодня вторник, а значит в эфире рубрика “повторяем теорию”🤓
Вспомним про регуляризацию сетей, а именно про три популярных метода: L1, L2 и Dropout (ведь был популярен когда-то, надо отдать дань старичку). Статья в телеграфе 👉 Регуляризуем правильно!
#регуляризация #L1 #L2 #dropout
Вспомним про регуляризацию сетей, а именно про три популярных метода: L1, L2 и Dropout (ведь был популярен когда-то, надо отдать дань старичку). Статья в телеграфе 👉 Регуляризуем правильно!
#регуляризация #L1 #L2 #dropout
Telegraph
Регуляризуем правильно!
Под термином регуляризация понимают набор различных методов для борьбы с переобучением и улучшением робастности модели. В нейронных сетях эти методы можно разделить на три группы, которые изменяют: функцию потерь; структуру сети; входные данные (различные…
После двух статей в телеграфе интересно узнать: в каком виде вам удобнее читать посты?
Anonymous Poll
76%
В виде телеграф-статей
24%
В виде сообщений в группе
Хотели рассказать вам про Efficient Net, потому что многие путаются в этой архитектуре и не до конца понимают причем тут “efficient” то вообще) Взяли на себя ответственность поставить точку в этом вопросе. Чтобы в следующий раз, когда вас спросят что это за EffNet такой, вы без проблем могли ответить.
Изучать архитектуры — полезно. Эти знания позволят вам правильно подобрать сеть под ваши задачи и ограничения, а иногда даже помогут пропатчить какую-нибудь китайскую сетку, чтобы потом сконвертить ее в TRT))
Но рассказывая про EffNet, нельзя не упомянуть MBConv блоки из MobileNet. Объясняя Inverted Residual хорошо бы рассказать про обычный Residual и так далее. Поэтому логичнее уже пройтись по всей истории эволюции и начать с VGG😅
Вот и начали… Представляем вашему вниманию первую статью из серии “вспоминаем архитектуры”: разбираем VGG. Давайте вместе пройдемся по истории и вспомним/изучим/дополним_наши_знания: https://telegra.ph/VGG-10-10
Изучать архитектуры — полезно. Эти знания позволят вам правильно подобрать сеть под ваши задачи и ограничения, а иногда даже помогут пропатчить какую-нибудь китайскую сетку, чтобы потом сконвертить ее в TRT))
Но рассказывая про EffNet, нельзя не упомянуть MBConv блоки из MobileNet. Объясняя Inverted Residual хорошо бы рассказать про обычный Residual и так далее. Поэтому логичнее уже пройтись по всей истории эволюции и начать с VGG😅
Вот и начали… Представляем вашему вниманию первую статью из серии “вспоминаем архитектуры”: разбираем VGG. Давайте вместе пройдемся по истории и вспомним/изучим/дополним_наши_знания: https://telegra.ph/VGG-10-10
Telegraph
VGG
Архитектура VGG-16 и 19 — детище Visual Geometry Group — академической группы Оксфордского университета. При создании своей архитектуры, авторы учли опыт Нью-Йоркских коллег и стали использовать меньший размер свёртки (3х3) и меньший шаг (stride=1) на первом…
Вы когда-нибудь путались в функциях потерь для классификации? BCE, log-loss, Cross Entropy, Focal Loss — одно является частным случаем другого, третье выражается через четвертое, еще и в разных статьях свапают названия между собой)
Если хотите вспомнить кто есть кто, то мы подготовили для вас статью Функции потерь для классификации.
В ней мы также напомним:
- кто такой Brier Score;
- когда в задаче классификации может сработать MSE;
- что можно сделать с функцией потерь при дисбалансе классов;
- да, в прошлом пункте нет интриги, можно взвесить классы — но что если в минорном классе есть простые примеры, которые сеть учит легко и быстро, а в мажорном сложные? В чем тут может быть проблема и как ее решить?
В общем, есть что вспомнить, давайте закрепим знания вместе: https://telegra.ph/Funkcii-poter-dlya-klassifikacii-10-12
Если хотите вспомнить кто есть кто, то мы подготовили для вас статью Функции потерь для классификации.
В ней мы также напомним:
- кто такой Brier Score;
- когда в задаче классификации может сработать MSE;
- что можно сделать с функцией потерь при дисбалансе классов;
- да, в прошлом пункте нет интриги, можно взвесить классы — но что если в минорном классе есть простые примеры, которые сеть учит легко и быстро, а в мажорном сложные? В чем тут может быть проблема и как ее решить?
В общем, есть что вспомнить, давайте закрепим знания вместе: https://telegra.ph/Funkcii-poter-dlya-klassifikacii-10-12
Telegraph
Функции потерь для классификации
Автор: Александр Лекомцев Функция потерь — это численное выражение ошибки модели. Поскольку современные нейросети обучаются методом обратного распространения, эта функция должна быть дифференцируема. Из-за требования к дифференцируемости нам не подходят accuracy…
Рубрика «Вопрос с собеседования»💼
У вас есть сетка, которая умеет на спутниковом снимке находить маски домиков. Затем эти маски нужно превратить в полигоны домиков.
Вряд ли ваша сетка умеет сегментировать pixel-perfect. Поэтому получится полигон как на картинке (b). У этого полигона слишком много вершин и такой рваный домик на карту не поставишь. Поэтому будем постпроцессить такой полигон. Нам нужно, чтобы было поменьше вершин и побольше прямых углов и параллельных сторон. Получим приятный полигон как на картинке (c).
На одной картинке могут быть сотни таких полигонов. Поэтому постпроцессинг может стать боттлнеком вашей системы.
Вопрос
Пусть в среднем нейросеть предсказывает маску за 100мс, а постпроцессинг в среднем занимает 2с. Вам нужно ускорить работу системы. Считаем, что сам код оптимизирован идеально. Поэтому для ускорения остается только заваливать задачу железом (масштабироваться). Ваши действия?
У вас есть сетка, которая умеет на спутниковом снимке находить маски домиков. Затем эти маски нужно превратить в полигоны домиков.
Вряд ли ваша сетка умеет сегментировать pixel-perfect. Поэтому получится полигон как на картинке (b). У этого полигона слишком много вершин и такой рваный домик на карту не поставишь. Поэтому будем постпроцессить такой полигон. Нам нужно, чтобы было поменьше вершин и побольше прямых углов и параллельных сторон. Получим приятный полигон как на картинке (c).
На одной картинке могут быть сотни таких полигонов. Поэтому постпроцессинг может стать боттлнеком вашей системы.
Вопрос
Пусть в среднем нейросеть предсказывает маску за 100мс, а постпроцессинг в среднем занимает 2с. Вам нужно ускорить работу системы. Считаем, что сам код оптимизирован идеально. Поэтому для ускорения остается только заваливать задачу железом (масштабироваться). Ваши действия?
Ответ на вопрос с собеседования💼
Будем считать, что у нас есть условный k8s и нам не нужно греть голову над балансировкой запросов между репликами, оно как-то само заработает 🙂. И пусть картинки к нам приходят по HTTP.
Нашу систему можно упрощенно нарисовать как на рис. 1 (a). Есть сетка на GPU и выход из нее мы передаем в постпроцессинг, который молотит полигоны на CPU.
Первый вариант, который может прийти в голову: а давайте просто горизонтально масштабировать всю систему целиком (рис. 1(b)). Так делать плохо. По условию наша сетка работает в 20 раз быстрее, чем постпроцессинг. Т.е. почти всё время наши дорогущие GPU-мощности простаивают. Получается, при таком масштабировании мы вместо одной дорогущей простаивающей видеокарты получаем много дорогущих простаивающих видеокарт. Не дела.
Будем считать, что у нас есть условный k8s и нам не нужно греть голову над балансировкой запросов между репликами, оно как-то само заработает 🙂. И пусть картинки к нам приходят по HTTP.
Нашу систему можно упрощенно нарисовать как на рис. 1 (a). Есть сетка на GPU и выход из нее мы передаем в постпроцессинг, который молотит полигоны на CPU.
Первый вариант, который может прийти в голову: а давайте просто горизонтально масштабировать всю систему целиком (рис. 1(b)). Так делать плохо. По условию наша сетка работает в 20 раз быстрее, чем постпроцессинг. Т.е. почти всё время наши дорогущие GPU-мощности простаивают. Получается, при таком масштабировании мы вместо одной дорогущей простаивающей видеокарты получаем много дорогущих простаивающих видеокарт. Не дела.
Давайте масштабировать только CPU-часть. Для этого вынесем ее в отдельный HTTP-сервис и сделаем столько реплик сервиса постпроцессинга, сколько нужно, чтобы CUDA-часть не простаивала (рис. 2 (а)). При таком подходе у нас не простаивает GPU и мы масштабируемся за счет относительно дешевых CPU (дешевых относительно видеокарт).
Можно посылать все полигоны (по условию их сотни) с картинки в сервис постпроцессинга. Но лучше разбивать полигоны на батчи и уже батчи асинхронно слать в сервис постпроцессинга (рис. 2 (б)). Такой подход позволит нам лучше утилизировать CPU-часть и лучше масштабироваться.
Это легко понять на простом примере: пусть к нам пришла только одна картинка и на ней 100 полигонов. Если мы пошлем все полигоны одним запросом, то будем ждать, пока один из зеленых сервисов их прожует. То есть мы вообще ничего не получили от масштабирования CPU-части. Но если мы разбили на пять батчей и каждый послали отдельным запросом, то над ними будут трудиться уже пять зеленых сервисов и мы ускоримся в пять раз.
Далее, когда докидывание CPU-сервисов перестает давать прирост к производительности, мы начнем докидывать еще и GPU-сервисы (рис. 2 (c)).
Можно заметить, что у нас появились накладные расходы на сеть, но будем считать, что они малы по сравнению с временем работы постпроцессинга.
Скорее всего, нагрузка на такой сервис не будет равномерной. Это значит, например, что в одно время суток нам нужно будет сто зеленых сервисов, а в другое время мы обошлись бы и десятью. Здесь, например, нас может выручить HPA. Он позволит нам автоматически разворачивать новые зеленые сервисы, например, тогда, когда утилизация CPU становится больше некоторого порога.
Еще можно сказать, что подход с HTTP-запросами и сервисами может быть заменен на подход с промежуточной очередью и воркерами. Он будет спасать нас, например, от резких всплесков нагрузки. Но в условиях несложной задачки будем считать этот пункт не очень важным 😉
Можно посылать все полигоны (по условию их сотни) с картинки в сервис постпроцессинга. Но лучше разбивать полигоны на батчи и уже батчи асинхронно слать в сервис постпроцессинга (рис. 2 (б)). Такой подход позволит нам лучше утилизировать CPU-часть и лучше масштабироваться.
Это легко понять на простом примере: пусть к нам пришла только одна картинка и на ней 100 полигонов. Если мы пошлем все полигоны одним запросом, то будем ждать, пока один из зеленых сервисов их прожует. То есть мы вообще ничего не получили от масштабирования CPU-части. Но если мы разбили на пять батчей и каждый послали отдельным запросом, то над ними будут трудиться уже пять зеленых сервисов и мы ускоримся в пять раз.
Далее, когда докидывание CPU-сервисов перестает давать прирост к производительности, мы начнем докидывать еще и GPU-сервисы (рис. 2 (c)).
Можно заметить, что у нас появились накладные расходы на сеть, но будем считать, что они малы по сравнению с временем работы постпроцессинга.
Скорее всего, нагрузка на такой сервис не будет равномерной. Это значит, например, что в одно время суток нам нужно будет сто зеленых сервисов, а в другое время мы обошлись бы и десятью. Здесь, например, нас может выручить HPA. Он позволит нам автоматически разворачивать новые зеленые сервисы, например, тогда, когда утилизация CPU становится больше некоторого порога.
Еще можно сказать, что подход с HTTP-запросами и сервисами может быть заменен на подход с промежуточной очередью и воркерами. Он будет спасать нас, например, от резких всплесков нагрузки. Но в условиях несложной задачки будем считать этот пункт не очень важным 😉
Как понять где ваш код тормозит
⠀
Недавно мы рассказали про два простых метода ускорения сетей: фьюзинг и дистилляция. Но не архитектурными трюками едины! Эффективно написанный код может также бустануть ваш инференс или тренировку.
Но как понять что код эффективен? Использовать профилировщики! В новой статье мы рассказали про вариант, который хорошо подойдет под специфику DL: Профилировщик torch.profiler — читайте и пишите эффективный код✌️
⠀
Недавно мы рассказали про два простых метода ускорения сетей: фьюзинг и дистилляция. Но не архитектурными трюками едины! Эффективно написанный код может также бустануть ваш инференс или тренировку.
Но как понять что код эффективен? Использовать профилировщики! В новой статье мы рассказали про вариант, который хорошо подойдет под специфику DL: Профилировщик torch.profiler — читайте и пишите эффективный код✌️
Telegraph
Профилировщик torch.profiler
Автор: Александр Лекомцев Иногда ваш код работает долго, а почему — не сразу понятно. Как выяснить, какие части кода стоит ускорить, а какие работают достаточно быстро? В этом помогают разобраться профилировщики. Профилирование позволяет замерить время работы…