DeepSchool – Telegram
DeepSchool
10.3K subscribers
77 photos
1 video
1 file
432 links
Это канал школы deepschool.ru. Здесь мы будем:
- напоминать вам теорию ML/DL в виде коротких постов,
- задавать вопросы с собеседований,
- рассказывать про полезные фреймворки
- и делиться советами, которые помогут вам в работе.

@deepschool_support
Download Telegram
По количеству китов поняли, что тема интересна, поэтому не будем откладывать до будних дней! Спасибо всем за ваши реакции! Ниже более подробный разбор статьи, как и обещали👇
👍6
​​Разбираем статью 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

Сегодня опубликуем первые две, а завтра третью, чтобы не высыпать слишком много букав за один раз)
И так, погнали👇
🔥22🤯2🐳1
​​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
🔥45👍5
​​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 (практическим путем выявили, что это докидывает).
🔥28👍6
​​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
🔥20👍31
Давно хотели завести рубрику “повторяем теорию”🤓 И кажется, что вторник отлично для нее подходит😉 Ранее мы вспоминали Batch Normalization, поэтому сперва закончим с нормализацией в рамках новой рубрики, а после пойдем дальше.

В этот раз для удобства написали пост в формате статьи в телеграфе: там можно вставлять картиночки между текстом, а на телефоне меньше скроллить и оставаться в приложении телеграма.

Если вы хотите вспомнить, какие проблемы есть у батчнорма, и какие “аналоги” были призваны их решить: Layer Norm, Instance Norm и Group Norm — то читайте нашу статью в телеграфе 🙂

#повторяем_теорию #нормализация
🔥23👍61
Записали для вас видео про ускорение инференса! 🚀

В нем Дима Чудаков рассказал как быстро и дешево ускорить инференс ваших сетей при помощи фьюзинга и дистилляции, а также оставил несколько советов по их применению.

Это наш дебют на ютубе! Будем рады поддержке) Подписывайтесь и ставьте лайки если вам понравилось видео в подобном формате👍

Переходите по ссылке, чтобы посмотреть: https://youtu.be/6UJn0J1Sul4
🔥36🎉6🎃1
Сегодня вторник, а значит в эфире рубрика “повторяем теорию”🤓

Вспомним про регуляризацию сетей, а именно про три популярных метода: L1, L2 и Dropout (ведь был популярен когда-то, надо отдать дань старичку). Статья в телеграфе 👉 Регуляризуем правильно!

#регуляризация #L1 #L2 #dropout
👍20🔥4
После двух статей в телеграфе интересно узнать: в каком виде вам удобнее читать посты?
Anonymous Poll
76%
В виде телеграф-статей
24%
В виде сообщений в группе
Хотели рассказать вам про Efficient Net, потому что многие путаются в этой архитектуре и не до конца понимают причем тут “efficient” то вообще) Взяли на себя ответственность поставить точку в этом вопросе. Чтобы в следующий раз, когда вас спросят что это за EffNet такой, вы без проблем могли ответить.

Изучать архитектуры — полезно. Эти знания позволят вам правильно подобрать сеть под ваши задачи и ограничения, а иногда даже помогут пропатчить какую-нибудь китайскую сетку, чтобы потом сконвертить ее в TRT))

Но рассказывая про EffNet, нельзя не упомянуть MBConv блоки из MobileNet. Объясняя Inverted Residual хорошо бы рассказать про обычный Residual и так далее. Поэтому логичнее уже пройтись по всей истории эволюции и начать с VGG😅

Вот и начали… Представляем вашему вниманию первую статью из серии “вспоминаем архитектуры”: разбираем VGG. Давайте вместе пройдемся по истории и вспомним/изучим/дополним_наши_знания: https://telegra.ph/VGG-10-10
👍31🔥162
Вы когда-нибудь путались в функциях потерь для классификации? BCE, log-loss, Cross Entropy, Focal Loss — одно является частным случаем другого, третье выражается через четвертое, еще и в разных статьях свапают названия между собой)

Если хотите вспомнить кто есть кто, то мы подготовили для вас статью Функции потерь для классификации.

В ней мы также напомним:
- кто такой Brier Score;
- когда в задаче классификации может сработать MSE;
- что можно сделать с функцией потерь при дисбалансе классов;
- да, в прошлом пункте нет интриги, можно взвесить классы — но что если в минорном классе есть простые примеры, которые сеть учит легко и быстро, а в мажорном сложные? В чем тут может быть проблема и как ее решить?

В общем, есть что вспомнить, давайте закрепим знания вместе: https://telegra.ph/Funkcii-poter-dlya-klassifikacii-10-12
🔥50👍12🤔21
​​Рубрика «Вопрос с собеседования»💼

У вас есть сетка, которая умеет на спутниковом снимке находить маски домиков. Затем эти маски нужно превратить в полигоны домиков.

Вряд ли ваша сетка умеет сегментировать pixel-perfect. Поэтому получится полигон как на картинке (b). У этого полигона слишком много вершин и такой рваный домик на карту не поставишь. Поэтому будем постпроцессить такой полигон. Нам нужно, чтобы было поменьше вершин и побольше прямых углов и параллельных сторон. Получим приятный полигон как на картинке (c).

На одной картинке могут быть сотни таких полигонов. Поэтому постпроцессинг может стать боттлнеком вашей системы.

Вопрос

Пусть в среднем нейросеть предсказывает маску за 100мс, а постпроцессинг в среднем занимает 2с. Вам нужно ускорить работу системы. Считаем, что сам код оптимизирован идеально. Поэтому для ускорения остается только заваливать задачу железом (масштабироваться). Ваши действия?
🤔19👍12🤯11🐳21
​​Ответ на вопрос с собеседования💼

Будем считать, что у нас есть условный k8s и нам не нужно греть голову над балансировкой запросов между репликами, оно как-то само заработает 🙂. И пусть картинки к нам приходят по HTTP.

Нашу систему можно упрощенно нарисовать как на рис. 1 (a). Есть сетка на GPU и выход из нее мы передаем в постпроцессинг, который молотит полигоны на CPU.

Первый вариант, который может прийти в голову: а давайте просто горизонтально масштабировать всю систему целиком (рис. 1(b)). Так делать плохо. По условию наша сетка работает в 20 раз быстрее, чем постпроцессинг. Т.е. почти всё время наши дорогущие GPU-мощности простаивают. Получается, при таком масштабировании мы вместо одной дорогущей простаивающей видеокарты получаем много дорогущих простаивающих видеокарт. Не дела.
🔥15🤯4
​​Давайте масштабировать только CPU-часть. Для этого вынесем ее в отдельный HTTP-сервис и сделаем столько реплик сервиса постпроцессинга, сколько нужно, чтобы CUDA-часть не простаивала (рис. 2 (а)). При таком подходе у нас не простаивает GPU и мы масштабируемся за счет относительно дешевых CPU (дешевых относительно видеокарт).

Можно посылать все полигоны (по условию их сотни) с картинки в сервис постпроцессинга. Но лучше разбивать полигоны на батчи и уже батчи асинхронно слать в сервис постпроцессинга (рис. 2 (б)). Такой подход позволит нам лучше утилизировать CPU-часть и лучше масштабироваться.
Это легко понять на простом примере: пусть к нам пришла только одна картинка и на ней 100 полигонов. Если мы пошлем все полигоны одним запросом, то будем ждать, пока один из зеленых сервисов их прожует. То есть мы вообще ничего не получили от масштабирования CPU-части. Но если мы разбили на пять батчей и каждый послали отдельным запросом, то над ними будут трудиться уже пять зеленых сервисов и мы ускоримся в пять раз.

Далее, когда докидывание CPU-сервисов перестает давать прирост к производительности, мы начнем докидывать еще и GPU-сервисы (рис. 2 (c)).

Можно заметить, что у нас появились накладные расходы на сеть, но будем считать, что они малы по сравнению с временем работы постпроцессинга.

Скорее всего, нагрузка на такой сервис не будет равномерной. Это значит, например, что в одно время суток нам нужно будет сто зеленых сервисов, а в другое время мы обошлись бы и десятью. Здесь, например, нас может выручить HPA. Он позволит нам автоматически разворачивать новые зеленые сервисы, например, тогда, когда утилизация CPU становится больше некоторого порога.

Еще можно сказать, что подход с HTTP-запросами и сервисами может быть заменен на подход с промежуточной очередью и воркерами. Он будет спасать нас, например, от резких всплесков нагрузки. Но в условиях несложной задачки будем считать этот пункт не очень важным 😉
🔥25🤔3🤯3🐳3
Как понять где ваш код тормозит

Недавно мы рассказали про два простых метода ускорения сетей: фьюзинг и дистилляция. Но не архитектурными трюками едины! Эффективно написанный код может также бустануть ваш инференс или тренировку.

Но как понять что код эффективен? Использовать профилировщики! В новой статье мы рассказали про вариант, который хорошо подойдет под специфику DL: Профилировщик torch.profiler — читайте и пишите эффективный код✌️
👍24🔥9🐳4👏2
Вебинар по введению в разработку

В посте про распределение нагрузки между GPU и CPU мы упомянули k8s. Еще тогда подумали рассказать что такое кубер в одном из постов, но тогда надо бы и докер упомянуть, да и CI/CD можно.. Плюс есть люди, которые вообще никогда не занимались разработкой. Поэтому мы решили провести вводную онлайн-лекцию, на которой расскажем как создают и поддерживают сервисы.

Вебинар рассчитан на новичков, которые не сталкивались с разработкой. На нем мы обзорно рассмотрим что такое сервис, докер, кубер, мониторинг, ci/cd и другие базззворды🐝 За пару часов вебинара стать профи в этих темах нельзя, но понять, за что каждая из них отвечает — вполне :)

Чтобы материал был еще полезнее, создали для вас короткую гугл-форму, через которую вы можете повлиять на содержание лекции и задать интересующие вас вопросы — на них мы ответим на вебинаре.

Время вебинара сообщим на этой неделе! Кстати, в гугл-форме можно повлиять и на него :)
🔥24👍6🤯2🤩1
Продолжаем ликбез по архитектурам

В прошлый раз мы рассказывали про VGG, теперь вспоминаем как зародилось семейство ResNet.

В отличии от VGG, ResNet не стыдно использовать в привычных CV задачах даже в 2022 году. Надо лишь знать как ее учить — об мы, кстати, рассказывали в серии предыдущих постов.

В новой же статье отдаем дань старичку и вспоминаем:
- изначальную идею,
- пользу ботлнек блоков
- и основной вклад identity веток в deep learning
19🔥5👍4🍌1
​​Вебинар по введению в разработку

Недавно мы анонсировали вебинар и попросили вас заполнить гугл-форму. Спасибо всем за ваши ответы! Благодаря им мы уже скорректировали план лекции и выбрали оптимальное время. Решили не тянуть с обещанием и провести вебинар уже в этот вторник 1 ноября в 18:00 Мск🔥

Напомним, что вебинар расчитан на новичков, которые еще не знакомы с разработкой. На нем вы узнаете:
- как обученную модель доставляют до клиентов,
- как разворачивают приложение на сервере,
- как автоматизируют доставку,
- и как следят за ошибками и метриками.

Чтобы зарегистрироваться, просто начните диалог с нашим ботом: @deepschool_webbot. До встречи на вебинаре!🚀
12🔥4🐳4👍1
DeepSchool
​​Вебинар по введению в разработку Недавно мы анонсировали вебинар и попросили вас заполнить гугл-форму. Спасибо всем за ваши ответы! Благодаря им мы уже скорректировали план лекции и выбрали оптимальное время. Решили не тянуть с обещанием и провести вебинар…
Провели наш первый вебинар! Спасибо всем кто заполнял формы, оставлял вопросы, участвовал в вебинаре и предлагал новые темы❤️

Получили несколько сообщений с просьбой повторить вебинар, поэтому хотим оценить количество желающих. Поставьте, пожалуйста, китенка в реакцию, если хотите повтор🐳 Наберем 30 китов — повторим!
🐳59
Однако, не ожидали, что за 30 минут наберем 30 китов😅
Повтору — быть!

Анонсируем дату позднее в этом канале
👍85🔥2
Виды сверток

Собрали в одну статью различные виды сверток!
Напомнили зачем существуют свертки 1х1, что такое Depthwise Separable Convolution, Spatialy Separable и другие. Не забыли и про нотку экзотики в виде Shuffled Grouped и Deformable.

Читайте статью, чтобы вспомнить какие бывают свертки и чем они отличаются: https://telegra.ph/Vidy-2D-svertok-11-03
🔥48👍5🤔1