Приложение CNN, обнаруживающее внешние повреждения автомобиля (полный реализуемый код)
Последние достижения в области глубокого обучения и вычислительной инфраструктуры (облако, графические процессоры и т. Д.) Сделали рывок вперед в приложениях компьютерного зрения: от открывания двери в офис лицом к лицу до беспилотных автомобилей. Не так давно задача классификации изображений, такая как распознавание рукописных цифр (отличный набор данных MNIST) или идентификация базового объекта (кошка / собака), считалась большим успехом в области компьютерного зрения. Однако сверточные нейронные сети (CNN), являющиеся движущей силой приложений компьютерного зрения, быстро развиваются с появлением передовых и инновационных архитектур для решения практически любых проблем, связанных с визуальной системой под солнцем.
Автоматическое обнаружение внешних повреждений автомобиля и последующая их количественная оценка (серьезность повреждений) поможет дилерам подержанных автомобилей (торговая площадка) точно и быстро оценивать автомобили за счет исключения ручного процесса оценки повреждений. Эта концепция одинаково выгодна для страховщиков имущества и от несчастных случаев (P&C) с точки зрения более быстрого урегулирования претензий и, следовательно, большей удовлетворенности клиентов. В этой статье я шаг за шагом опишу концепцию обнаружения автомобильных царапин (наиболее частое внешнее повреждение) с использованием обучения передачи CNN с использованием бэкэнда Tensorflow.
Обнаружение повреждений автомобиля - типичное применение сегментации экземпляров
Прежде чем перейти к деталям бизнес-проблемы и шагов по ее реализации, я расскажу о технике, использованной в этом специальном приложении для обнаружения объектов, и ее обосновании. Как и большинство реальных проблем компьютерного зрения, здесь мы также будем использовать переносное обучение из подходящей предварительно обученной CNN, чтобы сэкономить огромное время при переподготовке всей матрицы весов. В качестве типичного приложения в технике обнаружения объектов у нас есть несколько вариантов выбора методов - R-CNN, Fast R-CNN, Faster R-CNN, SSD и т. Д. Чтобы получить обзор этих методов, я рекомендую прочитать эту статью . Вкратце, как и любая задача по обнаружению объектов, здесь также есть 3 следующие подзадачи:
A) Извлечение областей интереса (ROI): изображение передается в ConvNet, которая возвращает область интересов на основе таких методов, как выборочный поиск (RCNN) или RPN (региональное предложение N / W для более быстрого RCNN), а затем уровень объединения ROI на извлекли ROI, чтобы убедиться, что все регионы имеют одинаковый размер.
Б) Задача классификации: регионы передаются в полностью подключенную сеть, которая классифицирует их по различным классам изображений. В нашем случае это будет царапина («повреждение») или фон (кузов автомобиля без повреждений).
C) Задача регрессии: наконец, регрессия ограничивающего прямоугольника (BB) используется для прогнозирования ограничивающих прямоугольников для каждой идентифицированной области для сужения ограничивающих прямоугольников (получение точных BB, определяющих относительные координаты).
Однако в нашем случае недостаточно получить только BB квадратной / прямоугольной формы, поскольку царапины / повреждения автомобиля являются аморфными (без четко определенной формы или формы). Нам необходимо определить точные пиксели в ограничивающей рамке, которые соответствуют классу (повреждение ). Точное расположение царапины в пикселях только поможет определить местоположение и точно оценить ущерб. Поэтому нам нужно добавить еще одну пошаговую семантическую сегментацию (пиксельное затенение интересующего класса) во весь конвейер, для которого мы будем использовать архитектуру CNN (Mask R-CNN) на основе области маскировки.
Маска R-CNN:
Mask R-CNN - это модель сегментации экземпляра, которая позволяет идентифицировать попиксельное разграничение для интересующего нас класса объектов. Таким образом, Mask R-CNN имеет две широкие задачи: 1) обнаружение объектов на основе BB (также называемое задачей локализации) и 2) семантическая сегментация, которая позволяет сегментировать отдельные объекты в пикселях в пределах сцены, независимо от формы. Объедините эти две задачи. Маска R-CNN действительно получает сегментацию экземпляра для данного изображения.
Хотя подробное обсуждение Mask R-CNN выходит за рамки этой статьи, давайте рассмотрим основные компоненты и сделаем обзор различных потерь.
Компоненты Mask R-CNN (Источник)
Таким образом, по сути, маска R-CNN состоит из двух компонентов: 1) обнаружение объекта BB и 2) задача семантической сегментации. Для задачи обнаружения объекта используется архитектура, аналогичная Faster R-CNN. Единственная разница в Mask R-CNN - это шаг ROI. При использовании объединения ROI он использует выравнивание ROI, чтобы позволить пиксель-пиксель сохранить ROI и предотвратить потерю информации. Для задачи семантической сегментации он использует полностью сверточный n / w (FCN). FCN создает маски (в нашем случае это двоичные маски) вокруг объектов BB, создавая пиксельную классификацию каждой области (отдельный интересующий объект). Таким образом, в общей маске R-CNN минимизирует общие потери, состоящие из следующих потерь на каждой фазе сегментации экземпляра. Прежде чем перейти к другому определению потерь, давайте введем важные обозначения.
1) rpn_class_loss: потеря классификатора привязки RPN рассчитывается для каждой области интереса, а затем суммируется для всех областей интереса для одного изображения, а сеть rpn_class_loss будет суммировать rpn_class_loss для всех изображений (поезд / проверка). Так что это не что иное, как потеря кросс-энтропии.
2) rpn_bbox_loss: Потери регрессии сетевого RPN BB суммируются как rpn_class_loss. Значения потерь ограничивающего прямоугольника отражают расстояние между истинными параметрами бокса, то есть координатами (x, y) местоположения бокса, его шириной и высотой - и предсказанные. Это по своей природе потеря регрессии, и она наказывает большие абсолютные различия (приблизительно экспоненциально для более низких различий и линейно для более крупных различий.
Учитывая изображение, эта фаза RPN извлекает множество предложений восходящих областей вероятных местоположений объектов на изображении, а затем подавляет предложения областей с критериями ≥ 0,5 IoU (пересечение по объединению) и вычисляет rpn_class_loss (измерение правильности этих уточненных областей) и насколько они точны (rpn_bbox_loss). Метод точного вычисления потерь требует немного сложного нелинейного преобразования между центрами (предсказанные и наземные истины) и между шириной (предсказанные и наземные истины) и высотами (предсказанные и наземные истины). Точно сеть сокращает SSE между предсказанными координатами BB: (tx, ty, th, tw) - расположение предлагаемой области относительно цели: (Vx, Vy, Vh, Vw) - Названия истинных меток для региона. Таким образом, после включения функции гладких потерь L1 для класса u и для прогнозируемого ограничивающего прямоугольника t, rpn_bbox_loss будет:
Таким образом, на этапе RPN общая потеря сети составляет:
3) mrcnn_class_loss: принцип вычисления этой потери такой же, как и rpn_class_loss, однако это потеря классификации на этапе полностью сверточного n / w (FCN) во время пиксельной классификации для задачи семантической сегментации.
4) mrcnn_bbox_loss: Принцип вычисления этой потери такой же, как и для rpn_bbox_loss, однако это потеря регрессии BB на этапе полностью сверточного n / w (FCN) во время уточнения ограничивающей рамки маски R-CNN для задачи семантической сегментации.
5) mrcnn_mask_loss: это двоичная кросс-энтропийная потеря для головы маски во время маскировки точного местоположения объекта (аморфные внешние места повреждения автомобиля). Она наказывает неправильную попиксельную двоичную классификацию - передний план (пиксели повреждения) / фон (пиксели кузова автомобиля) ) относительно истинных меток классов.
В то время как первые потери генерируются на этапе обнаружения объекта BB, последние три потери генерируются во время задачи семантической сегментации. Таким образом, во время обучения сеть сводит к минимуму общие потери, состоящие из 5 компонентов (для каждого поезда и проверки).
Бизнес-проблема
В подержанных автомобилях (как на торговых площадках, так и у дилеров), помимо функциональности и наличия оборудования, а также состояния здоровья, которое можно получить только с помощью тест-драйва / ручного осмотра, наблюдаются внешние повреждения кузова автомобиля (царапины, вмятины, перекраска и т. Д.) жизненно важная роль в определении точной цены на автомобиль. В большинстве случаев эти повреждения обнаруживаются и оцениваются вручную по изображениям автомобиля в процессе оценки автомобиля. Тем не менее, новейшие системы компьютерного зрения могут определять место повреждения на кузове автомобиля и помогать ценообразованию количественно оценить ущерб без особого ручного вмешательства. Эта концепция также поможет автостраховщикам автоматически оценивать ущерб и быстрее обрабатывать претензии.
В следующем разделе я кратко рассмотрю подготовку данных и реализацию этой концепции на реальных изображениях автомобилей с использованием Mask R-CNN. Подробный код вместе со всеми входами (видео контента и изображение стиля) и выходом (сгенерированные кадры изображений) можно найти здесь в моем репозитории GitHub.
Шаг 1: Сбор данных - хотя мы будем использовать переносное обучение из подходящей предварительно обученной (весовой) архитектуры CNN, нам необходимо настроить сеть для нашего конкретного использования, чтобы минимизировать потери, специфичные для приложения - потери из-за несоответствия местоположения повреждения на уровне пикселей между землей правда и предсказано. Итак, мы запустим поезд n / w на использование 56 изображений повреждений вагонов, собранных из Google, из которых 49 изображений используются для поезда, а 7 используются для целей проверки.
Шаг 2: аннотации данных - поскольку концепция попадает в режим контролируемого обучения, нам необходимо маркировать данные. В контексте обнаружения объектов компьютерного зрения или локализации объекта такая маркировка называется аннотацией. Именно для нашего приложения он определяет области повреждения на изображении и точно отмечает их по границе царапины. Для целей аннотации я использовал аннотатор изображений VGG (VIA) по этой ссылке. Используя этот инструмент, я загрузил все свои изображения и нарисовал многоугольные маски вдоль границы повреждения для каждого изображения следующим образом.
После аннотации всех изображений мы загрузили аннотацию в формате .json, и я сделал это отдельно для обучающих и проверочных изображений.
Шаг 3: Настройка среды - это один из важных шагов перед обучением модели на собранных изображениях и аннотациях (этикетках), так как я буду использовать репозиторий Matterport Mask R-CNN для использования нескольких предварительно обученных CNN n. / w весовых матриц, построенных на различных стандартных наборах данных, таких как набор данных COCO, ImageNet и т. д., и пользовательских функциях, таких как обработка и подготовка данных, настройка конфигурации, обучение модели, создание файла журнала для сохранения итерационных объектов матрицы весов и н / б потери, обнаружение объектов, маскирование обнаруженных локализованных областей и т. д. Чтобы запустить пользовательскую функцию обучения для изображений и аннотаций, нам нужно сначала клонировать репозиторий, следуя точной структуре файлов и папок, как описано в репозитории. Эта маска Matterport R-CNN построена на основе API обнаружения объектов Tensorflow. Ниже приведены шаги перед началом тренировочного процесса.
а) Хранить обучающие и проверочные изображения и соответствующие файлы аннотаций в отдельных подпапках с именами «train» и «val» внутри папки данных. Я назвал это «обычай».
б) На основе вычислительной инфраструктуры, желаемой точности обнаружения объектов и шагов обучения нам необходимо определить конфигурацию обучения.
class CustomConfig(Config): """Configuration for training on the toy dataset. Derives from the base Config class and overrides some values. """ # Give the configuration a recognizable name NAME = "scratch" # We use a GPU with 6GB memory, which can fit only one image. # Adjust down if you use a smaller GPU. IMAGES_PER_GPU = 1 # Number of classes (including background) NUM_CLASSES = 1 + 1 # Car Background + scratch # Number of training steps per epoch STEPS_PER_EPOCH = 100 # Skip detections with < 90% confidence DETECTION_MIN_CONFIDENCE = 0.9
c) Наконец, нам нужно выбрать начальную точку - объект предварительно обученной матрицы весов, чтобы начать процесс обучения. Я выбрал mask_rcnn_coco.h5, который предварительно обучен на наборе данных coco.
Шаг 4: Загрузка наборов данных: здесь мы загружаем обучающие и проверочные изображения и помечаем отдельное изображение соответствующими метками или аннотациями. Здесь я настроил код baloon.py, написанный для Mask R-CNN в соответствии с приложением (метка класса, путь к каталогу, стандартизация форм и т. Д.), Чтобы подготовить custom_1.py, который загружает изображения и аннотации и добавляет их в класс CustomDataset. Код находится в моем репозитории GitHub.
class CustomDataset(utils.Dataset): def load_custom(self, dataset_dir, subset): """Load a subset of the dataset. dataset_dir: Root directory of the dataset. subset: Subset to load: train or val """ # Add classes. We have only one class to add. self.add_class("scratch", 1, "scratch") # Train or validation dataset? assert subset in ["train", "val"] dataset_dir = os.path.join(dataset_dir + subset)
Шаг 4: Обучение сети. Теперь нам нужно усовершенствовать базу «mask_rcnn_coco.h5» с помощью обучения модели на реальных изображениях, и после каждой итерации (эпохи) обновленная матрица весов сохраняется в «журнале». Кроме того, статистика потерь по итерациям / эпохам сохраняется для мониторинга в TensorBoard.
def train(model): """Train the model.""" # Training dataset. dataset_train = CustomDataset() dataset_train.load_custom(args.dataset, "train") dataset_train.prepare() # Validation dataset dataset_val = CustomDataset() dataset_val.load_custom(args.dataset, "val") dataset_val.prepare() # *** This training schedule is an example. Update to your needs *** # Since we're using a very small dataset, and starting from # COCO trained weights, we don't need to train too long. Also, # no need to train all layers, just the heads/last few layers should do it. print("Training network heads") model.train(dataset_train,dataset_val, learning_rate=config.LEARNING_RATE,epochs=15,layers='heads') layers='hea
Нам нужно запустить обучающий код (файл .py) на изображениях с помощью следующих команд
### Train the base model using pre-trained COCO weights(I ran using these weights,Download 'mask_rcnn_coco.h5' weights before starting the training) py custom_1.py train --dataset=C:/Users/Sourish/Mask_RCNN/custom --weights=coco ### Train the base model using pre-trained imagenet weights(for this to download imagenet weights)) py custom_1.py train --dataset=C:/Users/Sourish/Mask_RCNN/custom --weights=imagenet ## We can even resume from the latest saved callback(latest saved weights) python3 custom.py train --dataset=C:/Users/Sourish/Mask_RCNN/custom --weights=last
и начинается волшебство.
Шаг 4: Проверка модели - По мере каждой итерации (эпохи) обновленная матрица весов сохраняется в журнале. Также статистика потерь по итерациям / эпохам сохраняется для мониторинга в TensorBoard.
Хотя большая часть части обучения модели стандартизирована и находится вне нашего контроля, мы не можем контролировать, мы можем просмотреть различные компоненты потерь при обучении и проверке (как описано в предыдущем разделе) в TensorBoard. Также из сохраненных обратных вызовов (сохраненных матриц весов) мы можем проверить гистограмму весов и смещений.
Шаг 5: Прогнозирование модели - после удовлетворительного и желательного мониторинга потерь - в идеале монотонно уменьшая потери как при обучении, так и при проверке, мы можем протестировать объект модели на случайно выбранных проверочных изображениях, чтобы увидеть точность прогноза (маскирование повреждений автомобиля).
image_id = random.choice(dataset.image_ids) #select a random image from validation dataset image, image_meta, gt_class_id, gt_bbox, gt_mask =\ modellib.load_image_gt(dataset, config, image_id, use_mini_mask=False) #image loading # Run object detection results = model.detect([image], verbose=1) # Display results ax = get_ax(1) r = results[0] visualize.display_instances(image, r['rois'], r['masks'], r['class_ids'], dataset.class_names, r['scores'], ax=ax, title="Predictions") log("gt_class_id", gt_class_id) log("gt_bbox", gt_bbox) log("gt_mask", gt_mask) #Showing damage polygon on car body print('The car has:{} damages'.format(len(dataset.image_info[image_id]['polygons'])))
и вот прогноз.
И прогноз выглядит неплохо.
Внедрение бизнеса и перспективы на будущее
Продавцы подержанных автомобилей / компания по страхованию автомобилей могут установить инфраструктуру с камерами высокого разрешения под подходящими углами и в подходящем месте, чтобы щелкать стандартизированные (размерные) изображения различных частей кузова (спереди, сзади, сбоку и т. Д.) И могут обнаруживать все возможные внешние повреждения в автомобилях. . Эту концепцию можно использовать как мобильное приложение как решение API, что может упростить процесс оценки автомобиля.
Кроме того, после обнаружения и маскировки повреждений автомобиля, процесс может помочь специалистам по оценке автомобилей / персоналу по урегулированию претензий в количественной оценке серьезности повреждений с точки зрения размеров и приблизительной относительной площади (относительно площади поверхности автомобиля) повреждения. Что наиболее важно, поскольку мы используем трансферное обучение, нам не нужно собирать много изображений и последующих аннотаций, а поскольку обучение модели начинается с натренированных весов («кокос»), нам не нужно тренироваться слишком долго. Кроме того, эта концепция может быть расширена для обнаружения других типов видимых повреждений / неисправностей автомобиля.