Привет, Хабр! Представляю вам перевод статьи.



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


0. TLDR


Ссылка на соревнование и подробное описание.


Быстрая картинка сайта, кому лень ходить.


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


Также я потратил некоторое время на написание хорошего читаемого кода на PyTorch и генераторов данных. Его можно без застенчивости использовать для своих целей (только поставьте плюсик). Код максимально простой и модульный, плюс читайте дальше про best practices для семантической сегментации.


Кроме того, не исключено, что мы напишем пост про понимание и разбор Skeleton Network, которую в итоге использовали все финалисты в топе соревнования для преобразования маски изображения в граф.


Суть соревнования
Суть соревнования на 1 картинке


1. Соревнование


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


В этом соревновании были все критерии:


  • Жесткий челлендж и высокая вероятность того, что команда ods.ai будет стоящим соперником (они участвовали в 3-4 соревнованиях со спутниками в 2017 году).
  • Соревнование требовало не только построить подходящую семантическую сегментацию изображения, но и построить граф из предсказанных масок. Это породило запутанную и интересную метрику (пост про нее раз, два, репа). Люди, которые пробовали код из репозитория, говорили мне, что тот питоновский код как-то сильно расходился у них с leaderboard, так что все в итоге использовали их тулзу для визуализации, написанную на Java.
  • Интересная область — спутниковые изображения с обильным количеством информации, примерно 4000 HD изображений из 4 городов в разных каналах (в основном у нас были хайрезы в чб, 8 канальные MUL изображения, pan-sharpened MUL изображения и обычные RGB).
  • Интересный данные (графы, geojson, спутниковые снимки) и новая область поисследовать (TLDR — можно использовать skimage и rasterio — все остальные библиотеки из списка, предоставленного хостами — УЖАСНЫ). Также выяснилось, что skimage неплохо работает с 16-битными изображениями, tiff и другими странными форматами.
  • Я не могу понять, хорошо это или плохо, но платформа TopCoder требует от участников высокого уровня профессионализма (все ваши решения должны быть докеризированы, что очень скучно для меня, не по��ому что мне не нравится докер, а по сути потому, что орги хотят, чтобы мы за них еще и юнит тесты написали). Но сама платформа просто ужасна, и качество кода предоставленного ими мне показалось мягко говоря спорным. Меня это сильно раздражало — после того, как ты потратил кучу времени на собственно решение задачи, они просят тебя потратить еще больше времени на упаковку этого решения, когда само описание конкурса и код очень тяжело читать.

Мое краткое мнение о текущих популярных data science платформах:
  • Kaggle — куча стакерщиков, и в основном бизнес ориентированные задачи, по крайней мере в 2017 году.
  • TopCoder — иногда очень интересные и сложные нишевые задачи, но в целом платформа страшновата и требования к участникам высокие.
  • DrivenData — самая маленькая, но самая лучшая. Интересные области, отличные организаторы, которые делают свою работу и не требуют от тебя лишнего.

2. Быстро про первоначальный анализ данных и интересные краевые случаи




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


Вы можете видеть входные данные на картинке выше, но есть пару интересных моментов и заслуживающих внимание краевых случаев, которые объясняют, что же на са��ом деле происходит.



Гистограмма оригинала 16-битной картинки



Гистограмма 8-битной картинки, некоторая информация потерялась



Асфальтированные дороги против неасфальтированных



Пример асфальтированных дорог вместе с неафсальтированными плюс перекрестки



Комбинация дорожных полос — заметьте несколько 12 полосных дорог — на пропускных пунктах границ, я полагаю



Типичная разметка в Париже — не очень хорошая


3. Полезное чтение


Вот лист лучших материалов по теме, что я изучил во время соревнования.



Если суммировать все архитектуры и эксперименты, то выйдет что-то типа:


  • UNET + Imagenet неплохо, но LinkNet лучше (2 раза быстрее и легче с небольшой потерей точности);
  • Transfer learning обязателен и приводит к лучшему результату;
  • Skeleton Network лучшая тулза для превращения маски в граф, но требует некоторой настройки;


Unet + transfer learning



LinkNet



Некоторые ученые все еще используют MSE...


4. Начальные варианты архитектур и косячные кейсы


Очки на лидерборде начинались с 0 и до почти 900k для примерно 900 тестовых изображений, каждому изображению присваивалось 0 — 1. Финальная метрика считалась как среднее между городами, что было не очень, так как Париж опускал скор вниз очень существенно.



Распределение скора по тайлам для некоторых из наиболее эффективных моделей. В Париже много растительности и пригородных тайлов с плохой разметкой, которые влияют на скор. Кроме того, у Шанхая и Хартума более высокие расхождения между оценками t-p и p-t, то есть для модели намного проще убедиться, что все ребра графа верны, но гораздо труднее найти ВСЕ ребра графа, которые есть в природе


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


