Yolo v5源码解析笔记

一、Yolo v5文件目录树结构

 

 重要的几个文件:

coco.yaml:数据集配置文件

yolo5s.yaml:网络模型配置参数

common.py:网络模型定义代码

runs目录:保存的训练结果

utils:激活函数、超参数等

yolo5s.pt:权重文件

参考链接:

YOLOV5学习笔记(四)——项目目录及代码讲解_桦树无泪的博客-CSDN博客_yolov5 model.half()

二、train.py文件介绍

从main()方法,首先读取参数;其次建立YOLONet;然后读取训练数据;最后进行训练。

2.1 读取参数

部分截图

Yolo v5源码解析笔记_第1张图片

这里的参数的含义后面会补充

2.2  建立YOLONet

        YOLONet的建立是通过 yolo文件夹中的yolo_net.py文件的代码实现了。yolo_net.py定义了YOLONet类,该类包含了网络初始化(__init__()),建立网络(build_networks())和loss函数(loss_layer())等方法。

        网络的所有初始化参数包含于__init__()方法之中:

三、yolov5s.yaml源码解读

        YOLO V5不再采用.cfg配置文件了,而是使用了新的.yaml配置文件,方便进行基于函数式的模块化开发。下面会对模型配置文件 yolov5s.yaml 进行讲解。

先附上yolov5s的网络结构图:

在这里插入图片描述

3.1 参数配置

# parameters
nc: 20  # number of classes
depth_multiple: 0.33  # model depth multiple 控制模型的深度(BottleneckCSP个数)
width_multiple: 0.50  # layer channel multiple 控制Conv通道channel个数(卷积核数量)
# depth_multiple表示BottleneckCSP模块的缩放因子,将所有BottleneckCSP模块的Bottleneck乘上该参数得到最终个数。
# width_multiple表示卷积通道的缩放因子,就是将配置里面的backbone和head部分有关Conv通道的设置,全部乘以该系数。
# 通过这两个参数就可以实现不同复杂度的模型设计。

 这个文件主要设置了三个参数,会用于模型搭建 yolo.py 文件中 如下:

在这里插入图片描述

 第一个是 nc(number of classes)数据集类别个数;

第二个参数是depth_multiple,用于控制模型的深度。通过深度参数 depth gain 在搭建每一层的时候,实际深度 = 理论深度( 每一层的参数n) * depth_multiple,这样就可以起到一个动态调整模型深度的作用。如下图:

在这里插入图片描述

第三个参数是width_multiple,用于控制模型的宽度。在模型中间层的每一层的实际输出channel = 理论channel(每一层的参数c2) * width_multiple,这样也可以起到一个动态调整模型宽度的作用。

第二个参数和第三个参数是控制模型大小的。

如下图:

在这里插入图片描述 这里的 depth_multiple 和 width_multiple 两个参数,这种通过一个参数动态调整网络规模的方法是从 EfficientNetV1 和 EfficientNetV2 得到的灵感,感兴趣的可以看一下。

3.2 anchors配置

# anchors
anchors:
  - [10,13, 16,30, 33,23]  # P3/8   stride=8
  - [30,61, 62,45, 59,119]  # P4/16
  - [116,90, 156,198, 373,326]  # P5/32

        yolov5初始化了9个anchors,在三个Detect层使用(3个feature map)中使用,每个feature map的每个grid_cell都有三个anchor进行预测。分配的规则是:尺度越大的feature map越靠前,相对原图的下采样率越小,感受野越小,所以相对可以预测一些尺度比较小的物体,所有分配到的anchors越小;尺度越小的feature map越靠后,相对原图的下采样率越大,感受野越大,所以相对可以预测一些尺度比较大的物体,所有分配到的anchors越大。即可以在小特征图(feature map)上检测大目标,也可以在大特征图上检测小目标。

        yolov5根据工程经验得到了这么3组anchors,对于很多数据集而言确实挺合适的。但是也不能保证这3组anchors就适用于所有的数据集,所有yolov5还有一个anchor进化的策略:使用k-means和遗传进化算法,找到与当前数据集最吻合的anchors。具体的代码细节可以看我的这篇博文链接: 【YOLOV5-5.x 源码解读】autoanchor.py。里面很详细的讲解了如何使用这个策略以及代码理解,这里就不多说了。

3.3 backbone

