Это 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
Вниз
bounding_box_test
Обработка изображения ниже такая же,test
один изid
это -1, а? Я действительно не понимаю, но это не влияет на обучение.
Для вышеуказанных операций напишите простой скрипт
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
После обучения,checkpoint
Создайте файл модели подckpt.t7
, найдите видео, протестируйте его
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
из.