Yolov5 Для Распознавания Марок Автомобилей



Введение Недавно опубликовано объявление новый YOLOv5, который концептуально обеспечивает гораздо лучшую степень распознавания набора данных COCO, чем предыдущие версии.

Автор решил опробовать новую модель на задаче по распознаванию марок автомобилей.



Данные

Прежде всего, нам нужны данные.

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

Разметка данных выполнена с помощью инструмента меткаImg .

Всего было отмечено 118 фотографий автомобилей следующих марок: Lada, Kia, Nissan, Volkswagen, Chevrolet, Ford, Mitsubishi, Renault, Hyundai, Opel. Это довольно оптимистичная цель — попытаться обучить нейронную сеть на таком небольшом наборе данных, однако покажет только практика!

Предварительная обработка

Так как labelImg использует формат Pascal VOC и записывает разметку в файлы XML, а YOLOv5 использует файлы TXT со строками следующего формата: «x-center class-number y-center ширина высота», все нормализованные к единице, мы должны преобразовать разметку в этот формат. Размещаем фотографии в директории CAR_BRANDS/ и пишем код конвертации:
  
  
  
  
  
  
  
   

from lxml import etree import cv2 from glob import glob import re CAR_BRANDS_PATH = 'CAR_BRANDS/' classes = {'lada': 0, 'kia': 1, 'nissan': 2, 'volkswagen': 3, 'chevrolet': 4, 'ford': 5, 'mitsubishi': 6, 'renault': 7, 'hyundai': 8, 'opel': 9} def extract_txt(img_path, xml_path, txt_path): img = cv2.imread(img_path) W = img.shape[1] H = img.shape[0] tree = etree.parse(xml_path) root = tree.getroot() with open(txt_path, 'w') as f: for child in root: if child.tag == 'object': for object_child in child: coords = [] if object_child.tag == 'name': f.write(str(classes.get(object_child.text))+' ') if object_child.tag == 'bndbox': for bbox_child in object_child: coords.append(int(bbox_child.text)) xmin = coords[0] xmax = coords[2] ymin = coords[1] ymax = coords[3] w = (xmax - xmin) / W h = (ymax - ymin) / H xc = (xmin + (xmax - xmin) / 2) / W yc = (ymin + (ymax - ymin) / 2) / H f.write(str(xc)+' '+str(yc)+' '+str(w)+' '+str(h)+'\n') xmls = sorted(glob(CAR_BRANDS_PATH + '*.

xml')) for xml_path in xmls: img_path = re.findall('[A-Za-z0-9_/]+', xml_path)[0]+'.

jpg' txt_path = re.findall('[A-Za-z0-9_/]+', img_path)[0]+'.

txt' extract_txt(img_path, xml_path, txt_path)

Мы будем передавать в нейронную сеть фотографии размера (416, 416), поэтому следующая функция поможет нам изменить их размер:

def resize(folder): files = glob(folder + '*.

jpg') for file in files: img = cv2.imread(file) img = cv2.resize(img, (416, 416)) cv2.imwrite(file, img)



Увеличение

Ресурс использован для аугментации робопоток Однако вы можете использовать любой доступный вам метод аугментации.

Фотографии умножены до 4130, типы увеличения - Обрезка, Яркость, Экспозиция, Шум.

Итоговые файлы были разделены на обучающие, валидационные и тестовые в соотношении 7:2:1.

Образование

Давайте загрузим YOLOv5 из репозитория на Github и установим требования:

git clone https://github.com/roboflow-ai/yolov5 pip install -U -r yolov5/requirements.txt

Информация о данных будет храниться в файле data.yaml. Давайте создадим этот файл со следующим содержимым:

train: .

/train/images val: .

/valid/images nc: 10 names: ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']

где train — путь к каталогу, содержащему изображения для поезда, valid — изображения проверки, nc — количество классов, имена — имена классов.

Вам также необходимо поместить архитектуру в каталог yolov5/models/.

Возьмем за основу архитектуру yolov5s.yaml и разместим в custom_yolov5s.yaml следующую информацию:

# parameters nc: 10 # number of classes depth_multiple: 0.33 # model depth multiple width_multiple: 0.50 # layer channel multiple # anchors anchors: - [10,13, 16,30, 33,23] # P3/8 - [30,61, 62,45, 59,119] # P4/16 - [116,90, 156,198, 373,326] # P5/32 # yolov5 backbone backbone: # [from, number, module, args] [[-1, 1, Focus, [64, 3]], # 1-P1/2 [-1, 1, Conv, [128, 3, 2]], # 2-P2/4 [-1, 3, Bottleneck, [128]], [-1, 1, Conv, [256, 3, 2]], # 4-P3/8 [-1, 9, BottleneckCSP, [256]], [-1, 1, Conv, [512, 3, 2]], # 6-P4/16 [-1, 9, BottleneckCSP, [512]], [-1, 1, Conv, [1024, 3, 2]], # 8-P5/32 [-1, 1, SPP, [1024, [5, 9, 13]]], [-1, 6, BottleneckCSP, [1024]], # 10 ] # yolov5 head head: [[-1, 3, BottleneckCSP, [1024, False]], # 11 [-1, 1, nn.Conv2d, [na * (nc + 5), 1, 1, 0]], # 12 (P5/32-large) [-2, 1, nn.Upsample, [None, 2, 'nearest']], [[-1, 6], 1, Concat, [1]], # cat backbone P4 [-1, 1, Conv, [512, 1, 1]], [-1, 3, BottleneckCSP, [512, False]], [-1, 1, nn.Conv2d, [na * (nc + 5), 1, 1, 0]], # 17 (P4/16-medium) [-2, 1, nn.Upsample, [None, 2, 'nearest']], [[-1, 4], 1, Concat, [1]], # cat backbone P3 [-1, 1, Conv, [256, 1, 1]], [-1, 3, BottleneckCSP, [256, False]], [-1, 1, nn.Conv2d, [na * (nc + 5), 1, 1, 0]], # 22 (P3/8-small) [[], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5) ]

Теперь вы можете начать учиться.

Перейдем к yolov5/:

cd yolov5/

и обучим нашу модель:

python train.py --img 416 --batch 4 --epochs 50 --data '.

/data.yaml' --cfg .

/models/custom_yolov5s.yaml --weights '' --name yolov5s_results --nosave --cache



Результаты

Чтобы протестировать модель, введите следующее:

python detect.py --weights weights/last_yolov5s_results.pt --img 416 --conf 0.4 --save-txt --source .

/test/images

При желании вы можете увеличить или уменьшить значение параметра conf — это позволит вам выбирать прогнозы с вероятностью большей, чем указано в conf. Результаты сохраняются в каталог yolov5/inference/output/ (как изображения, так и TXT-файлы (при условии указания флага --save-txt).

Из 12 фотографий, выбранных для теста, бренды распознались в 10 случаях, и все распознанные оказались правильными.

Вполне хороший результат для исходной выборки из 118 фотографий.

Примеры вывода нейросети (для идентификации брендов используем записанный ранее словарь):

YoloV5 для распознавания марок автомобилей

И, наконец, давайте подробнее рассмотрим процесс обучения.

Во время тренировки YOLOv5 делает что-то похожее на фотографии:

YoloV5 для распознавания марок автомобилей

Это так называемая «мозаичная аугментация» — к фотографиям применяются отражения и разрезание фотографий на части.

Вы можете удалить его, войдя в код train.py и изменив флаг augmet на False. Когда его использование может причинить вред? Например, если бы мы поставили задачу идентифицировать номерные знаки, отражение и разрезание отдельных букв и цифр привело бы не к улучшению, а к ухудшению качества распознавания.



Что дальше?

Во-первых, одним из просторов для творчества может стать перебор различных вариантов архитектур YOLOv5 — все они находятся в yolov5/models/.

Напомню, мы использовали yolov5s — он считается самым быстрым, но не лучшим по качеству распознавания.

Также классической темой YOLO является игра со значениями якорей.

Итак, давайте следить за новостями о новых архитектурах нейросетей и пробовать их на собственных данных! Надеюсь, эта статья была вам полезна.

Теги: #Машинное обучение #python #машинное обучение #компьютерное зрение #yolov5

Вместе с данным постом часто просматривают: