Когда нужны результаты лучше, чем "удовлетворительно" Часть 1
Часть 2  Переход зоны из зимнего сезона в летний, составлено из изображений Sentinel-2. Можно заметить некоторые отличия в типах покрова по снегу, что описывалось в прошлой статье. Прошлые пару недель были весьма непростыми. Мы опубликовали первую и вторую части наших статей по поводу классификации покрова в масштабе целой страны при помощи фреймворка eo-learn. eo-learn — это библиотека с открытым исходным кодом для создания прослойки между получением и обработкой снимков со спутников и машинного обучения. В предыдущих статьях в примерах мы указывали только маленькое подмножество данных и показывали результаты лишь на малом проценте всей зоны интереса (AOI — area of interest). Знаю, это выглядит по меньшей мере не слишком впечатляюще, а возможно — весьма грубо с нашей стороны. Всё это время вас мучили вопросы, как можно использовать эти знания и перенести их на следующий уровень. Не волнуйтесь, именно для этого нужна третья статья в этом цикле! Хватайте чашку кофе, и присаживайтесь... Вы уже сидите? Может оставьте кофе на столе еще на секунду, потому что сейчас вы услышите лучшие новости за сегодня…
Мы в Sinergise решили опубликовать полный набор данных по Словении за 2017 год. Бесплатно. Вы беспрепятственно можете получить доступ к 200ГБ данных в виде ~300 фрагментов EOPatch, каждый примерно в размере 1000х1000, в разрешении 10м! Подробнее про формат EOPatch можете прочитать в прошлом посте про eo-learn, но по сути это контейнер для гео-темпоральных EO (Earth Observation) и не-EO данных: например, спутниковые снимки, маски, карты, и пр. 
Структура EOPatch) Мы не халтурили, когда загружали эти данные. Каждый EOPatch содержит изображения Sentinel-2 L1C, соответствующую им маску s2cloudless, и официальную карту покрова земли в растровом формате! Данные хранятся на AWS S3 по адресу: http://eo-learn.sentinel-hub.com/ Десериализация объекта EOPatch довольно проста: В результате вы получите объект следующей структуры: Доступ к разным атрибутам EOPatch осуществляется следующим образом: Отлично, данные загружаются. Пока мы ждём завершения этого процесса, давайте взглянем на возможности класса, который еще не обсуждался в этих статьях — EOExecutor. Этот модуль занимается выполнением и мониторингом конвейера и позволяет без лишних усилий использовать многопоточность. Больше никаких поисков на Stack Overflow о том, как правильно распараллеливать конвейер или как заставлять работать прогресс-бар в таком режиме — мы уже всё сделали за вас! Дополнительно, он обрабатывает возникающие ошибки и может генерировать краткую сводку о процессе выполнения. Последнее — важнейший момент для того, что бы быть уверенным в повторяемости своих результатов в будущем, что бы пользователю не пришлось тратить драгоценное рабочее время на поиск параметров, которые он использовал в прошлый четверг в 9 утра после целой ночи кутежа (алкоголь и программирование смешивать не стоит!). Этот класс также умеет генерировать приятный граф зависимости для конвейера, который вы можете показать своему боссу! 
Граф зависимости задач в конвейере, генерируемый eo-learn Как и обещали, эта статья в основном предназначена для исследования разных моделей с eo-learn используя предоставленные нами данные. Ниже мы подготовили два эксперимента, где мы изучаем влияние облаков и разных алгоритмов ресемплинга при темпоральной интерполяции на конечный результат. После всего этого, мы начнём работу со свёрточными сетями (CNN), и сравним результаты двух подходов — попиксельный анализ деревом решений и глубокое обучение при помощи свёрточных нейронных сетей. К сожалению, нельзя дать однозначный ответ по поводу того, какие решения следует принимать во время экспериментов. Вы можете глубже изучать предметную область и делать предположения для того, что бы решить, стоит ли овчинка выделки, но в конечном итоге всё равно работа будет сводиться к методу проб и ошибок. Облака — огромная боль в мире EO, особенно если речь заходит об алгоритмах машинного обучения, где хочется их определить и убрать из набора данных для проведения интерполяции по пропущенным значениям. Но насколько большая выгода от этой процедуры? Стоит ли оно того? Rußwurm и Körner в статье Multi-Temporal Land Cover Classification with Sequential Recurrent Encoders даже показали, что для глубокого обучения процедура фильтрации облаков возможно абсолютно неважна, поскольку классификатор сам способен обнаруживать облака и игнорировать их. 
Активация входного слоя (сверху) и модуляционного слоя (снизу) на последовательности снимков определённого фрагмента для нейронной сети. Можно заметить, что этот фрагмент сети научился сам создавать маски облачности и фильтровать полученные результаты. (Страница 9 в https://www.researchgate.net/publication/322975904_Multi-Temporal_Land_Cover_Classification_with_Sequential_Recurrent_Encoders) Вкратце напомним структуру шага фильтрации данных (подробности в [предыдущей статье]()). После получения снимков Sentinel-2 мы начинаем фильтровать облачные снимки. Отсеиванию подлежат все снимки, в которых количество не-облачных пикселей не превышает 80% (пороговые значения могут отличаться для разных зон интереса). После этого, для получения значений пикселей в произвольные дни, используются маски облачности для того, что бы не учитывать такие данные. Итого, возможны четыре варианта поведения: 
Визуальное отображение стека изображений со спутника Sentinel-2. Прозрачные пиксели слева подразумевают пропавшие пиксели ввиду облачности. Стек по центру показывает значения пикселей после фильтрации снимков и их интерполяции с маской облачности (Случай 4), а стек справа показывает результат интерполяции в случае без фильтрации снимков и без масок облачности (1). (Прим. пер. — судя по всему, в статье опечатка, и подразумевалось наоборот — по центру случай 1, а справа — 4). Мы в прошлой статье уже выполняли вариацию случая 1 и показали результаты, так что будем использовать их для сравнения. Подготовка других конвейеров и тренировка модели звучит как не сложная задача — надо лишь убедиться, что мы сравниваем правильные величины. Для этого, достаточно взять один и тот же набор пикселей для тренировки и валидации модели. Результаты указаны в таблице ниже. Можно заметить, что в целом влияние облаков на результат работы модели достаточно низок! Это может быть связано с тем, что референсная карта очень хорошего качества и модель способна игнорировать большую часть снимков. В любом случае, такое поведение нельзя гарантировать для любой AOI, так что не торопитесь выбрасывать этот шаг из своих моделей! Выбор параметров темпорального ресемплинга не очевиден. С одной стороны, нам необходим детальный массив изображений, которые хорошо демонстрируют детали исходных снимков — хочется включить максимально близкое количество снимков к исходным данным. С другой стороны, мы ограничены вычислительными ресурсами. Уменьшение шага ресемплинга в два раза увеличивает количество кадров после интерполяции, и таким образом увеличивает количество признаков, которые используются при тренировке. Стоит ли подобное улучшение результата затраченных ресурсов? Это нам и предстоит узнать. Для этого эксперимента, будем использовать вариацию 1 из предыдущего шага. После интерполяции, мы совершаем ресемплинг со следующими вариациями: Выборка в случае 3 базируется на самом большом количестве общих дат для всех EOPatch в выбранной AOI

График показывает количество фрагментов EOPatch, которые содержат данные за каждый день 2017 года (синий). Красными линиями показаны оптимальные даты для ресемплинга, которые базируются на датах снимков Sentinel-2 для заданной AOI 2017 года. Взглянув на таблицу ниже, можно заметить, что результаты не слишком впечатляющие, как и в прошлом опыте. Для случаев 2 и 3 количество затраченного времени вырастает примерно вдвое, но при этом разница с начальным подходом составляет меньше 1%. Подобные улучшения слишком незаметны для практического применения, так что можно считать 16-дневный интервал подходящим для задачи. Результаты общей точности и взвешенных F1 для разных конвейеров с изменением подхода к ресемплингу. Глубокое обучение стало стандартным подходом к многим задачам, таким как компьютерное зрение, обработка текстов на естественных языках, и обработка сигналов. Это связано с их способностью выделять шаблоны из сложных многомерных входных данных. Классические подходы машинного обучения (такие, как деревья решений) использовались во многих задачах, связанных с темпоральными геоданными. С другой стороны, свёрточные сети использовали для анализа пространственной корреляции между соседними снимками. В основном, их применение ограничивалось работой с единичными снимками. Мы хотели изучить архитектуру моделей глубокого обучения, и попробовать подобрать такую, которая способна анализировать как пространственные, так и темпоральные аспекты спутниковых данных, одновременно. Для этого, мы использовали темпоральные полносвёрточные сети (Temporal Fully-Convolutional Netvork, TFCN), а точнее, темпоральное расширение к U-Net, реализованную в TensorFlow. Если точнее, архитектура использует пространственно-временные корреляции для улучшения результата. Дополнительным преимуществом также является то, что структура сети позволяет лучше представить пространственные отношения в разных масштабах благодаря процессу кодирования\декодирования в U-net. Так же, как и в классических моделях, на выходе мы получаем двухмерную матрицу меток, которую будем сравнивать с истиной.  Натренированную модель мы использовали для предсказания меток на тестовом множестве, и полученные значения проверили с истиной. В целом точность составила 84.4% и F1 была равна 85.4%.  Сравнение разных предсказаний для нашей задачи. Визуальное изображение (левое сверху), истинная референсная карта (справа сверху), предсказание модели LightGBM(снизу слева) и предсказание при помощи U-net(снизу справа) Эти результаты показывают лишь начальную работу над настоящим прототипом, который крайне не оптимизирован для текущей задачи. Несмотря на это, результаты сходятся с некоторыми статистиками, полученными в области. Для раскрытия потенциала нейронной сети необходима оптимизация архитектуры (набор признаков, глубина сети, кол-во свёрток), а также настройка гиперпараметров (скорость обучения, кол-во эпох, взвешивание классов). Мы рассчитываем углубиться в эту тему (ха-ха) еще сильнее, и планируем распространить наш код, когда он будет в приемлемом виде. Можно придумать множество способов улучшить текущие результаты, но мы не можем ни перебрать, ни попробовать их все. Именно в этот момент на сцене появляетесь вы! Покажите, что вы можете сделать с этим набором данных и помогите нам улучшить результаты! Например, один из наших коллег в ближайшем будущем будет заниматься классификацией покрова, основываясь на темпоральном стеке отдельных изображений при помощи свёрточных сетей. Идея в том, что некоторые поверхности, например, искусственные, можно отличить без темпоральных признаков — достаточно пространственных. Мы будем рады написать отдельную статью, когда эта работа приведёт к результатам! К сожалению, следующая часть этого цикла статей не вышла, а значит, примеров исходного кода с построением U-Net авторы не показывали. Как альтернативу могу предложить следующие источники: Программист