backbone:
  # [from, number, module, args]
  # from表示当前模块的输入来自那一层的输出,-1表示来自上一层的输出
  # number表示本模块重复的次数,1表示只有一个,3表示重复3次
  # module: 模块名
  [[-1, 1, Focus, [64, 3]],          # 0-P1/2   [3, 32, 3]
   [-1, 1, Conv, [128, 3, 2]],       # 1-P2/4   [32, 64, 3, 2]
   [-1, 3, C3, [128]],               # 2        [64, 64, 1]
   [-1, 1, Conv, [256, 3, 2]],       # 3-P3/8   [64, 128, 3, 2]
   [-1, 9, C3, [256]],               # 4        [128, 128, 3]
   [-1, 1, Conv, [512, 3, 2]],       # 5-P4/16  [128, 256, 3, 2]
   [-1, 9, C3, [512]],               # 6        [256, 256, 3]
   [-1, 1, Conv, [1024, 3, 2]],      # 7-P5/32  [256, 512, 3, 2]
   [-1, 1, SPP, [1024, [5, 9, 13]]], # 8        [512, 512, [5, 9, 13]]
   [-1, 3, C3, [1024, False]],       # 9        [512, 512, 1, False]
   # [nc, anchors, 3个Detect的输出channel]
   # [1, [[10, 13, 16, 30, 33, 23], [30, 61, 62, 45, 59, 119], [116, 90, 156, 198, 373, 326]], [128, 256, 512]]
  ]

这是yolov5s的backbone,可以看到每一个模块算一行,每行都由四个参数构成。分别是:

1. from:表示当前模块的输入来自那一层的输出,-1表示来自上一层的输出。
2. number: 表示当前模块的理论重复次数,实际的重复次数还要由上面的参数depth_multiple共同决定,决定网络模型的深度。
3. module:模块类名,通过这个类名去common.py中寻找相应的类,进行模块化的搭建网络。
4. args: 是一个list,模块搭建所需参数,channel,kernel_size,stride,padding,bias等。会在网络搭建过程中根据不同层进行改变:
BottleneckCSP, C3, C3TR:

在这里插入图片描述

 nn.BatchNorm2d:

在这里插入图片描述

Detect

在这里插入图片描述

3.4 head 

YOLOv5 head = PANet+Detect

# YOLOv5 head  作者没有区分neck模块,所以head部分包含了PANet+Detect部分
head:
  [[-1, 1, Conv, [512, 1, 1]], # 10                 [512, 256, 1, 1]
   [-1, 1, nn.Upsample, [None, 2, 'nearest']], # 11 [None, 2, 'nearest']
   [[-1, 6], 1, Concat, [1]],  # 12 cat backbone P4 [1]
   [-1, 3, C3, [512, False]],  # 13                 [512, 256, 1, False]

   [-1, 1, Conv, [256, 1, 1]], # 14                 [256, 128, 1, 1]
   [-1, 1, nn.Upsample, [None, 2, 'nearest']], #15  [None, 2, 'nearest']
   [[-1, 4], 1, Concat, [1]],  # 16 cat backbone P3 [1]
   [-1, 3, C3, [256, False]],  # 17 (P3/8-small)    [256, 128, 1, False]

   [-1, 1, Conv, [256, 3, 2]], # 18                 [128, 128, 3, 2]
   [[-1, 14], 1, Concat, [1]], # 19 cat head P4     [1]
   [-1, 3, C3, [512, False]],  # 20 (P4/16-medium)  [256, 256, 1, False]

   [-1, 1, Conv, [512, 3, 2]], # 21                 [256, 256, 3, 2]
   [[-1, 10], 1, Concat, [1]], # 22 cat head P5     [1]
   [-1, 3, C3, [1024, False]], # 23 (P5/32-large)   [512, 512, 1, False]

   [[17, 20, 23], 1, Detect, [nc, anchors]],  # 24  Detect(P3, P4, P5)
  ]

可以看到,和backbone的很像,也是由4个参数构成:

1.from: 表示当前模块的输入来自那一层的输出,-1表示来自上一层的输出。不过这里可以为list,就是这层的输入由所层输出concat而来。
2. number:表示当前模块的理论重复次数,实际的重复次数还要由上面的参数depth_multiple共同决定,决定网络模型的深度。
3. module:模块类名,通过这个类名去common.py中寻找相应的类,进行模块化的搭建网络。
4. args:也是是一个list,模块搭建所需参数,channel,kernel_size,stride,padding,bias等。

搭配着yolo.py一起看,会更清晰每个参数的作用。

四、训练

【YOLOv5】记录YOLOv5的学习过程_Q小鑫的博客-CSDN博客

五、

参考链接:

【YOLOV5-5.x 源码解读】yolov5s.yaml_满船清梦压星河HK的博客-CSDN博客_yolov5s.yamlhttps://blog.csdn.net/qq_42108414/article/details/128277972?spm=1001.2101.3001.6650

你可能感兴趣的:(深度学习,深度学习,python,人工智能)