Классификация изображений на видеокадрах
Yandex DataSphere позволяет строить модели машинного обучения, используя интерфейс Jupyter Notebook в Yandex Cloud.
В этом сценарии решена задача бинарной классификации изображений. Такая задача возникает при определении типа транспортного средства по изображению с камеры видеонаблюдения. Предполагается, что система управления видеомониторингом захватывает изображения с камеры при обнаружении движения. Далее изображения передаются в S3-бакет.
Чтобы познакомиться с решением задачи:
- Установите зависимости.
- Загрузите и разметьте данные.
- Подготовьте ML-модель и вычислите признаки.
- Обучите классификатор на полученных признаках.
- Получите результаты предсказания признака на тестовом изображении.
- Посмотрите варианты практического применения модели.
Перед началом работы
-
Создайте S3-бакет. Загрузите в него изображения для обучения модели из каталога по ссылке.
-
Создайте сервисный аккаунт.
-
Назначьте роль
storage.viewer
сервисному аккаунту для доступа на чтение объектного хранилища, в котором создан бакет. -
Создайте статический ключ доступа.
-
Сохраните статический ключ доступа в файл:
[default] aws_access_key_id=<идентификатор статического ключа> aws_secret_access_key=<секретный ключ>
-
Создайте проект в DataSphere и откройте его.
-
Склонируйте Git-репозиторий, в котором находятся ноутбуки с примерами обучения и тестирования модели машинного обучения:
https://github.com/MaxKhlupnov/ImageClassificationML
Дождитесь окончания клонирования, это может занять некоторое время. После завершения операции в блоке File Browser появится каталог склонированного репозитория.
-
Откройте каталог ImageClassificationML и затем файл
yc.config
. Замените содержимое файла строками из локального файла со статическим ключом доступа. -
Откройте каталог ML и затем ноутбук model-building.ipynb.
Примечание
Если вы обновите вкладку браузера, на которой запущен ноутбук, или закроете ее, то состояние ноутбука сохранится. Переменные и результаты уже сделанных вычислений при этих действиях не сбрасываются.
Установите зависимости
-
Выделите первую ячейку, кликнув на нее:
#!g1.1 %matplotlib inline import matplotlib import matplotlib.pyplot as plt import os import io from os import path ...
-
Запустите выделенную ячейку, выбрав в меню Run → Run Selected Cells (также можно использовать сочетание клавиш Shift+Enter).
-
Дождитесь завершения операции.
В решении используется интерфейс Keras библиотеки TensorFlow с CNTK-бэкендом. Пакет boto3
используется для подключения к S3-бакету как источнику изображений. Также в ячейке задаются переменные окружения, необходимые для работы с CNTK-бэкендом и подключения к S3-бакету.
Указанные в ячейке пакеты уже установлены в DataSphere и импортируются с помощью команды import
. Полный список предустановленных в DataSphere пакетов см. в разделе Список предустановленного ПО.
Примечание
Эта и последующие ячейки используют конфигурацию вычислительных ресурсов g1.1 для ускорения загрузки и обучения модели. Подробнее см. в разделе Конфигурации вычислительных ресурсов.
Загрузите и разметьте данные
Перейдите к разделу Функции для подключения к S3. В нем выполняются следующие операции:
- Настраивается подключение к S3-бакету.
- Загружается список объектов (изображений) автомобилей и автобусов. Они будут использоваться при обучении модели.
- Определяется функция для извлечения изображения по ключу (названию).
В следующем разделе Маркировка выполняется разметка данных:
- Изображения маркируются в соответствии со значением ключа (именем папки).
- Изображения автобусов помечаются меткой
0
, автомобилей —1
.
Чтобы загрузить и разметить данные:
-
Выделите все ячейки с кодом в разделах Функции для подключения к S3 и Маркировка, удерживая Shift и кликая слева от нужных ячеек:
#!g1.1 session = boto3.session.Session() ...
-
Запустите выделенные ячейки.
-
Дождитесь завершения операции. По завершении операции выводится одно из изображений для проверки корректности загрузки и разметки данных.
Подготовьте ML-модель и вычислите признаки
Перейдите к разделу Вычисление признаков. В нем выполняются следующие операции:
- Из пакета Keras загружается модель ResNet50 с весами, предварительно подобранными на наборе данных ImageNet. Этот набор содержит 1,2 миллиона изображений, которые разнесены по 1000 категорий.
- Определяется функция для разделения списка изображений на пачки (chunks) по 32 в каждой.
- Определяется функция, которая читает список изображений и преобразует в формат, пригодный для обработки моделью, а также вычисляет признаки и возвращает их в массиве NumPy.
- С помощью данных функций вычисляются бинарные признаки (
1
— автомобиль,0
— иное) и сохраняются в файл. Этот шаг может занять 10-15 минут. Подробнее про модель ResNet50.
Чтобы подготовить модель и вычислить признаки:
-
Выделите все ячейки с кодом в разделе Вычисление признаков:
#!g1.1 model = ResNet50(weights='imagenet', input_shape=(224, 224, 3)) ...
-
Запустите выделенные ячейки.
-
Дождитесь завершения операции.
Обучите классификатор на полученных признаках
Перейдите к разделам Training and Cross Validation и Save the model. В них выполняются следующие операции:
- Определяется объект для кросс-валидации результатов обучения методом K-fold.
- Готовится таблица для сохранения метрик качества классификации.
- Определяется функция вычисления выбранных метрик.
- Запускается обучение классификатора LightGBM. В данном примере используется кросс-валидация с пятью фолдами:
- Обучающая выборка разбивается на пять непересекающихся одинаковых по объему частей.
- Выполняется пять итераций. На каждой итерации выполняются следующие шаги:
- Модель обучается на четырех частях выборки.
- Модель тестируется на части выборки, которая не участвовала в обучении.
- Выводятся выбранные метрики качества.
- Классификатор обучается на полном наборе данных и выводится итоговая матрица ошибок.
Для обучения классификатора запустите последовательно все ячейки в разделах Training and Cross Validation и Save the model.
Результатом обучения является модель, сохраненная в отдельном файле.
Получите результаты предсказания признаков на тестовых данных
Чтобы использовать полученную модель:
-
Откройте каталог ImageClassificationML/ML и затем ноутбук model-testing.ipynb.
Примечание
Для использования модели нужно существенно меньше ресурсов, чем для ее обучения, поэтому здесь оставлена минимальная конфигурация c1.4 (по умолчанию).
-
Запустите первые две ячейки. В этих ячейках:
- Импортируются необходимые для теста пакеты.
- Настраивается подключение к S3-бакету с изображениями из сервиса видеомониторинга.
-
Задайте тестовое изображение с автомобилем:
test_image = 'car/test/3_60184_41.jpg'
-
В следующей ячейке загрузите модель ResNet50 и подготовленный классификатор LightGBM, и вычислите вероятность предсказанного значения бинарного признака (
1
соответствует автомобилю).В первый раз ячейка с вычислением предсказания обрабатывается дольше, так как модели загружаются в память. При последующих запусках ячейка будет выполняться быстрее:
%%time clf = lgb.Booster(model_file='ImageClassificationML/lightgbm_classifier.model') model = ResNet50(weights='imagenet', input_shape=(224, 224, 3)) ...
-
Убедитесь, что значение вероятности близко к единице (должно получиться
≈0.98
). -
Поменяйте код в ячейке перед загрузкой модели:
test_image = 'car/test/3_59296_27.jpg'
Это тестовое изображение, на котором нет автомобиля.
-
Выполните ячейку.
-
Повторите вычисление вероятности и убедитесь, что значение существенно меньше
0.5
.
Таким образом, классификатор успешно предсказывает признак для этих двух изображений.
Примечание
Вы можете поделиться готовым ноутбуком с расчетами или экспортировать проект целиком.
Практическое применение модели
Есть несколько вариантов практического применения построенной модели:
-
На основе кода предлагаемого решения можно запустить веб-сервис с помощью Yandex Cloud Functions и анализировать изображения при наступлении соответствующего события в видеомониторинге.
-
Для параллельной обработки изображений, приходящих с большого количества видеокамер в S3-бакет, можно загрузить код в кластер Apache Spark™ в Yandex Data Proc с помощью пакета PySpark.
Пример кода Python для интеграции модели с PySpark:
from sparkdl import readImages, KerasImageFileTransformer # load cctv image body from S3 and return image tensor def load_image_body_and_process(uri): import PIL.image from keras.applications.imagenet_utils import preprocess.input ... # load cctv images in batch (from S3 or copy to local hdfs) image_uri_dataset = readImages("/cctv-in/*.jpg") # create a Keras estimator that takes our saved model file and train it using Spark estimator = KerasImageFileEstimator(inputCol="imageUri", outputCol="predict_car", labelCol="categoryVec", imageLoader=load_image_body_and_process, kerasOptimizer="adam", kerasLoss="categorical_crossentropy", kerasFitParams={"epochs": 5, "batchSize": 64}, modelFile="lightgbm_classifier.model") predictions = estimator.fit(image_uri_dataset)