Привет! Меня зовут Дима и я веду канал про соревновательный МЛ. Недавно мы выиграли приз в довольно престижном соревновании и я сделал обзор всех лучших решений
Хочу вам рассказать о Open Problems, где не удалось взять золото, но все равно все очень довольны, ведь мы взяли 13 место и специальные приз жюри, который позволил нам выступить на NeuralIPS.
Начнем с краткого описания соревнования:
Компания-организатор занимается тем, что пытается оптимизировать проведение дорогостоящих экспериментов с препаратами на живых, но отделенных от самих созданий клетках 🧪 (in vitro) 🧪. У клеток много разных типов и препарат лечащий одну клетку мог спокойно убить все клетки другого типа в том же организме. Взяли много таких экспериментов, в том числе контрольные. Можно увидеть на картинке подробности того, как проводился тест
И того на вход у нас есть:
1. Химическая формула препарата (строка в формате SMILES)
Например вот так записывается Л-аланин: N[C@@H](C)C(=O)O
Сейчас пойду завтракать и его есть
2. Тип клетки, которая будет воздействовать на препарат (просто название-категориалка)
Пример T cell CD8+, надеюсь к меня их очень много. Они убивают рак
Все, больше ничего нет. Есть только таргеты. Таргеты забавные:
Для каждого эксперимента замеряли экспрессию генов и прогнали ее через эконометрически-биоинформатическую модель-пакет из R под названием Limma (Linear Models for Microarray Data) сравнивая с контрольным экспериментом. Взяли diff p-value изменений каждого гена и их логарифмировали и умножили все это дело на знак изменения (уменьшение- минус, увеличение плюс).
Седьмое место:
Мужчина с седьмого места был прямолинеен и верил в лучшее:
Он взял статью о том, как учить эмбединги для препаратов и... выучил их.
Для трехмерной матрицы (экспрессия гена, позиция в клетке, тип клетки) градиентным спуском учится факторизация, а затем поверх этих эмедов уже учится взаимодействие гена в клетке с препаратом уже другой сетью.
Прием можно представить как нормализацию для каждого триплета взаимодействий, а затем доучивание того, как всю эту великолепную микровселенную меняет препарат.
Шестое место:
Муж с 6 места, наоборот, поступил в лучших традициях Александра Геннадьевича:
Разобрался с пакетом Limma на R:
1. Обучил Limma на трейне
2. Предсказал тест
3. Понял, что цифры на трейне не совсем сходятся
Понял, что Limma была обучена на трейне и тесте одновременно (так правильно, это же эконометрическая модель!), а он учился только на трейне.
4. Вспомнил два ключевых слова и одно секретное (среднее, дисперсия и таргет-лик) и домножил на коэффициенты параметры линейной модели, чтобы цифры сходились.
5. Посчитал обратное преобразование из получившейся модели
Таким образом он получил пайплайн восстановления оригинальных экспрессий генов и получил великолепное свойство для таргетов:
Теперь таргеты были не из островершинного распределния, а из вполне себе нормального. Но эта моделька хорошо перформила на private test, на лб она работала средне. Тем ценнее вера в себя и в свою схему валидации!
Поэтому на всякий противопожарный случай, автор сблендил решения еще и с моделью, учащейся на обычные таргеты.
Из интересных штук, которые можно себе унести в любые соревнования/продакшны: учился в обеих моделях на Smooth L1 loss и клянется, что это сильно помогло на лб и валидации, еще и стабильности добавило.
Третье место:
Все пошло уже мощным и грамотным заливанием ресурсов:
1. Человек взял маленькую нейростеку и оптимизировал ее ширину/длину/место для батчнормов/место для дропаутов/место для леернормов c помощью оптуны
2. Из получившихся хороших сеток собрал ансамбль, для которого веса тоже оптимизровал оптуной.
3. Для этого ансамбля предсказал тест и взял результат как псевдолейблы 🤍️, для которых веса при обучении тоже оптимизировал (конечно оптуной).
Тут интересно: вес для всех псевдолейблов был глобальный, т.е. в обучение добавлялись вообще все предикты теста, но с одинаковым весом и никак не оценивалась 'уверенность' в предикте.
4. Затем собрал ансамбль назад и обучил его 20 раз, после чего взял медиану аутпута по каждому гену
Ставки на то, сколько терафлопс-часов потратил гений оптимизации- пишите в комментарии
Второе место:
На втором месте у нас несколько удачных находок:
Оригинальная стратегия валидации:
Автор применил подход к валидации, где кластеризовал многомерные таргеты с использованием K-means. Для кросс-валидации он затем равномерно семплировал данные из получившихся кластеров. Таким образом, в каждом фолде кросс-валидации получались похожие глобальные, но различные локальные распределения таргетов. Мы также попытались использовать схожий метод, семплируя по типам клеток, что также добавило стабильности валидации. Размер валидационных фолдов был подобран вручную в пределах 10% - 20%, лучшим был размер 10%, что докидывало немного скора
Фичегенерация:
1. Добавлен mean-target-encoding для типов клеток и драгов, что заметно улучшило производительность моделей.
2. Применен TruncSVD для преобразования таргетов, и обнаружено, что некоторые семплы имеют значительную дисперсию для TruncSVD, что было использовано как отдельная фича. Подобный прием с включением Var таргетов в фичи я уже пар раз видел в топовых решениях, хотя определение правила для применения трюка остается открытым вопросом.
Модель:
Обучал собственный трансформер. Архитектура была относительно простой, включая два эмбединга для континуальных и категориальных признаков, два линейных слоя для них, LayerNorm, линейный слой на конкатенации и трансформерный энкодер с GELU, завершенный линейным слоем для вывода. Мы пробовали похожие архитектуры, но без энкодера от трансформера. Кстати другие места тоже говорили о том, что пробовали трансформеры и у них не завелось.
Для оптимизации использовался Lion. Он прям хорошо работает для трансформеров. Ну и Huber Loss для применял для смягчения воздействия выбросов и улучшения общего качества.
Первое место:
🥇 🏆Победитель соревнования скорее удивил своей находчивостью и упорством
Фичи:
В первую очередь он вспомнил о статье из Nature: BioWordVec, improving biomedical word embeddings with subword information and MeSH
Идея статьи: обучим на заголовках статей/терминов word2vec и в нем будет крыться некоторая близость терминов.
Помните, что как входные данные были доступны только название лекарств, их формулы и типы клеток? Победитель пошел на вики и спарсил для каждого препарата и каждого типа клеток их короткое описание. Там, где описания не находились по обычному названию- он шел и руками находил релевантные или сам дописывал тексты. А вот уже эти описания он прогнал через BioWordVec.
И уже из этих векторов эмбедингов набутстрапил финальные эмбединги для каждого терма. Одним из параметров подбора было 'сколько предложений из описания термина бутстрапить'.
2. Взял признаки из ChemBert, которые тоже являются некоторым текстовым специализированным представлением для лекарств. Эти эмбединги были не очень стабильны и об их использование многие сломали копья. (и мы тоже) У автора пайплайн с этими эмбедингами завелся от добавления target-quantile-encoding для каждого из лекарств.
Валидация:
Без сложных приемов. Просто заметил дисбаланс клеток в некоторых фолдах и стратифицировал по типам клеток. Всего 5 фолдов. И это очень странно, построить хоть как-то коррелирующую с лб валидацию здесь было довольно сложно. Но автора и шейкнуло на 258 мест вверх.
Модели:
1d-CNN/GRU/LSTM архитектуры на его sequence фичах. Особых находок в арихетктуре нет. Но есть в лоссах, их тут целый зоопарк:
LogCoshLoss + MSE + L1 + BCE
1. Если с последними тремя все понятно, то вот первый это что-то редкое и авторское (на картинке)
Автор объясняет его как MAE, но более гладкий и взятый вот отсюда.
2. BCELoss предсказывал направление изменения эксперсии гена, что можно засчитать за декомпозицию постобработки таргета. Подробнее вот тут.
3. Оптимизатором использовался ванильный Adam, ничего особенного.
Что можно унести себе:
1. LogCoshLoss как более гладкий вариант MAE
2. Оригинальные ходы по обогащению данных иногда хорошо заходят и в этом направлении нужно думать
3. Иногда вас шейкапает на 258 мест из грязи в князи с призовыми в $12к и победу на NIPs сореве.
Спасибо за чтение и подписывайтесь на мой Псевдолейблинг!