Telegram Web Link
Так как мне в обозримом будущем может понадобиться поверхностное знание NLP, решил пройти какой-нибудь небольшой курс и выбрал NLP Course | For You. Так вот, это кайф с первой недели!

Во-первых, это просто качественный контент - не просто россыпь формул, не просто примеры с котиками, а стройное сбалансированное повествование от ключевых идей и математики за ними до разных инкрементальных улучшений поверх. Курс помогает не заботать, а развить интуицию, что, на мой взгляд, первично.

Во-вторых, курс будто сделан для бумеров, в формате прилично свертстанного текста, с картинками и ссылками в разумном количестве - олдскульный интернет, который мы потеряли в пользу ютубов и прочих тиктоков. По-старчески плачу от умиления. Семинары и домашки - в Jupyter ноутбуках, для чего они весьма уместны.

~~

Вообще идея "давайте вернемся к истокам и будем делать образование текстом" не новая, например, ее активно продвигает Educative.io:

Videos are holding you back. The average video tutorial is spoken at 150 words per minute, while you can read at 250. That‘s why our courses are text-based.

У Educative есть несколько хитовых курсов: например, Grokking the System Design Interview и Grokking the Coding Interview (сам я их не проходил). От тех Educative курсов, которые я когда-то щупал своими руками, ощущения неоднозначные, разбежка от достойных цельных курсов до третьесортных компиляций бестолковых постов с медиума👳‍♂️. В принципе, неудивительно - платформа со свободным доступом для авторов всегда будет привлекать не только крутых ребят, но и всякий треш.
Кажется, в написании любого computer vision пайплайна обязательно должны быть два важных этапа:
1) "все-таки придется добавить больше визуализаций";
2) "все-таки где-то перепутал x и y (или height и width)".

Я как наступал на такие грабли, так и продолжаю до сих пор. Разве что дебажить начал быстрее.
Мини-история началась с того, что Notion начал раздавать промокод (ADALOVELACE) на $500. Я пользуюсь этим сервисом, так что пошел в настройки, вбил код и заодно решил посмотреть, что там вообще в настройках есть.

Нашел поле Domain - на каком домене будут находиться те записи, которые я решил пошарить. По умолчанию там рандомный бессмысленный домен, почему бы и не поменять.

Вбиваю arseny - пишет, что занято. Ну и ладно, мало ли Арсениев, можно попробовать мой обычный arsenyinfo. Тоже занято, это уже довольно удивительно. Но когда и arsenyjdkhgjksehfjkhskjgh оказался занят, я заподозрил, что дело в чем-то другом.

Резонно предположить, что иногда внешние апишки так устроены, чтобы не раскрывать всю правду потенциальным злоумышленникам. Например, если кто-то явно брутфорсит пароли к вашему сервису, нормально отвечать что-то вроде Wrong password или Service not available, даже если пароль правильный и сервис нормально работает.

Long story short: несколько попыток перебора показали, что недоступны все домены по маске *arse*. Что ж, Notion не первый - я с таким уже сталкивался :(



Вообще, технические решения, основанные на white/black списках, не очень надежны.

Когда-то давно в одном популярном сервисе мы делали подсказки для опечаток в почте. Многие пользователи вводили [email protected] и страдали, что им не приходит confirmation email. Я почитал про расстояние Левенштейна и сделал так: для всех доменов не из top-N ищем соседа с расстоянием == 1 и предлагаем заменить.

Все круто, метрики везде растут, кроме одного региона - Азии. Потому что относительно популярный в Азии ymail.com не попал в глобальный top-N, и мы предлагали его заменить на gmail.com.
Я просто оставлю это здесь: A Time-Series Analysis of my Girlfriends Mood Swings. Сатирически-академический подход к важному вопросу "как девушка отреагирует, если я буду играть в видеоигры всю субботу напролет".
Спустя 10 месяцев поиска компания, в которой я работаю, смогла нанять погонщика менеджера для меня Head of ML. Он произвел впечатление на СТО своим девизом "Все мои сотрудники должны быть способны стать CEO стартапа через 10 лет!" - мол, надо развивать гребцов вширь, коучить обучать их делать более разнообразную работу, и уж тогда-то все заколосится.

Мне настолько не нравится этот девиз, что я созрел написать лонгрид про разделение ролей.

В одной из компаний, где я раньше работал, инженеры крутили свои гайки и не особенно стремились видеть большую картину. И однажды СТО собрал нас всех на оффсайте и сказал: "Дорогие инженеры, я хочу, чтобы каждый из вас после работы здесь мог стать фаундером стартапа! Благословляю вас больше вовлекаться в продуктовую работу!".

Его месседж был во многом уместен - культура компании была слегка перекошена, ownership-а на местах не хватало, инженеры могли делать херню и оправдываться в духе "с моей стороны пуля вылетела". Но вот соус, под которым месседж подавался, все испортил - инженеры чуть не устроили бунт. Многие из них пришли из компаний попроще, где занимали позиции тим-, тех- и прочих лидов, страдая и не особенно преуспевая, и потому с удовольствием вернулись к работе своими руками. "Зачем мне быть фаундером, после ухода из компании я рассчитываю уйти в другую компанию и там тоже писать код!" - возмущались инженеры, и СТО вынужден был сдать назад, пока его не подняли на вилы.

Эта история иллюстрировала крайний случай. У кофаундеров другая история: обычно им в голову не приходит сказать "это не моя работа" по отношению к какой-то непрофильной возне. Некому капризничать: если какую-то работу нельзя делегировать, то или кофаундер делает ее сам, или она не будет сделана. Так, например, я в свое время собственноручно собирал компьютеры и устанавливал на них софт глубоким вечером в пятницу, чтобы в понедельник пришли новые разметчики и сразу приступили к работе. Похожие истории может рассказать любой (ко-)фаундер - о том, как им приходилось быть на полшишечки юристом, эйчаром, маркетологом, сисадмином и еще черт знает кем. Но фаундеры на то и фаундеры, они обычно знают, на что идут, и обе морковки их мотивируют.

Не каждый должен быть готов стать CEO или фаундером через 10 лет. Не каждый даже должен готовиться стать менеджером или каким-то еще лидером - программисты находятся в отличной позиции, чтобы просто качественно делать свою работу и впредь, будучи рядовым исполнителем aka individual contributor. Как и не каждый доктор должен стремиться открывать свою клинику, не каждый редактор - открывать свое издательство, а про бордели и блудниц sex workers уважаемые читатели могут опционально додумать сами.
Хочу порекомендовать Tailscale - софт для настройки VPN, который просто работает из коробки и не требует особой конфигурации или понимания, как вообще работают сети.

Например, если covid не запер вас дома, и вам хочется хоть иногда путешествовать, и при этом иметь доступ к домашней сети и заодно прогонять через нее весь трафик, пользуясь стремным wi-fi где-то в отеле, предварительная настройка VPN с tailscale займет от силы пять минут.
Меня наконец-то пустили потрогать Github Copilot, и даже соответствующий плагин к Pycharm подоспел.

Я не стал целенаправленно искать bias (это уже давно сделали до меня), а просто сел за обычную работу - очередное перекладывание файлов для ML пайплайна.

Ощущения, как и ожидалось, неоднозначные.

Во-первых, copilot быстро выучил структуру json-файлов, которые я перекладывал: предлагал строки вроде `if data["key"] == "value", хотя ни key, ни value в этой функции нигде не появлялись.

Во-вторых, некоторые дополнения прямо в точку. Например, по инпуту
core, *_ = centers
dists = [

предложить dists = [np.linalg.norm(c - core) for c in centers] - это круто.

В-третьих, иногда плагин берет на себя прям слишком много и начинает творить. Например, по началу файла "This script can be used to prepare...", он нафигачил еще 20+ строк (неправильного) описания скрипта, его аргументов и наимпортировал 8 библиотек, часть из которых в проекте вообще не используются.

В-четвертых, latency все-таки заметно. В отличие от нативных подсказок IDE, Copilot достаточно медленный, и быстрее написать простой кусок самому, чем ждать подсказку и надеяться, что она осмысленная.
Продолжаю играть с Copilot.

Длинные подсказки из маленького контекста (например, в новых файлах) вообще всегда плохие: ожидаемое непонимание задачи, попытки импортировать несуществующие функции из несуществующих модулей.

Если же контекста хватает, то часто случается такой паттерн: "о, классная подсказка, принимаю... ТАК ПАДАЖЖИ это совсем дичь!". Т.е. все токены правильные, все вроде бы связно, но если присмотреться - это же полная херня! Из пяти строк четыре по делу, а пятая потенциально все сломает самым подлым образом так, что можно и сперва не заметить. Напоминает некоторые интервью: вроде бы собеседуешь человека, резюме красивое, говорит правильные слова в нужном порядке, но если приложить усилие и копнуть поглубже, карета превращается в тыкву.

Впрочем, лучший скриншот на тему мне все равно прислал дорогой подписчик.
Продолжаю транслировать контент от дорогих подписчиков. На этот раз - новостной заголовок:

В Китае нейросеть мешает козам совершить инцест 🐐

Кстати, задача идентификации животных на ферме технически довольно интересная. Source: один мой приятель прикручивал metric learning для идентификации коров по паттерну пятен на шкуре.
Finding why Pytorch Lightning made my training 4x slower - отличный пост про поиск замысловатого бага в ML инфраструктуре. Пример инженерного здравого смысла: хорошо использовать готовые инструменты, но не боги горшки обжигают - не стоит бояться залезть под капот и что-то пофиксить.
Всем DL-практикам, которые претендуют на большее, чем запускать готовые fit-predict пайплайны с гитхаба, рекомендую этот пост про inductive bias в нейросетях. Примеры в основном про computer vision, но обобщаемы и на другие задачи; для самых въедливых читателей в конце статьи предоставлен достаточно широкий набор ссылок по теме.
Today I learned: cтаринный развод "игра в наперстки" является важной задачей в академическом ML.
Узнал новый для себя концепт - multisource weak supervision. Точнее, красивое название в новинку, а сама идея старая: вместо качественной, но дорогой разметки руками нафигачим эвристик, которые сколько-то похожи на правду.

Эвристики и другие источники слабой разметки могут быть разными - lambda text: 'enlarge your' in text, какие-нибудь регэксы, результаты внешних моделей и так далее, отсюда и multisource. Потому после применения всех внешних supervision источников нужно сделать их сколько-то согласованными, для чего, оказывается, есть уже довольно много инструментов. Среди модных хипстерских замечен Snorkel (активно рекламируемый в курсe Стeнфорда), в опенсорсе есть свежак с NeurIPS 2021 (слайды на тему).

Вообще weak supervision - отлично работающий инструмент. Например, есть миллион фотографий, нужно удалить размытые. Самый простой способ: разметить эвристикой с лаплассианом, а потом на этой разметке обучить простой классификатор. Изначальная эвристика работает не очень хорошо сама по себе - например, размытая фотография клетчатой рубашки будет иметь высокую дисперсию лаплассиана, а неразмытая фотография стены - низкую. Но обученный классификатор сильно снизит этот уровень шума.
Продолжу пересказывать некоторые странные факты, услышанные на NeurIPS 2021.

Наверняка вы все знаете Imagenet как датасет, на котором меряются качеством image classification. Некоторые из вас также слышали про Imagenet 1k и Imagenet 21k: первый содержит тысячу классов и около 1.5 изображений, именно его обычно используют в качестве бенчмарка, а второй - 21+k классов и почти 15М изображений. И, предположу, еще меньшая доля читателей знает, что именно за классы там используются.

Более или менее известен факт, что структура классов Imagenet 1k не очень отражает распределение из реального мира: например, там есть CD-player, диплодок и 120 пород собак; есть и сильно схожие классы (например, red wine и wine bottle). Но список классов Imagenet 21k может удивить еще сильнее: там есть такие неожиданные классы, как филантроп, вегетарианец, расист и атеист.

Полный разбор на тему нескольких тысяч неподходящих (non-imageable, offensive, sensitive) классов можно прочитать в этой статье. Некоторым читателям часть изложенного может показаться левацкой придурью, но сложность отрицать бесполезность обучения на невизуализируемых лейблах типа orphan или rheumatologist.
Еще на прошлой неделе закончился NeurIPS 2021, пора собрать в кучу хотя бы некоторые заметки оттуда.

В этом году он проходил в онлайне; в целом все, кроме постер-сессий, было сделано довольно удобно - например, видео можно было смотреть на удобной скорости, можно листать слайды и синхронизировать с ними спикера, и так далее. Я смотрел не все и не очень внимательно, но кое-что запомнилось.

Главный хайп в сфере компьютерного зрения - это трансформеры. ViT был очень перспективен, но несовершенен (сложно обучать, долгий инференс, неустойчивость к изменению размера входных картинок...), и лучшие академические умы бросились исправлять это несовершенство. Например:

CAPE: Encoding Relative Positions with Continuous Augmented Positional Embeddings представляет новый тип positional embeddings, которые улучшают сходимость, повышают точность и устойчивость к размеру входа. Работает для CV, NLP, ASR задач.

All Tokens Matter: Token Labeling for Training Better Vision Transformers добавляет новую задачу, похожую на weak/self-supervised semantic segmentation для улучшения сходимости.

Not All Images are Worth 16x16 Words: Dynamic Transformers for Efficient Image Recognition предлагает способ динамически находить требуемое количество входных патчей, что повышает эффективность (напомню, трансформерам свойственна сложность O(n²) от количества токенов на входе).

TokenLearner: What Can 8 Learned Tokens Do for Images and Videos? предлагает скомбинировать сверточную сеть и трансформер: сначала сверточным блоком учим малое количество токенов, дальше засовываем их в трансформер.

ResT: An Efficient Transformer for Visual Recognition - очередной подход, как прикрутить свертки для оптимизации ViT и исправить родовые травмы positional encoding.

XCiT: Cross-Covariance Image Transformers предложили cross-covariance attention - еще один способ привести трансформер к линейной сложности. Бонусом идут повышение точности, визуализируемость, устойчивость к изменению входного разрешения.

В следующем посте: дистилляция, self-supervision, metric learning.
Продолжим про NeurIPS 2021. Как и обещал, сегодня про дистилляцию, self-supervision, metric learning.

Does Knowledge Distillation Really Work? задается вопросом, что не так с дистилляцией. Почему студент не всегда может дойти до уровня учителя в процессе дистилляции? Это проблема архитектуры, размера сети, домена, задачи, датасета? Авторы приходят к выводу, что корень всех зол именно в оптимизации.

Analyzing the Confidentiality of Undistillable Teachers in Knowledge Distillation - статья про nasty teachers и skeptical students. Если вы делаете какой-нибудь ML as a service, вы наверняка хотите, чтобы его было сложнее дистиллировать, для этого и нужны недистиллируемые модели. Авторы предлагают добавить новый лосс для учителя, чтобы усложнить его дистилляцию, а потом предлагают лосс для студентов, который позволяет лучше извлекать данные даже из такого учителя.

Provable Guarantees for Self-Supervised Deep Learning with Spectral Contrastive Loss тоже ставит занятный теоретический вопрос: почему вообще self-supervised обучение с contrastive лоссом позволяет выучить линейно разделяемые классы? Для ответа на вопрос авторы вводят идею augmentation graph on data, анализируют его довольно неочевидными методами (пришлось гуглить Eckart–Young–Mirsky theorem!) и в конце предлагают свой лосс. Стабильно побеждают SimCLR (используя значительно меньший батч!) и BYOL, но до SimSiam пока не дотягиваются.

Hard Negative Mixing for Contrastive Learning - вообще это статья с предыдущего NeurIPS, но я наткнулся на нее только в этом году; она была упомянута на туториале по self-supervised обучению. Семплинг важен для contrastive обучения, иначе задача становится слишком простой и модель недообучается (отсюда необходимость в большом батче для моделей типа SimCLR - это позволяет найти сложные негативные примеры). В этой статье авторы предлагают синтезировать негативные примеры прямо в feature space, что слегка улучшает качество на downstream задачах.

One Loss for All: Deep Hashing with a Single Cosine Similarity based Learning Objective - снова статья про волшебный лосс, который должен решить все проблемы, на этот раз для получения хороших deep hash, т.е. таких хэшей, по которым можно не только определять дубликаты, но и измерять близость между объектами. Авторы переформулировали расстояние Хэмминга через косинусное, что и позволяет избавиться от популярной для этой задачи комбинации нескольких лоссов.

Bag of Tricks and A Strong baseline for Image Copy Detection - набор трюков, использованных для одного из NeurIPS соревнований по определению похожих изображений. Главный трюк - “растягивание” дескрипторов за пределы традиционной для задачи единичной гиперсферы.

Partial success in closing the gap between human and machine vision - анализ того, насколько современные CV модели неустойчивы к изменению тестового распределения (например, применению аугментаций, изменению текстуры и так далее) в сравнении с людьми. До человеческого уровня еще далеко, но в среднем “продвинутые” модели (дистиллированные, self-supervised, adversarially trained, трансформеры) более устойчивы, чем “обычные” CNN. Тут можно снова вспомнить про inductive bias - это словосочетание, кажется, сейчас популярно.

В следующем (и последнем) посте про NeurIPS 2021 - небольшое ассорти из разных тем, от новых оптимизаторов до забавных названий статей.
Заключительный пост про NeurIPS 2021, с бору по сосенке.

Для тех, кто любит менять оптимизаторы на что-то поновее после каждой конференции - SuperAdam (передаю привет @hushpar).

Unadversarial Examples: Designing Objects for Robust Vision представляет концепцию unadversarial текстур, патчей и объектов, условно “как надо раскрашивать объекты в реальном мире, чтобы CV лучше их распознавало в разных условиях”. Своего рода антипод adversarial patches - наклеек, которые позволяют совершать adversarial атаки на физических объектах.

AugMax: Adversarial Composition of Random Augmentations for Robust Training - подход к CV аугментациям, который обеспечивает большую устойчивость к изменению распределения. Авторы вводят разделение для аугментаций - для повышения сложности (например, adversarial атаки) и для улучшения разнообразия (например, вращения), и проектируют такой вид аугментаций, который сможет сочетать оба преимущества.

Adaptive Denoising via GainTuning тоже про устойчивость к distribution shift, на этот раз для задачи денойзинга. Для каждого тестового изображения предлагается выучивать дополнительный параметр gain, который используется для масштабирования весов основной сети.

Узнал новую для себя концепцию адаптеров для языковых (и не только) моделей из статьи Adaptive Fine-tuning for Vision and Language Pre-trained Models (саму статью не могу нагуглить, вот постер). Идея в том, чтобы добавлять внутрь крупных блоков (в данном случае - трансформер-блоков в VisualBERT) небольшие блоки-адаптеры, которые и будут дообучаться под будущие задачи. Сведущие в NLP люди рассказали, что идея не очень нова ), но в последнее время набирает популярность (см. например). Уже планирую прикрутить к computer vision задаче!

В speech recognition я не понимаю практически ничего, но Unsupervised Speech Recognition понравилась инженерным подходом к проблеме: не изобретая ничего особенно нового, авторы из готовых кусков собрали фреймворк для распознавания речи на неразмеченных данных (и тексты, и аудио).

Конечно, было немало статей про GANы, но я, как дилетант, обратил внимание только на т.н. StyleGAN 3 - Alias-Free Generative Adversarial Networks, авторы анализировали и успешно решили проблему т.н. texture sticking - артефакта, заметного при интерполяции в латентном пространстве и потому не позволяющего генерировать правдоподобные видео и анимации. Отдельно процитирую “This entire project consumed 92 GPU years” - это больше GPU-времени, чем я потратил за всю карьеру. 😱

Дискуссировали с коллегами про самое заметное название статьи, шорт-лист составили:
- Vector-valued Gaussian Processes on Riemannian Manifolds via Gauge Independent Projected Kernels 🤓
- A Gang of Adversarial Bandits 🦹
- You Never Cluster Alone 💔

Наконец, каким-то чертом меня занесло на туториал по NLP для редких языков, где ребята из Африки рассказывали, как им сложно учить языковые модели из-за отсутствия больших качественных датасетов. Но ничего нового не узнал, TL;DR - авторы рекомендуют использовать претрейны с более популярных языков, аугментации, шумную разметку эвристиками, multi-task learning, но все эти трюки все равно резко теряет ценность, как только появляется достаточное количество качественно размеченных данных (вот это поворот, конечно).
Мой братишка по масонской ложе, широко известный в data science тусовке качок-карьерист Валера недавно пустился во все тяжкие: свалил из Фейсбука Меты, перебрался в криптостартап, а теперь еще завел телеграм-канал "Время Валеры".

Всегда рад рекламировать каналы корешей, если там теплится жизнь, т.е. сколько-то регулярно появляется годный контент. Надеюсь, когда-нибудь Валера публично расскажет хотя бы часть кулсториз, которыми он делился приватно - например, как эффективно работать на трех работах и не поехать кукухой, или как справляться с тем, что твой подчиненный называет коллег "ебаными гуманитариями".
Очень хорошая статья со слегка пафосным названием A ConvNet for the 2020s.

TL;DR: чувакам надоел хайп vision трансформеров, и они решили сделать сверточные сети great again. Для этого они проанализировали, в чем же могут быть сильные стороны трансформеров, и попытались воспроизвести аналогичные преимущества в классической сверточной архитектуре (Resnet), что им в основном удалось.

Статья хороша не столько результатом (кого сейчас удивишь очередными 82+% точности на Imagenet), сколько стилем изложения. Авторы описали траекторию исследования и соответствующие кумулятивные улучшения, а не продемонстрировали очередную серебряную пулю из ниоткуда. Отдельный лайк за Robustness Evaluation в приложении.
В далеком 2018 мы с коллегами делали proof of concept сервиса по оценке размера кольца. Точнее, "мы с коллегами" на тот момент в основном означало, что Андрей рисовал на доске геометрические формулы и писал тонны кода, а я приставал к нему с туповатыми вопросами и иногда коммитил инфраструктурные мелочи. Сценарий простой: для онлайн-продаж ювелирки одна из проблем вызвана тем, что пользователи не знают размер своего пальца (или пальца своего партнера), и потому не могут опасаются заказывать кольцо в интернет-магазине. Для дорогих товаров магазины бесплатно высылают специальные мерные кольца, для дешевых - советуют разные эвристики типа "обмотай палец ниткой N раз, померяй использованную нитку линейкой и подставь результат в формулу". Примечание про несколько измерений, кстати, важно: это такой бутстраппинг курильщика, потому что единичные измерения слишком шумные.

Наш подход cтроился на фотографии руки на листе бумаги А4, для которого известен размер, а значит - есть референс для калибровки. Соответственно, можно найти нужный палец, определить его размер в пикселях и перевести в мм. В итоге дальше прототипа дело не пошло по двум причинам. Во-первых, медианная ошибка нашего подхода получалась около 0.4 мм, а это примерно шаг размера, т.е. точность недостаточна. Даже увеличение датасета не спасало ситуацию, т.е. говоря умными словами, большая часть ошибки отражала aleatoric uncertainty. Во-вторых, тестовые пользователи игнорировали инструкции и фотографировали руки на чем угодно (например, на мятых салфетках), но не на ровном листе А4. В итоге направление было деприоритезировано, но многие наработки оттуда были успешно использованы в другом, гораздо более успешном проекте.

И вот прошло четыре года, и я снова делаю измерение физического размера по фотографии, на этот раз сугубо своими руками. На этот раз права на ошибку меньше - в этой нише пользователей интересует точность в микронах. Но общий уровень сложности как будто снизился: сабпиксельная точность четыре года назад оказалась нерешенной задачей, а сейчас уже почти получается. Конечно, не стоит приписывать все заслуги себе: камеры стали лучше, from pretrained_sota import SuperbModel точнее, а итерации на современных GPU и с современными инструментами - быстрее.
2025/07/02 02:28:41
Back to Top
HTML Embed Code: