При работе над проектами машинного обучения создается впечатление, что мы потратим большую часть времени на кодирование волшебных моделей для решения нашей проблемы. К сожалению, это далеко от реальности, особенно для машинного обучения, применяемого к данным наблюдения Земли (EO). Проект машинного обучения обычно включает в себя несколько компонентов, таких как сбор данных, исследовательский анализ данных (EDA), извлечение признаков, предварительная обработка, управление машинными ресурсами, обслуживание и т. д. Для машинного обучения, применяемого к данным EO, отсутствие стандартизированного способа запуска экспериментов с машинным обучением ограничивает воспроизводимость экспериментов, а также обмен данными и моделями. Более того, современные конвейеры машинного обучения позволяют проводить эти эксперименты в масштабе и, следовательно, легко тестировать несколько моделей.

Конвейеры ML не часто используются с данными EO, и большинство доступных примеров рабочих процессов ML сосредоточены на наборах данных с основными этапами подготовки и предварительной обработки данных. Наборы данных EO требуют дополнительного программного обеспечения и библиотек для обработки и извлечения признаков, таких как GDAL, Geopandas, shapley, fiona, rasterstats. Более того, почти нет готовых к использованию наборов данных, таких как набор данных CIFAR и наборы данных EO, которые, как известно, имеют большой размер и имеют несколько поставщиков данных (для изображений Sentinel-2 я могу перечислить более 5)!

В этом посте мы сосредоточимся на использовании конвейеров Kubeflow в наборах данных Sentinel-2. Пост разделен на несколько частей:

  • Что такое Kubeflow? зачем его использовать?
  • Что представляет собой конвейер Kubeflow?
  • Начало работы с установки Kubeflow на локальном компьютере
  • Пример конвейера для классификации типов культур с использованием изображений Sentinel-2 и набора данных о границах полей из Национального института географической и лесной информации во Франции, включая загрузку изображений Sentinel-2 из Google Cloud Storage
  • Разверните обученную модель как сервис с помощью flask в Kubernetes

Что такое кубефлоу? зачем его использовать?

Kubeflow — это не зависящая от облака облачная платформа, основанная на Kubernetes и работающая под управлением Argo, которая позволяет создавать конвейеры машинного обучения. Хорошая новость заключается в том, что если вы знакомы с Docker и Python, вы можете начать с Kubeflow. Мы используем Kubeflow для организации рабочих процессов машинного обучения, совместного использования и повторного использования компонентов машинного обучения, а также для экспериментов с несколькими моделями и наборами данных. Kubeflow можно запускать на локальном компьютере (например, ноутбуке), локально, GCP, AWS и т. д., поэтому конвейеры переносимы.

Что делает конвейер Kubeflow?

  • Группа задач, каждая задача отвечает за определенное действие в нашем конвейере (например, загрузка данных, извлечение признаков, классификация, оценка)
  • Укажите, как связаны задачи и их последовательность
  • Входные параметры для конвейера

Начало работы с установки Kubeflow на локальном компьютере

  • Скачайте kind для запуска локальных кластеров Kubernetes. Для Linux

Для других ОС отметьте вид быстрого старта. Мы предполагаем, что docker и kubectl уже установлены.

  • Создайте кластер, используя kind
  • Установите конвейеры Kubeflow, установка занимает несколько минут после запуска этой команды.
  • После завершения установки вы можете проверить развернутые службы и использовать переадресацию портов, чтобы получить доступ к службе, на которой размещена панель мониторинга конвейеров Kubeflow.
  • Откройте http://localhost:8080 в браузере, должно появиться что-то вроде этого

Пример конвейера для классификации культур на основе данных Sentinel-2

