目标检测:YOLOv5
文章目录
一、环境配置
1.1、源码下载安装方式
# 下载源码
git clone https://github.com/ultralytics/yolov5
git clone https://github.com.cnpmjs.org/ultralytics/yolov5 # 使用镜像站进行加速下载
# 切换到 yolov5 目录
cd yolov5
# 安装所需环境:注意取消 requirements.txt 中的 wandb/onnx 及 extra 中的所有依赖,然后再运行如下命令
pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
# 下载字体 Arial.ttf 到 yolov5 目录下,下载地址:https://ultralytics.com/assets/Arial.ttf
sudo cp Arial.ttf /usr/share/fonts/truetype/dejavu
- 更改后的
requirements.txt
如下所示:
# pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
# base ----------------------------------------
matplotlib>=3.2.2
numpy>=1.18.5
opencv-python>=4.1.2
Pillow>=8.0.0
PyYAML>=5.3.1
scipy>=1.4.1
torch>=1.7.0
torchvision>=0.8.1
tqdm>=4.41.0
# logging -------------------------------------
tensorboard>=2.4.1
wandb # automatically track and visualize YOLOv5 runs
# plotting ------------------------------------
seaborn>=0.11.0
pandas
# export --------------------------------------
onnx>=1.9.0 # for export onnx
# coremltools>=4.1
# scikit-learn==0.19.2 # for coreml quantization
# tensorflow==2.4.1 # for TFLite export
# extras --------------------------------------
Cython # for pycocotools https://github.com/cocodataset/cocoapi/issues/172
pycocotools>=2.0 # COCO mAP
albumentations>=1.0.3
thop # FLOPs computation
1.2、docker 镜像方式
- 宿主机环境需求:
Nvidia Driver >= 455.23,Docker Engine CE >= 19.03
- 直接拉取官方镜像:
docker pull ultralytics/yolov5:latest
- 启动镜像:
docker run --ipc=host --gpus all -it ultralytics/yolov5:v5.0
- 工作目录:
/usr/src/app
torch.__version__=1.9,torchvision.__version__=0.9, onnx.__version__ =1.8, cuda=11.2
- 自己从
Dockfile
制作镜像,可以参考如下代码:
# Start FROM Nvidia PyTorch image https://ngc.nvidia.com/catalog/containers/nvidia:pytorch
FROM nvcr.io/nvidia/pytorch:21.05-py3
# Install linux packages
RUN apt update && apt install -y zip htop screen libgl1-mesa-glx
# Install python dependencies
COPY requirements.txt .
RUN python -m pip install --upgrade pip
RUN pip uninstall -y nvidia-tensorboard nvidia-tensorboard-plugin-dlprof
RUN pip install --no-cache -r requirements.txt coremltools onnx gsutil notebook
RUN pip install --no-cache -U torch torchvision numpy
# RUN pip install --no-cache torch==1.9.0+cu111 torchvision==0.10.0+cu111 -f https://download.pytorch.org/whl/torch_stable.html
# Create working directory
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
# Copy contents
COPY . /usr/src/app
# Set environment variables
ENV HOME=/usr/src/app
# Usage Examples -------------------------------------------------------------------------------------------------------
# Build and Push
# t=ultralytics/yolov5:latest && sudo docker build -t $t . && sudo docker push $t
# Pull and Run
# t=ultralytics/yolov5:latest && sudo docker pull $t && sudo docker run -it --ipc=host --gpus all $t
# Pull and Run with local directory access
# t=ultralytics/yolov5:latest && sudo docker pull $t && sudo docker run -it --ipc=host --gpus all -v "$(pwd)"/datasets:/usr/src/datasets $t
# Kill all
# sudo docker kill $(sudo docker ps -q)
# Kill all image-based
# sudo docker kill $(sudo docker ps -qa --filter ancestor=ultralytics/yolov5:latest)
# Bash into running container
# sudo docker exec -it 5a9b5863d93d bash
# Bash into stopped container
# id=$(sudo docker ps -qa) && sudo docker start $id && sudo docker exec -it $id bash
# Clean up
# docker system prune -a --volumes
二、主要改进
YOLOv5 是一个基于 Anchor 的单阶段目标检测,其主要分为以下 5 个阶段:
输入端
:Mosaic数据增强、自适应Anchor计算、自适应图像缩放
Backbone
:CSPDarkNet, 提取出高中低层的特征,使用了 CSP 结构、SPPF、SiLU
等操作;Neck
:使用FPN+PAN
结构,将各层次的特征进行融合,并提取出大中小的特征图;Head
:进行最终检测部分,在特征图上应用 Anchor Box
,并生成带有类别概率、类别得分以及目标框的最终输出向量;损失函数
:使用 CIoU 计算预测结果与 Ground Truth 之间的 Loss。
2.1、Using multi-anchors for single ground truth
- 用多个 anchor 去负责一个 GT:对于 G T j GT_j GTj 来说,只要 I o U ( a n c h o r i , G T j ) > t h r e s h o l d IoU(anchor_i, GT_j) > threshold IoU(anchori,GTj)>threshold,就让 a n c h o r i anchor_i anchori 去负责 G T i GT_i GTi
- 相当于 anchor 框的数量没变,但正样本的比例增加了,缓解了正负样本不均衡的问题
2.2、Eliminate grid sensitivity
- 按理说 b 应该能取到一个grid 里面的任意位置,但 sigmoid 函数的值域是: ( 0 , 1 ) (0, 1) (0,1) ,取不到边界 0 或 1
- 解决方案:在 sigmoid 函数前乘上一个略大于 1 的数(1.05,1.1,1.2 等等),这样改动以后效果会再次提升
b x = 1.1 σ ( t x ) + c x b y = 1.1 σ ( t y ) + c y b_x = 1.1 \sigma(t_x) + c_x \\ b_y = 1.1 \sigma(t_y) + c_y bx=1.1σ(tx)+cxby=1.1σ(ty)+cy
2.3、Data Augmentation
- 随机调整亮度、对比度、色调;随机缩放、裁剪、翻转、旋转
- Mosaic data augmentation:丰富了数据集(尤其是小目标),减少显存的占用,使用一块 GPU 即可训练
- Random Erase/hide and Seek
- Self-Adversarial-Training(SAT):自对抗训练
- Label Smoothing
-
Mosaic data augmentation
-
Mosaic data augmentation 步骤:有拼 4 张和 9 张的可选:参考,目标检测数据增强之mosaic 和 数据增强mosaic实现
- step1:新建 mosaic 画布(用 114 填充),并在 mosaic 画布上随机生成一个
拼接点
- step2:围绕随机点 (x_c, y_c) 放置 4 块拼图(注意要使用
缩放
后的图片进行拼图),超出范围的裁剪掉
- step3:更新 bbox 坐标
- Random Erase/hide and Seek
- Self-Adversarial-Training(SAT):自对抗训练
- Label Smoothing
2.4、加上了自适应 anchor 的功能
- Yolov3、Yolov4 中,训练不同的数据集时,计算初始锚框的值是通过单独的程序运行的
- Yolov5 中,将此功能嵌入到代码中,每次训练时,自适应的计算不同训练集中的最佳锚框值
2.5、 Cross mini-Batch Normalization
三、网络结构
- Yolov5 的五个基本组件:
- CBM:Yolov4 网络结构中的最小组件,由 Conv+Bn+Mish 激活函数三者组成。
- CBL:由 Conv+Bn+Leaky_Relu 激活函数三者组成。
- CSP1_X:借鉴 CSPNet 网络结构,由三个卷积层和 X 个 Res unit 模块 Concat 组成。
- CSP2_X:不再用 Res unint 模块,而是改为 CBL
- SPP:采用 1×1,5×5,9×9,13×13 的最大池化的方式,进行多尺度融合
- 其中 CSP1 结构主要应用于 Backbone 中,CSP2 结构主要应用于 Neck 中
3.1、BackBone
-
Focus: 相当于下采样,减少后续计算量
- 将 feature map 在
spatial
维度上的数据展开到channel
维度上(相邻的 4 个像素在 channel 维的数据依次拼接),原始在channel
维度上连续的元素在展开后的feature map
中依然是连续的,如右图的切片示意图,4×4×3 的图像切片后变成 2×2×12的特征图。 - 以 Yolov5s 的结构为例,原始 608×608×3 的图像输入 Focus 结构,采用切片操作,先变成 304×304×12 的特征图,再经过一次 32 个卷积核的卷积操作,最终变成 304×304×32 的特征图。
- 将 feature map 在
-
CSPNet(Cross Stage Paritial Network)
- Yolov5 中设计了两种 CSP 结构,以 Yolov5s 网络为例,以
CSP1_X
结构应用于 Backbone 主干网络,另一种CSP2_X
结构则应用于 Neck 中CSP1_X
:借鉴 CSPNet 网络结构,由三个卷积层和 X 个 Res unit 模块 Concat 组成CSP2_X
:不再使用 Res unit 模块,而是改为 CBL(由 Conv+Bn+Leaky_Relu 激活函数三者组成)
- 每个 CSP 模块前面的卷积核的大小都是 3×3,步长为 2,因此可以起到下采样的作用(结合完整网络结构来看)
- 具体实现:先将基础层的特征按照
channel
维划分为两部分,然后通过跨层结构将它们合并,在减少了计算量的同时可以保证准确率(增强 CNN 的学习能力)
- Yolov5 中设计了两种 CSP 结构,以 Yolov5s 网络为例,以
-
CBAM(Convolutional Block Attention Module):
- 加入空间注意力机制模块(Spatial Attention Module)
- 空间注意力机制模块中直接使用卷积,不使用 Pooling
-
Dropblock:
- 这种方式其实是借鉴 Cutout 数据增强的方式,Cutout 是将输入图像的部分区域清零,而 Dropblock 则是将 Cutout 应用到每一个特征图
- Dropblock 可以定制各种组合,在训练的不同阶段可以修改删减的概率,从空间层面和时间层面,和 Cutout 相比都有更精细的改进
-
Activation:YOLOv5 使用的激活函数是
SiLU
(YOLOv4为 Mish激活函数)
3.2、Neck
-
SPP( Spatial Pyramid Pooling)
- 在 SPP 模块中,使用
k
=
1
×
1
,
5
×
5
,
9
×
9
,
13
×
13
k={1×1,5×5,9×9,13×13}
k=1×1,5×5,9×9,13×13 的最大池化(输出大小不变,采用 stride=1,padding 的方式),再将不同尺度的特征图进行
Concat
操作。 - .SPP 对于特定的CNN网络设计和结构是独立的。(也就是说,只要把SPP放在最后一层卷积层后面,对网络的结构是没有影响的, 它只是替换了原来的pooling层)
- 实现了局部特征和全局特征的融合,扩大了感受野,丰富了最终特征图的表达能力
- 在 SPP 模块中,使用
k
=
1
×
1
,
5
×
5
,
9
×
9
,
13
×
13
k={1×1,5×5,9×9,13×13}
k=1×1,5×5,9×9,13×13 的最大池化(输出大小不变,采用 stride=1,padding 的方式),再将不同尺度的特征图进行
-
YOLOv5 中对 SPP 进行了改进 SPPF:将经过 CBS 的 x 与一次池化后的 y1、两次池化后的 y2 和 3 次池化后的 y3进 行拼接,然后再 CBS 进一步提取特征;在融合的过程中多次运用最大池化,尽可能多的去提取高层次的语义特征
-
FPN(特征金字塔)+PAN:
- FPN 结构只增强了特征的语义信息,对特征的定位信息没有得到很好的传递,因此在YOLOv4中添加了 PAN 结构,来增强定位信息的传递
- Top-Down + Bottom-Up
- PAN (借鉴的是
PANet
)原本的 Add 操作改成 Concat
3.3、Prediction
-
DIoU NMS
- 实际案例如下:
- 在下图重叠的摩托车检测中,中间的摩托车因为考虑边界框中心点的位置信息,也可以回归出来。因此在重叠目标的检测中,DIOU NMS 的效果优于传统的 NMS
- 为什么不用 CIOU NMS,而用 DIOU NMS 呢?因为 CIOU 需要用到 GT 标注框的信息,但在测试过程中,并没有 GT 的信息,因此只能使用 DIOU NMS
- 实际案例如下:
-
自适应 padding and resize
- 按比例缩放,若能够整除,则不需要填充;若不能整除,则填充最少的黑边(根据下采样次数),在 datasets.py 的 letterbox 函数中也有详细的代码解释(结合lili之前的 padandresize 代码进行分析)
- 按比例缩放,若能够整除,则不需要填充;若不能整除,则填充最少的黑边(根据下采样次数),在 datasets.py 的 letterbox 函数中也有详细的代码解释(结合lili之前的 padandresize 代码进行分析)
-
坐标表示
- 解码顺序:NCHW,其中 C 为
4+1+cls_num
,具体为x, y, w, h, obj_confidence, one_hot_obj_cls
四、损失函数
YOLO系列 Location Loss 演化过程:
L2(MSE) Loss --> IoU Loss --> GIoU Loss --> DIoU Loss --> CIoU Loss
- 定位损失:使用 CIOU Loss
- 目标置信度损失以及分类损失:使用二元交叉熵损失函数(多标签分类)
五、代码解析
-
网络的深度和宽度设置
- 深度因子(depth_multiple):控制网络的深度(_后面的 x 为重复次数)
- 宽度因子(width_multiple):控制网络的宽度(Conv 卷积核的数量)
-
YOLOv5s 网络的深度如下图所示
-
YOLOv5s 网络的宽度如下图所示
-
输出 anchor 排列:与 Yolov3 一致
六、参考资料
1、深入浅出Yolo系列之Yolov3&Yolov4&Yolov5核心基础知识完整讲解
2、深入浅出Yolo系列之Yolov5核心基础知识完整讲解
3、使用YOLO V5训练自动驾驶目标检测网络
4、官方代码:https://github.com/ultralytics/yolov5
5、YOLOv4 / Scaled-YOLOv4 (Windows and Linux version of Darknet )
6、https://github.com/WongKinYiu/ScaledYOLOv4
7、https://github.com/WongKinYiu/PyTorch_YOLOv4
8、https://github.com/Tianxiaomo/pytorch-YOLOv4(PyTorch ,ONNX and TensorRT implementation of YOLOv4 )
9、https://github.com/wuzhihao7788/yolodet-pytorch
10、YOLOV5-5.x 源码讲解—整体项目文件导航
11、YOLOV5 代码解析专栏
12、PANet(CVPR 2018)原理与代码解析
13、【CV中的特征金字塔】四,CVPR 2018 PANet
14、https://github.com/ShuLiu1993/PANet
15、https://github.com/open-mmlab/mmdetection/blob/master/mmdet/models/necks/pafpn.py
16、https://docs.ultralytics.com/environments/Docker-Quickstart
17、https://hub.docker.com/r/ultralytics/yolov5/tags