yolov5目标检测具备一定的小目标检测能力,但由于参与训练的coco数据集缺少小目标素材,故检测小目标有局限。本文利用无人机采集的小目标数据集,对yolov5权重文件进行再训练,提高小目标检测能力。本文仅记录跑通训练的过程,得到一些启示,没有尝试训练整个数据集。
使用visDrone无人机小目标数据集训练yolov5检测器比较 上图用未训练的yolov5s.pt,下图用经过训练的best.pt权重。 可以看出两种检测的区别,其中visDrone训练图片用了其中69张,epoch=100,简单训练已初见成效。而且并没有改变原来的yolov5s模型结构。此测试图来自评估集val。 利用yolov5训练程序,采用visDrone训练集的过程如下: 下载visDrone训练集:https://github.com/VisDrone/VisDrone-Dataset。其中有百度网盘和google drive两种选择,在百度网盘限速时,google drive的下载速度明显快。 新版yolov5提供了visDrone数据集转yolov5训练数据集的格式变换,见yolov5/data/VisDrone.yaml。将该文件中附带的数据集的处理部分,新建visdrone2yolov5.py。
from utils.general import download, os, Path
def visdrone2yolo(dir):
from PIL import Image
from tqdm import tqdm
def convert_box(size, box):
dw = 1. / size[0]
dh = 1. / size[1]
return (box[0] + box[2] / 2) * dw, (box[1] + box[3] / 2) * dh, box[2] * dw, box[3] * dh
(dir / 'labels').mkdir(parents=True, exist_ok=True)
pbar = tqdm((dir / 'annotations').glob('*.txt'), desc=f'Converting {dir}')
for f in pbar:
img_size = Image.open((dir / 'images' / f.name).with_suffix('.jpg')).size
lines = []
with open(f, 'r') as file:
for row in [x.split(',') for x in file.read().strip().splitlines()]:
if row[4] == '0':
continue
cls = int(row[5]) - 1
box = convert_box(img_size, tuple(map(int, row[:4])))
lines.append(f"{cls} {' '.join(f'{x:.6f}' for x in box)}\n")
with open(str(f).replace(os.sep + 'annotations' + os.sep, os.sep + 'labels' + os.sep), 'w') as fl:
fl.writelines(lines)
dir = Path('~/project_name/datasets/VisDrone2019')
for d in 'VisDrone2019-DET-train', 'VisDrone2019-DET-val', 'VisDrone2019-DET-test-dev':
visdrone2yolo(dir / d)
如此,产生符合yolov5训练数据格式的labels。VisDrone原数据集中,VisDrone2019-DET-train目录下有两个目录annotations,images,运行visdrone2yolov5.py后,产生labesl目录。yolov5训练中,仅使用train和val目录下的images和labels。 准备好的数据集结构如下: 构造数据集配置文件,可从VisDrone.yaml修改而得。
path: ~/project_name/datasets/VisDrone2019
train: VisDrone2019-DET-train
val: VisDrone2019-DET-val
nc: 10
names: ['pedestrian', 'people', 'bicycle', 'car', 'van', 'truck', 'tricycle', 'awning-tricycle', 'bus', 'motor']
注:visDrone数据集共有类型11个,此处只用到10个,去除了others,即背景类。
修改yolov5s.yaml,将nc改为10
nc: 10
depth_multiple: 0.33
width_multiple: 0.50
anchors:
- [10,13, 16,30, 33,23]
- [30,61, 62,45, 59,119]
- [116,90, 156,198, 373,326]
至此,完成visDrone数据集配置修改,可运行train.py。这里需要对命令行做如下修改:
--data ~/project_name/yolov5/data/myvisDrone.yaml
--cfg ~/project_name/yolov5/models/yolov5s.yaml
--weights ~/project_name/yolov5/weights/yolov5s.pt
--workers 4
--batch-size 4
--epochs 100
其中,workers=4,与主机GPU能力有关;batch-size=4,与GPU内存大小有关。 运行train.py 运行结果存放在yolov5/runs/train/exp文件夹中,得到权重best.pt。 运行detect.py检验权重best.pt的训练效果,得到博文开始的图片。 需注意,检测类别数值。类别car在visDrone中classes=4,而运行detect.py时,类别car的classes=3。原因或许类别值从0开始计算,这与coco数据集类别有不同。
|