Цель этого пайплайна — классифицировать два типа сельскохозяйственных культур (пшеницу и кукурузу) с использованием данных Sentinel-2 L2A. Изображения Sentinel-2 будут загружены из облачного хранилища Google, поля для обучения извлечены из национальной французской базы данных под названием Registre Parcellaire Graphique (RPG). Наш фрагмент Sentinel-2 представляет собой T31TCJ, в котором расположена Тулуза, столица аэронавтики и космической промышленности. Входные данные для этого пайплайна доступны здесь:

  • Файл изображения JSON: изображения Sentinel-2 T31TCJ для загрузки (доступны здесь)
  • Шейп-файл с примерами полей пшеницы и кукурузы для обучения (доступен здесь)

Давайте посмотрим на конвейер, который мы собираемся построить, прежде чем вдаваться в подробности.

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

  • Предварительно созданные компоненты: они уже являются докеризированными компонентами, которые можно напрямую использовать в конвейере, используя только их файл конфигурации YAML.
  • Компоненты на основе функций Python: для облегченных пользовательских компонентов мы отвечаем только за написание нашей функции Python. Kubeflow сделает все остальное.
  • Пользовательские компоненты: для большей гибкости, когда вы можете использовать любой язык программирования. Однако мы несем ответственность за кодирование, докеризацию и создание файла конфигурации YAML нашего компонента.

В этом конвейере мы будем использовать пользовательские компоненты несколько раз, а также компоненты на основе функций Python.

Как видно на следующем рисунке, у каждого пользовательского компонента есть своя папка. Эта папка содержит код Python, файл Dockerfile и файл YAML. Давайте пока проигнорируем папку deploy_xgb.

Загрузить изображения Sentinel-2 (папка process_img)

  • process_img.py

Этот сценарий имеет в качестве входных данных файл JSON, содержащий изображения Sentinel-2 L2A, которые необходимо загрузить из Google Cloud Storage, и шейп-файл полей примеров. Загрузка выполняется изображение за изображением, чтобы не исчерпать ресурсы хранилища. Затем рассчитывается индекс нормализованной разности растительности (NDVI), и статистические данные вычисляются с использованием каждого полигона на уровне поля. Это стандартный скрипт Python с переданными ему аргументами. Вы можете проверить это локально с помощью этой команды

python3 process_img.py --json_data https://storage.googleapis.com/gcp-ml-88/response_1641976752143.json --shp_fname https://storage.googleapis.com/gcp-ml-88/T31TCJ_MIS_BTH --output_path /data/test_pipeline
  • Файл Docker

Следующим шагом будет создание Dockerfile. Обратите внимание, что мы копируем исходный код process_img.py внутрь

с этими требованиями

Здесь мы используем некоторые библиотеки для обработки спутниковых изображений и наборов векторных данных, таких как GDAL и geopandas. Создайте образ докера и отправьте его в свой реестр докеров. Я уже отправил эти образы в Docker Hub, и они общедоступны.

docker build . -t YOUR-USER/process-img:latest
docker push YOUR-USER/process-img:latest
  • process_img.yaml

Этот файл начинается с имени, которое отображается в узле на панели управления для этой задачи и описания. Входы и выходы определяют вход и выход этого конвейера. Реализация — это то, что мы собираемся запустить для этого компонента. Он содержит образ докера, доступный в концентраторе докеров, который мы только что отправили, команду для запуска и аргументы скрипта python.

Обратите внимание на использование ключевых слов, inputValue, inputPath и outputPath. Они используются Kubeflow для определения входных и выходных данных и их распространения между различными компонентами. inputValue является заполнителем для значения, тогда как inputPath и outputPath являются заполнителями для файлов.

Ранее мы говорили о совместном использовании и повторном использовании компонентов в наших рабочих процессах машинного обучения. С помощью этого файла конфигурации YAML мы можем поделиться нашим компонентом с коллегой, не передавая ему коды, файлы докеров и так далее.

Если вы хотите интегрировать GCP BigQuery на этом этапе, чтобы вы могли запрашивать изображения по диапазону дат вместо предоставления списка изображений, проверьте это репозиторий.

  • Построить временную статистику NDVI (папка темпоральная_статистика)