Loss функция


  1. BCE + DICE / BCE + 1 — DICE — показали себя более менее одинаковож
  2. Clipping loss функции тут показал себя ужаснож
  3. N BCE + DICE, BCE + N DICE — не работало в моем случае. Потом коллеги из чата подсказали, что мониторить надо не DICE, а hard DICE (по сути процент угаданных пикселей) и хорошо заходит 4 * BCE + DICE, с учетом того, что брать надо лучшую эпоху по hard DICE;

CNN


  1. LinkNet34 (Resnet34 + Decoder) — было лучшим по скорости и точности;
  2. Linknet50, LinkNext101 (ResNeXt + LinkNet), VGG11-Resnet — все показали себя одинаково, но требовали в 2-4 раза больше ресурсов;
  3. Все энкодеры были предобучены на ImageNet, ессно;
  4. Для 8-канальной сетки я просто заменил первый слой, но она вела себя более менее так же как и 3-канальная (но ела больше ресурсов CPU);

Обработка


  1. Бинаризация маски;
  2. Я сделал ablation анализ всех разумных комбинаций каналов — лучшими были растительность, rgb, 8 каналов, urban (смотрите чему они соответствовали в коде /src/presets.py) — но разница была минимальна (3-5%);
  3. Естественно HD изображения показали себя лучше;
  4. 8 и 16-битные изображения также показали себя более менее одинаково;
  5. Нормализация изображения — экстракция среднего и стандартного отклонения Imagenet дали +2-3% уменьшения функции потерь, но никакой разницы на лидерборде особо не было;

Маски


  1. Маска из APLS репы. 10% масок не создавалось, т.к. код организаторов не содержал обработки ошибок и там не было дорог. Сначала я не стал париться и включать их в тренировку, но потом вероятно это было моей ошибкой, хотя нормально это проверить я так и не смог;
  2. Просто загрузить линии в skimage и допилить примерно 10% пустых изображений — давало уменьшение loss-а, но влияние на итоговый результат было неясным;
  3. Тоже самое давали маски, где ширина дороги соответствовала ее реальной ш��рине — вроде лосс сходится лучше, но графы получаются не лучше. Вероятно hard DICE бы решил эту проблему;
  4. Модели для неасфальтированных дорог работали гораздо хуже, из-за плохих данных;
  5. Многослойные маски также не сработали (1 слой для перекрестков, 1 слой для грунтовых дорог, 1 слой для асфальтированных дорог);

Метамодели


Сиамские сети для уточнения предсказаний моделей на "широких" и "узких" масок тоже не сработали. Что интересно — предсказания моделей на "широких" масках выглядели гораздо лучше, но графы получались хуже.


Пайплайны


  1. 3 или 8 канальные изображения показали себя более менее одинаково;
  2. Развороты на 90 градусов, горизонтальные и вертикальные перевороты, небольшие аффинные преобразования снижали лосс еще на 15-20%;
  3. Моя лучшая модель была на полном разрешении, но случайные кропы 800x800 отрабатывались тоже хорошо;

Ансамблирование


3x фолда + 4x TTA ни дало никакого прироста в моем случае.


Еще всякие идеи, которые по видимому давали буст на LB моим конкурентам


  1. LinkNet34 (LinkNet + Resnet) => Inception encoder — +20-30k (я хотел попробовать Inception Resnet, но после ряда неудач отчаялся и не попробовал);
  2. На трейне — обучение на полном разрешении. На inference: downsize => predict => upsize => ensemble — +10-20k;
  3. Пост обработка графов и доведение их до краев тайлов — +20-30k;
  4. RGB изображения (в противовес MUL) — +10-15k из-за того что исходные данные были неконсистентными;
  5. 4 BCE + 1 DICE, мониторинг hard DICE в качестве метрики — +10-30k.


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



Основная причина почему широкие маски косячат — они производят полипы и осьминогов =)



Та же проблема



Париж — плохая разметка. Лесные области — также косячный кейс



Многоуровневые дороги — предсказание широкой модели против узкой



Модель придумала дороги поверх парковки =)



Иногда PyTorch глючил и рождал на свет такие артефакты


5. Построение графов и основные косячные кейсы


Ключевой ингредиент это Skeleton Network + добавить ребра графа для кривых дорог (спасибо Dmytro за его совет!). Одно это скорее всего гарантировало, что вы будете в топ-10.



Без этих шагов все маски выглядели вот так


Альтернативные пайплайны, которые я попробовал


  1. Скелетонизация+ corner detection из skimage
  2. Некоторая вариация dilation отсюда
  3. Все это производило какие-то ребра, но Skeleton Network все равно гораздо лучше

Дополнительные штуки, что иногда помогали другим участникам


  • Dilation как пред и пост обработка;
  • Доводить ребра графа до краев клеток;


Тулза для визуализации от оргов


6. Конечное решение



По сути замена для TLDR


7. Красивая визуализация — тайлы для всех городов собранные вместе


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


Картинки

Рассмотреть их в высоком разрешении можно по клику на них.



Vegas



Paris



Shanghai



Khartoum


Полезные и интересные ссылки из поста в одном месте: