Неделька выдалась тяжелой, попробуем наверстать.
Все говорят, что BatchNorm -- это хорошо, но давайте обсудим)
Предположим, речь идет про картинки, на вход в BN приходит тензор [bs, channels, height, width].
Сколько в BN обучаемых параметров?
В каком порядке правильно-то размещать BN и остальные слои?
Современные фреймворки удобны не только тем, что дают удобные примитивы: в них используются отличные дефолтные параметры. Мы особо не заморачиваемся с инициализацией когда учим с нуля резнет.
Между тем, вопрос об инициализации все еще активно пересматривается.
Во времена сигмоид (когда только самые математики использовали 1.72 tanh 2x/3) проблема была простой: функции активации с насыщением душили сигналы и градиенты. Этот момент полечился с помощью *ReLU, но градиенты продолжали взрываться и тухнуть.
Удобной эвристикой для построения архитектур, инициализацией весов и нормализации входных данных можно считать следующее соглашение:
пусть в промежуточных тензорах соблюдается x.mean = 0, x.std =1.
Исходя из подобных соображений инициализируются веса
(см arxiv.org/abs/1502.01852)
Что делать, если инициализация где-то оказалась неудачной? Можно физически уменьшить влияние и отнормировать промежуточные значения.
В этом нам помогают *Norm-слои:
x - это входной тензор, средние считаются по некоторым осям, gamma и beta - обучаемые параметры.
Важный момент: E[x], Var[x] - не обучаемые параметры!
gamma и beta призваны восстанавливать параметры распределения, если это нужно. gamma инициализируется единичками, beta -- нулями.
В pytorch их можно выключать.
Если говорить про BN, E[x], Var[x] считаются по всем размерностям кроме каналов. Это порождает вопросы и проблемы:
- семплы в батче теперь взаимодействуют
- что делать во время инференса? ведь там в батч может придти что угодно => это будет влиять на результат
Решение простое: во время тренировки в формуле используем честное средние по нужным осям (и градиенты на них пропускаем честно), а для инференса воспользуемся накопленными усредненными статистиками. В pytorch это поведение переключается методами: model.train(), model.eval().
Так что если на вход BN приезжает тензор размеров [bs, ch, h, w], то усреднения делаются по [bs, h, w]. Они используются как есть и добавляются к двум векторам размера [channels].
Кроме статистик есть два обучаемых вектора размеров [channels].
Conv + BN (в eval-режиме) можно зафьюзить, т.е. заменить на один Conv-слой, просто пересчитав для него ядра.
Алсо, gamma и beta выглядят многообещающе для закидывания в сеть дополнительных фичей: например статистик из другой сети/с другой картинки (см AdaIN). А еще можно добавить пространственных осей и подсыпать в сеть сегментационных данных (см SPADE).
• • •
Missing some Tweet in this thread? You can try to
force a refresh
Пояснения к опросам я выложу завтра. А пока поговорим про сетки в проде.
В какой прод вы катите ML/DL модельки?
В основном на курсах по ML/DL речь идет про обучение моделек. MVP делается на слегка подправленной кодовой базе с питоном и фласками.
Моделька создается кодом, в нее подгружаются веса из чекпоинта.
Если проект не умер на первых порах, дальше пойдет эволюция.
Люди прибывают. Модельки усложняются.
Появляется легаси (и это нормально!).
Вы начинаете страдать от обратной совместимости, а она от вас, катить становится сложнее, в коде копятся валенки (скажем другой метод ресайза картинок будет стоить вам процентов acc@1 на imagenet).
Что стоит знать в фреймворке (для определенности pytorch):
- как строится вычислительный граф (у тензоров есть backward-функция, за которую можно дернуть для бекпропа)
- как представлять данные (условно складываем картинки в тензора [bs, channels, height, width])
- как вычисляется лосс (давайте опросом, что должно быть у сети для многоклассовой классификации в голове?)
Пояснения на всякий случай:
- в доку не подглядывать!
- FC=Linear (иначе не лезло)
- если не понимаете о чем речь => reply с вопросом
- как управлять оптимизатором (обход весов, lr scheduling, grad_clip..)
- как мерить скорость и утилизацию железа (tqdm, watch nvidia-smi, profiler..)
- как дебажить наны (forward_hook, backward_hook)
- как сериализовать модель (torch.save, jit.trace, jit.script)
Про инструменты.
Я в основном пишу код на питоне, эпизодически на C++, иногда JS/bash и на чем еще придется по задаче.
Все хоббийное и учебное я пишу на Pytorch, почти все рабочее на TF.
Самый богатый источник граблей - рабочие инструменты.
Очень часто наблюдаю как люди тонну времени тратят на войну с инструментами, а не задачей.
Распространенная история - человек что-то делал, получил результаты, но им нельзя доверять => работу надо переделывать.
Имхо про фреймворки:
- конкуренция это здорово, tf был удобнее theano, pytorch удобнее tf, tf2 удобнее tf1
- не важной какой фреймворк вы используете, кодовую базу и математику сетей нужно заботать, иначе в ваших результатах буду валенки
- ....
На первом курсе универа на колабе МИСиС, MIT и Сколково подружились с Олегом Уржумцевым. Нас преподы из MIT учили делать игрушки на 3D принтерах и лазерных резаках.
Чтобы попасть в эту программу надо было знать английский и уметь в сборку электроники. В этом-то я был хорош.
Потом мне удалось с ними пообщаться вживую (помогли старые EPAM-вские связи)
Оказалось они только стартуют и челленджей непочатый край. Я начал работу над OpenSource проектом с баг-фикса в алгоритме перемножения распределённых блочных матриц и понеслось. 102 коммита, 300k+ строк кода, 15 моделей, PMC проекта.
Чем больше я пилил распределенный ML, читал статьи, писал свои, изучал код scikit-learn/Spark/dlib/tensorflow, тем больше крепло ощущение, что это мое. В какой-то момент случилась магия:
DEThread: Перебравшись в СПб я уже вплотную занялся прокачкой навыков DE, пытаясь устроиться чистым DS. На чистого DS брали только на мало денег, поэтому я раз за разом выбирал DE проекты (presale/прототипы) и рос очень быстро, играя роль FullStackBigData
Одновременно пошел просто огромный поток джавистов, дотнетчиков, database administrators, бегущих из старых рынков в новый сияющий мир "BigData: Hadoop, Hive, Spark". В EPAM мы открыли менторинг (учеба с куратором) по BigData, через который прошло 300+ человек в 16-18 годах
Мне повезло работать с очень крутыми архитекторами и большим количеством досконально изучающих фреймворки людей. Кишки Hadoop - это нечто. Именно тогда и началось мое погружение в недра и уход в библиотекописательство. Ты глядишь - и понимаешь, что можешь говнякать не хуже. 100%