Полный код этого компонента доступен на github. Поэтому я просто опишу, что делает этот компонент. Он принимает в качестве входных данных выходные данные предыдущего компонента (файл, содержащий статистику для каждого изображения), объединяет статистику по дате изображения и сохраняет результат в виде GeoDataFrame. Мы выполняем те же шаги, чтобы создать этот компонент (скрипт Python, Dockerfile и конфигурация YAML).

  • Подготовить данные классификации культур (папка preprocess_data)

Этот компонент выполняет предварительную обработку набора данных временных рядов для восстановления отсутствующих данных с использованием алгоритма knn. Затем он разделяет набор данных на данные для обучения и тестирования с помощью scikit-learn. Одной из основных целей создания конвейеров машинного обучения является воспроизводимость результатов. Поэтому при разбиении нашего набора данных мы фиксируем случайное начальное число, чтобы каждый раз при запуске кода мы получали одно и то же разбиение. Таким образом, можно сравнивать разные прогоны.

  • Классификатор и настройка XGBoost

Этот компонент реализует обучение алгоритма XGBoost и выполняет этап настройки гиперпараметров с помощью случайного поиска. Эта задача принимает в качестве входных данных обучающие данные, подготовленные на предыдущем шаге в виде фрейма данных geopandas, логическую переменную для выполнения настройки гиперпараметров или нет, количество итераций и перекрестных проверок, которые необходимо выполнить. Выходными данными являются модель, отчет о классификации и два других артефакта, называемых mlpipeline-ui-metadata и mlpipeline-metrics. Здесь мы сосредоточимся на них, так как все остальное похоже на предыдущие компоненты (Dockerfile).

Kubeflow позволяет передавать некоторые данные из компонентов в другие встроенные компоненты для визуализации и мониторинга метрик модели (см. рисунки ниже).

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

В разделе выходных данных выходным именем метаданных для визуализации должно быть «mlpipeline-ui-metadata», а выходным именем метрик должно быть «mlpipeline-metrics». Это позволяет kubeflow находить эти данные для визуализации и мониторинга показателей. Обратите внимание, как мы назначаем эти переменные скрипту Python для запуска в строках 32–35 в файле YAML.

Второй шаг — создать два выходных файла JSON для mlpipeline-ui-metadata и mlpipeline-metrics. Эти файлы JSON имеют особый формат (см. документацию Kubeflow и эту ссылку). Однако в коде я создал две функции для автоматического создания этих файлов JSON из данных. Обратите внимание, что ключи в этих JSON-файлах не должны содержать заглавных букв для какой-либо версии Kubeflow, иначе он не сможет ее интерпретировать.

  • Классификатор и настройка LSTM

Это очень похоже на предыдущий компонент, но одной особенностью является использование оболочки kerasclassifier вокруг нашего LSTM, чтобы использовать случайный поиск для настройки гиперпараметров. Обратите внимание, что задача, созданная из этих компонентов, будет выполняться параллельно с задачей XGBoost и будет использовать те же входные данные. Это очень важно для масштабирования экспериментов с различными моделями (спасибо Kubeflow!)

  • Сравнить модели

Последний компонент является базовым, который будет сравнивать показатели лучших моделей XGBoost и LSTM, которые будут использоваться, например, в производстве. Функциональность этого компонента очень проста. Наши отчеты в формате CSV, поэтому нам нужно только открыть файл CSV и получить значение внутри него, и все. Вместо того, чтобы усложнять эту простую задачу, используя пользовательский компонент, можно использовать компонент на основе Python. Единственное, что нужно сделать, это написать функцию для выполнения и использовать «kfp.components.create_component_from_func» из kfp SDK. При его вызове мы указываем используемую функцию Python, устанавливаемые зависимости и базовый образ докера.

Наши компоненты готовы к использованию в конвейере. Следующим шагом является определение того, как они связаны, и их последовательности. Мы можем сделать это на Python, используя Kubeflow SDK. Мы пишем функцию Python и используем декоратор «dsl.pipeline». Входные параметры этой функции являются входными данными для нашего конвейера.

Чтобы использовать компонент в конвейере, прежде всего мы используем «kfp.components.load_component_from_file» для импорта нашего компонента в конвейер. Мы даем ему путь к нашему файлу конфигурации YAML компонента. На втором этапе мы создаем задачу, используя импортированный компонент.

Чтобы передать выходные данные задачи «download_task» в качестве входных данных для другой задачи с именем «test_task», мы делаем

test_task = test_component(download_task.output)

Если у нас есть несколько выходов, мы можем указать, какой из них использовать «TASK_NAME.outputs[«OUTPUT_NAME»]»

Наконец, мы компилируем наш конвейер, чтобы преобразовать его в файл YAML, используя

kfp.compiler.Compiler().compile(crop_classification_pipeline, 'advanced-crop-classification-pipeline.yaml')

мы даем только функцию, в которой мы реализовали наш конвейер, и имя выходного файла. Полный сценарий конвейера приведен ниже.

В конвейере обратите внимание на использование этой строки кода

TASK_NAME.execution_options.caching_strategy.max_cache_staleness = "P0D"

Kubeflow использует кеширование результатов успешных запусков, поэтому задачи не запускаются повторно. Эта строка заставляет Kubeflow игнорировать кеш и выполнять задачу в любом случае.

Последний шаг — загрузить наш пайплайн в Kubeflow. Это можно сделать программно или с помощью панели инструментов Kubeflow. Как только конвейер загружен, мы готовы создать прогон.

На этапе производства модель может быть развернута как сервис в кластере Kubernetes. Для этого используемую модель можно загрузить из результатов запуска нашего конвейера. Код обслуживания доступен в папке deploy_xgb, где мы используем Flask API с методом POST для получения прогноза. Код Python представляет собой базовое приложение для фляг. Мы готовим Dockerfile, который устанавливает необходимые зависимости, и копируем внутрь исходный код нашего приложения Flask. Мы создаем образ и помещаем его в наш реестр докеров. Наконец, мы создаем наш файл конфигурации YAML для службы и развертывания нашего приложения.

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

kubectl apply -f FILE_NAME.yaml

Если вы запустите эту команду

kubectl get services --namespace kubeflow

вы должны найти развернутую службу xgb. Мы будем использовать информацию, отображаемую в PORT (например, 5000:30967/TCP).

Получите внутренний IP-адрес кластера, используя

kubectl get nodes -o wide

Предположим, внутренний IP-адрес — 172.19.0.2. Отправьте запрос к вашей развернутой модели в python, используя этот фрагмент кода, где мы отправляем временную серию значений NDVI, связанных с полем, в нашу развернутую модель для классификации

Это все для этого варианта использования!

Давайте завершим некоторые важные моменты

  • Машинное обучение для наблюдения за Землей — быстро развивающаяся область. Однако отсутствие стандартных рабочих процессов экспериментов с машинным обучением замедляет этот рост.
  • Kubeflow a — это бесплатная платформа с открытым исходным кодом для конвейеров машинного обучения. Он позволяет организовывать рабочие процессы машинного обучения, экспериментировать с несколькими моделями, совместно использовать компоненты и запускать машинное обучение в любом масштабе.
  • Если вы знаете, как работать с Python и Docker, вы легко сможете начать работу с Kubeflow.
  • Компонент — это основа пайплайнов Kubeflow. Существуют три типа с разными уровнями сложности и гибкости. Для обработки сложных данных, таких как спутниковые изображения, должны быть установлены определенные библиотеки и зависимости, такие как GDAL. Пользовательские компоненты обеспечивают высокий уровень гибкости для решения такой сложности.
  • Kubeflow позволяет отслеживать и визуализировать модели с использованием метрик и метаданных.
  • Чтобы поделиться своим конвейером, достаточно поделиться файлом YAML!
  • Конвейеры Kubeflow могут выполняться локально, локально, GCP, AWS и т. д.
  • Чтобы узнать больше обо всем этом, ознакомьтесь с Документацией по Kubeflow.