Обучение модели DeepSort

глубокое обучение компьютерное зрение

Это 17-й день моего участия в августовском испытании обновлений. Узнайте подробности события:Испытание августовского обновления

Программно-аппаратная среда

  • ubuntu 18.04 64bit
  • GTX 1070Ti
  • anaconda with python 3.7
  • pytorch 1.6
  • cuda 10.1

предисловие

ПреамбулаОтслеживание целей на основе YOLOv5 и DeepSortввел использованиеYOLOv5иDeepSortДля достижения цели обнаружения и сопровождения. Однако модель исходного проекта содержит только обычных людей и ничего не может сделать для других целей.В этой статье я научу свой собственный трекер отслеживать конкретные цели.

Что касаетсяYOLOv5Для обучения модели обнаружения обратитесь к предыдущему сообщению в блоге.Обучение модели YOLOv5.

Набор данных Market 1501

Market-1501Набор данных был собран в кампусе Университета Цинхуа, снят летом, построен и обнародован в 2015 году. Он включает 1501 пешехода, 32668 обнаруженных пешеходных прямоугольников, снятых 6 камерами (из них 5 камер высокого разрешения и 1 камера низкого разрешения). Каждый пешеход фиксируется как минимум двумя камерами и может иметь несколько изображений на одной камере. В обучающей выборке 751 человек, в том числе 12 936 изображений, и у каждого человека в среднем 17,2 обучающих данных; в тестовой выборке 750 человек, включая 19 732 изображения, и у каждого человека в среднем 26,3 тестовых данных. Прямоугольники обнаружения пешеходов 3368 изображений запроса рисуются вручную, аgalleryПрямоугольник обнаружения пешеходов вDPMобнаруживаются детектором.

Структура каталога набора данных

Market-1501-v15.09.15
├── bounding_box_test
├── bounding_box_train
├── gt_bbox
├── gt_query
├── query
└── readme.txt

Содержит четыре папки

  • bounding_box_test: для тестирования
  • bounding_box_train: для тренировки
  • query: Есть 750 личностей. Мы случайным образом выбираем изображение запроса для каждой камеры
  • gt_query: Содержит фактическую выноску. По каждому запросу релевантные изображения были помечены как «хорошие» или «мусорные». «Спам» не влияет на точность поиска. «мусорные» изображения также включают изображения с той же камеры, что и запрос.
  • gt_bbox: граница, нарисованная вручную, в основном используется для сужденияDPMОграничительная рамка хороша?

Правила именования изображений

от0001_c1s1_000151_01.jpgНапример

  • 0001 представляет собой номер ярлыка каждого человека, от 0001 до 1501, всего 1501 человек.
  • c1Указывает на первую камеру (cдаcamera), всего 6 камер
  • s1Обозначает первый видеоклип (sдаsequence), каждая камера имеет несколько видеоклипов
  • 000151 означаетc1s1Изображение кадра 000151, частота кадров видео составляет 25 кадров в секунду.
  • 01 означаетc1s1_001051Первый кадр обнаружения на этом кадре из-за использованияDPMДля автоматических детекторов на каждом кадре может быть несколько пешеходов, и может быть несколько соответствующих полей для аннотаций. 00 означает поле ручной аннотации

Адрес загрузки набора данных:

Ссылка на сайт:disk.baidu.com/is/1i9loveZX-E…
Код извлечения:up8x

Как устроен рынок?

Исходная структура набора данных выглядит так

Market-1501-v15.09.15
├── bounding_box_test
├── bounding_box_train
├── gt_bbox
├── gt_query
├── query
└── readme.txt

иbounding_box_trainиbounding_box_testВ каталоге есть определенные файлы изображений, которые здесь не отражены.id. Правильный способ: поставитьid(то есть чьи-то) картинки помещаются в папку сidкак имя папки. как будетbounding_box_trainвсе следующие0002Файлы изображений в начале хранятся в папке0002Вниз

market deepsort

bounding_box_testОбработка изображения ниже такая же,testодин изidэто -1, а? Я действительно не понимаю, но это не влияет на обучение.

market deepsort

Для вышеуказанных операций напишите простой скрипт

import os
import sys
import shutil


if __name__ == '__main__':
    root = os.path.join(sys.argv[1], 'dataset')
    os.mkdir(root)
    train_dir = os.path.join(root, 'train')
    test_dir = os.path.join(root, 'test')
    os.mkdir(train_dir)
    os.mkdir(test_dir)

    # 处理train
    for file in os.listdir(os.path.join(sys.argv[1], 'bounding_box_train')):
        print(file)
        id = file.split('_')[0]
        if not os.path.exists(os.path.join(train_dir, id)):
            os.mkdir(os.path.join(train_dir, id))
        else:
            shutil.copy(os.path.join(sys.argv[1], 'bounding_box_train', file), os.path.join(train_dir, id))

    # 处理test
    for file in os.listdir(os.path.join(sys.argv[1], 'bounding_box_test')):
        id = file.split('_')[0]
        if not os.path.exists(os.path.join(test_dir, id)):
            os.mkdir(os.path.join(test_dir, id))
        else:
            shutil.copy(os.path.join(sys.argv[1], 'bounding_box_test', file), os.path.join(test_dir, id))

инструкции

python test.py Market-1501-v15.09.15

После выполнения скриптаMarket-1501-v15.09.15папка сборкиdataset, файловая структура такая

dataset/
├── train
    ├── 0002
    ├── 0007
    ├── 0010
    ├── 0011
    ├── 0012
    ├── 0020
    ├── 0022

├── test
    ├── 0000
    ├── 0001
    ├── 0003
    ├── 0004
    ├── 0005
    ├── 0006
    ├── 0008
    ├── 0009

Это создает набор данных, который можно напрямую обучать, не разрушая исходный.

обучение модели глубокой сортировки

Я не буду говорить, что это зависит от среды, см. предыдущую статью.

git clone --recurse-submodules https://github.com/mikel-brostrom/Yolov5_DeepSort_Pytorch.git
cd Yolov5_DeepSort_Pytorch/deep_sort/deep_sort/deep

Далее набор данныхMarketскопировать вYolov5_DeepSort_Pytorch/deep_sort/deep_sort/deepЗагрузите и распакуйте набор данных.Расположение набора данных произвольно и может быть указано параметрами.

Наконец, вам нужно изменить место, отредактироватьmodel.py,будет

def __init__(self, num_classes=751 ,reid=False):

изменить на

def __init__(self, num_classes=752 ,reid=False):

Тогда можно приступать к обучению

python train.py --data-dir Market-1501-v15.09.15

deepsort_market_pytorch

deepsort_market_pytorch

После обучения,checkpointСоздайте файл модели подckpt.t7, найдите видео, протестируйте его

deepsort_market_pytorch

num_classes значение

объясните здесьnum_classesзначит, по первоначальному проектуGitHub.com/micoli-br OST…серединаtrain.pyкод

trainloader = torch.utils.data.DataLoader(
    torchvision.datasets.ImageFolder(train_dir, transform=transform_train),
    batch_size=64,shuffle=True
)
testloader = torch.utils.data.DataLoader(
    torchvision.datasets.ImageFolder(test_dir, transform=transform_test),
    batch_size=64,shuffle=True
)

num_classes = max(len(trainloader.dataset.classes), len(testloader.dataset.classes))

можно увидеть,num_classesдаtrainиtestТипы в коллекции (то есть общееidчисло) значение большего числа, вMarket 1501набор данных,trainИх 751,testИх 752 (включая идентификационный номер -1), поэтомуnum_classesЭто 752.

Поэтому при обучении набора данных нужно только изменитьmodel.py,будетnum_classesИзмените его на 752,train.pyНикаких модификаций не требуется.

Примечание

Наконец, еще одно слово, инженерияGitHub.com/micoli-br OST…серединаdeepsortРаздел отслеживания относится кGitHub.com/ZQ PEI/deep_…, но с некоторыми изменениями. Предыдущее обучение основано наYolov5_DeepSortиз.

использованная литература