超详细!手把手教你使用YOLOX进行物体检测(附数据集)
作者:王浩,3D视觉开发者社区签约作者,毕业于北京航空航天大学,人工智能领域优质创作者,CSDN博客认证专家。
编辑:3D视觉开发者社区
摘要
YOLOX: Exceeding YOLO Series in 2021
•代码:https://github.com/Megvii-BaseDetection/YOLOX•论文:https://arxiv.org/abs/2107.08430
YOLOX 是旷视开源的高性能检测器。旷视的研究者将解耦头、数据增强、无锚点以及标签分类等目标检测领域的优秀进展与 YOLO 进行了巧妙的集成组合,提出了 YOLOX,不仅实现了超越 YOLOv3、YOLOv4 和 YOLOv5 的 AP,而且取得了极具竞争力的推理速度。如下图:
其中YOLOX-L版本以 68.9 FPS 的速度在 COCO 上实现了 50.0% AP,比 YOLOv5-L 高出 1.8% AP!还提供了支持 ONNX、TensorRT、NCNN 和 Openvino 的部署版本,本文将详细介绍如何使用 YOLOX进行物体检测。
一、 配置环境
本机的环境:
操作系统 | Win10 |
Pytorch版本 | 1.8.0 |
Cuda版本 | 11.1 |
1.1 下载源码
GitHub地址:https://github.com/Megvii-BaseDetection/YOLOX,下载完成后放到D盘根目录,然后用PyCharm打开。
1.2 安装依赖包
点击“Terminal”,如下图,
然后执行下面的命令,安装所有的依赖包。
pip install -r requirements.txt
1.3 安装yolox
python setup.py install
看到如下信息,则说明安装完成了
1.4 安装apex
APEX是英伟达开源的,完美支持PyTorch框架,用于改变数据格式来减小模型显存占用的工具。其中最有价值的是amp(Automatic Mixed Precision),将模型的大部分操作都用Float16数据类型测试,一些特别操作仍然使用Float32。并且用户仅仅通过三行代码即可完美将自己的训练代码迁移到该模型。实验证明,使用Float16作为大部分操作的数据类型,并没有降低参数,在一些实验中,反而由于可以增大Batch size,带来精度上的提升,以及训练速度上的提升。
安装步骤:
1) 到官网下载apex,地址:mirrors / nvidia / apex · CODE CHINA (csdn.net)[1]
2) 下载完成后,解压后,在Shell里,进入到apex-master中。
3) 执行安装命令
pip install -r requirements.txt
python setup.py install
看到如下log,则表明安装成功。
1.5 安装pycocotools
pip install pycocotools
注:如果出现环境问题,可以参考博客:https://blog.csdn.net/hhhhhhhhhhwwwwwwwwww/article/details/105858384
1.6 验证环境
下载预训练模型,本文选用的是YOLOX-s,下载地址:https://github.com/Megvii-BaseDetection/YOLOX/releases/download/0.1.1rc0/yolox_s.pth。
下载完成后,将预训练模型放到工程的根目录,如下图:
然后验证环境,执行:
python tools/demo.py image -f exps/default/yolox_s.py -c ./yolox_s.pth --path assets/dog.jpg --conf 0.3 --nms 0.65 --tsize 640 --save_result --device gpu
参数说明
参数 | 说明 |
-c | 权重的路径 |
-path | 测试图片的路径 |
-conf | 置信度阈值 |
-nms | nms的IOU阈值 |
-tsize | 测试图片resize的大小 |
-save_result | 是否保存推理结果 |
--device | 选用gpu或cpu推理 |
查看运行结果:
看到上图说明环境没有问题了。
二、 制作数据集
数据集我们采用VOC数据集,原始数据集是Labelme标注的数据集。下载地址:https://pan.baidu.com/s/1kj-diqEK2VNVqd2n4ROa5g (提取码rrnz)
新建labelme2voc.py文件
import os from typing import List, Any import numpy as np import codecs import json from glob import glob import cv2 import shutil from sklearn.model_selection import train_test_split # 1.标签路径 labelme_path = "LabelmeData/" # 原始labelme标注数据路径 saved_path = "VOC2007/" # 保存路径 isUseTest = True # 是否创建test集 # 2.创建要求文件夹 if not os.path.exists(saved_path + "Annotations"): os.makedirs(saved_path + "Annotations") if not os.path.exists(saved_path + "JPEGImages/"): os.makedirs(saved_path + "JPEGImages/") if not os.path.exists(saved_path + "ImageSets/Main/"): os.makedirs(saved_path + "ImageSets/Main/") # 3.获取待处理文件 files = glob(labelme_path + "*.json") files = [i.replace("\\", "/").split("/")[-1].split(".json")[0] for i in files] print(files) # 4.读取标注信息并写入 xml for json_file_ in files: json_filename = labelme_path + json_file_ + ".json" json_file = json.load(open(json_filename, "r", encoding="utf-8")) height, width, channels = cv2.imread(labelme_path + json_file_ + ".jpg").shape with codecs.open(saved_path + "Annotations/" + json_file_ + ".xml", "w", "utf-8") as xml: xml.write('\n') xml.write('\t' + 'WH_data' + '\n') xml.write('\t' + json_file_ + ".jpg" + '\n') xml.write('\t\n') xml.write('\t\tWH Data\n') xml.write('\t\tWH\n') xml.write('\t\tflickr\n') xml.write('\t\tNULL\n') xml.write('\t\n') xml.write('\t\n') xml.write('\t\tNULL\n') xml.write('\t\tWH\n') xml.write('\t\n') xml.write('\t\n') xml.write('\t\t' + str(width) + '\n') xml.write('\t\t' + str(height) + '\n') xml.write('\t\t' + str(channels) + '\n') xml.write('\t\n') xml.write('\t\t0\n') for multi in json_file["shapes"]: points = np.array(multi["points"]) labelName = multi["label"] xmin = min(points[:, 0]) xmax = max(points[:, 0]) ymin = min(points[:, 1]) ymax = max(points[:, 1]) label = multi["label"] if xmax <= xmin: pass elif ymax <= ymin: pass else: xml.write('\t\n') print(json_filename, xmin, ymin, xmax, ymax, label) xml.write('') # 5.复制图片到 VOC2007/JPEGImages/下 image_files = glob(labelme_path + "*.jpg") print("copy image files to VOC007/JPEGImages/") for image in image_files: shutil.copy(image, saved_path + "JPEGImages/") # 6.split files for txt txtsavepath = saved_path + "ImageSets/Main/" ftrainval = open(txtsavepath + '/trainval.txt', 'w') ftest = open(txtsavepath + '/test.txt', 'w') ftrain = open(txtsavepath + '/train.txt', 'w') fval = open(txtsavepath + '/val.txt', 'w') total_files = glob("./VOC2007/Annotations/*.xml") total_files = [i.replace("\\", "/").split("/")[-1].split(".xml")[0] for i in total_files] trainval_files = [] test_files = [] if isUseTest: trainval_files, test_files = train_test_split(total_files, test_size=0.15, random_state=55) else: trainval_files = total_files for file in trainval_files: ftrainval.write(file + "\n") # split train_files, val_files = train_test_split(trainval_files, test_size=0.15, random_state=55) # train for file in train_files: ftrain.write(file + "\n") # val for file in val_files: fval.write(file + "\n") for file in test_files: print(file) ftest.write(file + "\n") ftrainval.close() ftrain.close() fval.close() ftest.close()
运行上面的代码就可以得到VOC2007数据集。如下图所示:
VOC的目录如下,所以要新建data/VOCdevkit目录,然后将上面的结果复制进去