我的学习思路:
- dang下来一个完整code
- 不断debug直到能在我电脑上正常运行
- 看代码,学习code,哪里能看懂了,改哪里的代码,改多了就成我自己的东西了,就能让“别人的code”去做“我想做的事情”
下载code
首先上一个GitHub下载yolov5 code链接:GitHub - ultralytics/yolov5: YOLOv5 🚀 in PyTorch > ONNX > CoreML > TFLite
我是下载了5.0版本,后来一直报错,又下载了6.1版本就能运行了。
下载过程:
打开code+运行(配置环境,自己debug)
然后用PyCharm IDE打开即可,如下图,这是我的目录:
根据requirements.txt这个文件配置环境。
pip install -r requirements.txt
其中我遇到了pycocotools、SPPF、AttributeError: 'Upsample' object has no attribute 'recompute_scale_factor'、、、、等等问题,建议小伙伴们可以自行网页搜索,每天不是在创造bug就是在debug的过程,具备一些自己Google解决问题的能力是很必要的。
代码学习
目录介绍
对代码的整体目录做一个介绍:
├── data:主要是存放一些超参数的配置文件(这些文件(yaml文件)是用来配置训练集和测试集还有验证集的路径的,其中还包括目标检测的种类数和种类的名称);还有一些官方提供测试的图片。如果是训练自己的数据集的话,那么就需要修改其中的yaml文件。但是自己的数据集不建议放在这个路径下面,而是建议把数据集放到yolov5项目的同级目录下面。
├── models:里面主要是一些网络构建的配置文件和函数,其中包含了该项目的四个不同的版本,分别为是s、m、l、x。从名字就可以看出,这几个版本的大小。他们的检测测度分别都是从快到慢,但是精确度分别是从低到高。这就是所谓的鱼和熊掌不可兼得。如果训练自己的数据集的话,就需要修改这里面相对应的yaml文件来训练自己模型。
├── utils:存放的是工具类的函数,里面有loss函数,metrics函数,plots函数等等。
├── weights:放置训练好的权重参数。
├── detect.py:利用训练好的权重参数进行目标检测,可以进行图像、视频和摄像头的检测。
├── train.py:训练自己的数据集的函数。
├── test.py:测试训练的结果的函数。
├──requirements.txt:这是一个文本文件,里面写着使用yolov5项目的环境依赖包的一些版本,可以利用该文本导入相应版本的包。
以上就是yolov5项目代码的整体介绍。我们训练和测试自己的数据集基本就是利用到如上的代码。
了解预训练模型
detect.py文件
运行效果:
可以看到detect的预测结果放在了runs\detect\exp2中。这是运行效果图
这里是我dang下来code自带的两张图片,大家也可以把想测试的图片或视频放到这里,我就放入了一些图片,然后比较离谱的事情就发生了:
参数详情:
weights
parser.add_argument('--weights', nargs='+', type=str, default=ROOT / 'yolov5s.pt', help='model path(s)')
weights权重,自己可以调,yolov5s.pt, yolov5m.pt, yolov5l.pt, yolov5x.pt,
source
parser.add_argument('--source', type=str, default=ROOT / 'data/images', help='file/dir/URL/glob, 0 for webcam')
source网络输入路径,就是即将被预处理的图片或视频,默认是文件夹下所有内容,也可以指定某个具体的文件
data
parser.add_argument('--data', type=str, default=ROOT / 'data/coco128.yaml', help='(optional) dataset.yaml path')
imgsz
parser.add_argument('--imgsz', '--img', '--img-size', nargs='+', type=int, default=[640], help='inference size h,w')
imgsz图像的height和width,输入和输出的大小不变,只是送入网络后被缩小后放大。在检测前将它resize成640*640的大小,喂进网络。
conf-thres
parser.add_argument('--conf-thres', type=float, default=0.25, help='confidence threshold')
conf_thres置信度,只输出置信度大于xx的预测结果
iou-thres
parser.add_argument('--iou-thres', type=float, default=0.45, help='NMS IoU threshold')
iou:intersection over union
iou_thres过大容易出现一个目标多个检测框;IOU thres过小容易出现检测结果少的问题。
介绍以下iou和nms:
- nms:non-maximum suppresion非最大抑制(以下是两篇文章的连接)非极大值抑制算法(Non-Maximum Suppression,NMS)_非极大抑制算法-CSDN博客【精选】Bounding Box Regression超详解(全站最全汇总版)综合各个途径文档 看这一篇就够了 解决你所有疑惑_bounding-box regression计算_迪菲赫尔曼的博客-CSDN博客
max-det
parser.add_argument('--max-det', type=int, default=1000, help='maximum detections per image')
一张图中最大检测数量,最多可以检测1000个
device
parser.add_argument('--device', default='', help='cuda device, i.e. 0 or 0,1,2,3 or cpu')
用来选择GPU的,如果不选择,默认会自动检测
view-img
parser.add_argument('--view-img', action='store_true', help='show results')
在检测是时候是否把检测结果实时显示出来,如检测一张显示一张。
save-txt
parser.add_argument('--save-txt', action='store_true', help='save results to *.txt')
是否把检测结果保存成一个.txt文本,我们试验一下,会得到一个label文件夹:
在终端terminal输入
python detect.py --save-txt
save-conf
parser.add_argument('--save-conf', action='store_true', help='save confidences in --save-txt labels')
是否以.txt格式保存置信度,如果单独执行python detect.py --save-conf不报错,但没效果,应该在terminal输入:
python detect.py --save-txt --save-conf
save-crop
parser.add_argument('--save-crop', action='store_true', help='save cropped prediction boxes')
是否把模型检测到的物体剪裁下来,若是,我们执行一下,得到如下结果,都是剪裁下来的图片:
nosave
parser.add_argument('--nosave', action='store_true', help='do not save images/videos')
不保存预测结果,但还生成exp文件(空)。我觉得这个应该搭配--view-img一起使用
classes(nargs)
parser.add_argument('--classes', nargs='+', type=int, help='filter by class: --classes 0, or --classes 0 2 3')
nargs参数:给变量赋值,可以把0赋值给classes,也可以把0,1,2,3都赋值给classes
(nargs=' * ' 表示参数可设置零个或多个
nargs=' + ' 表示参数可设置一个或多个
nargs=' ? ' 表示参数可设置零个或一个)
如果我们只把0类别,也就是人类别,赋值给classes,那么得到:
python detect.py --classes 0
agnostic-nms
parser.add_argument('--agnostic-nms', action='store_true', help='class-agnostic NMS')
agnostic-nms是跨类别nms,比如当待预测图像中出现一个长长的像橄榄球的足球,而pt文件的分类中有橄榄球和足球,就会标注出两个框,一橄榄一足球。但当我们开启agnostic-nms,只会标注一个框。
augment
parser.add_argument('--augment', action='store_true', help='augmented inference')
这个参数也是一种增强的方式,下图是启用前和启用后:
visualize
parser.add_argument('--visualize', action='store_true', help='visualize features')
是否把特征图可视化出来,运行后,可以发现多了一些.npy后缀的文件,可以读作numpy
如何打开npy文件:python读取并可视化npy格式的深度图文件以及将其保存为jpg图片的方法_npy文件-CSDN博客
update
parser.add_argument('--update', action='store_true', help='update all models')
如果指定这个参数,则对所有模型进行strip-optimizer操作(条带优化器),去除pt文件中的优化器信息。
project
parser.add_argument('--project', default=ROOT / 'runs/detect', help='save results to project/name')
name
parser.add_argument('--name', default='exp', help='save results to project/name')
如上图,文件夹的名字
exist-ok
parser.add_argument('--exist-ok', action='store_true', help='existing project/name ok, do not increment')
每次预测结果是否保存在上一个文件夹中。如果指定了这个参数,则每次保存结果都在上一个保存结果文件夹中,如果不指定,那么每次保存结果都在一个新文件夹中。
line-thickness
parser.add_argument('--line-thickness', default=3, type=int, help='bounding box thickness (pixels)')
调节预测框粗细的,我们输入python detect.py --line-thickness 16,得到:
hide-lables
parser.add_argument('--hide-labels', default=False, action='store_true', help='hide labels')
hide-conf
parser.add_argument('--hide-conf', default=False, action='store_true', help='hide confidences')
隐藏置信度
half
parser.add_argument('--half', action='store_true', help='use FP16 half-precision inference')
是否使用FP16半精度推理。
dnn
parser.add_argument('--dnn', action='store_true', help='use OpenCV DNN for ONNX inference')