Yaml文件详解

以YOLOV5.yaml文件为例:

# Ultralytics YOLO 🚀, AGPL-3.0 license
# YOLOv5 object detection model with P3-P5 outputs. For details see https://docs.ultralytics.com/models/yolov5

# Parameters
nc: 80 # number of classes
scales: # model compound scaling constants, i.e. 'model=yolov5n.yaml' will call yolov5.yaml with scale 'n'
  # [depth, width, max_channels]
  n: [0.33, 0.25, 1024]
  s: [0.33, 0.50, 1024]
  m: [0.67, 0.75, 1024]
  l: [1.00, 1.00, 1024]
  x: [1.33, 1.25, 1024]

# YOLOv5 v6.0 backbone
backbone:
  # [from, number, module, args]
  - [-1, 1, Conv, [64, 6, 2, 2]] # 0-P1/2
  - [-1, 1, Conv, [128, 3, 2]] # 1-P2/4
  - [-1, 3, C3, [128]]
  - [-1, 1, Conv, [256, 3, 2]] # 3-P3/8
  - [-1, 6, C3, [256]]
  - [-1, 1, Conv, [512, 3, 2]] # 5-P4/16
  - [-1, 9, C3, [512]]
  - [-1, 1, Conv, [1024, 3, 2]] # 7-P5/32
  - [-1, 3, C3, [1024]]
  - [-1, 1, SPPF, [1024, 5]] # 9

# YOLOv5 v6.0 head
head:
  - [-1, 1, Conv, [512, 1, 1]]
  - [-1, 1, nn.Upsample, [None, 2, "nearest"]]
  - [[-1, 6], 1, Concat, [1]] # cat backbone P4
  - [-1, 3, C3, [512, False]] # 13

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

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

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

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

1.1 参数设置

nc:80:这是模型的输出类别数,这里设置为80(通常与COCO数据集相对应)

scales:这里定义了模型的不同规模版本(如n,s,m,l,x),每种规模都有不同的深度、宽度和最大通道数:

  • depth:网络的层数
  • width:网络中每层的通道宽度
  • max_channles:每个层中允许的最大通道数

1.2 backbone部分

backbone部分有四个重要参数,[from,number,module.args],下面一一解释:

from:这个参数表示从哪一层获得输入,-1就表示从上一层获得输入,[-1,6]就表示从上一层和第6层这两层获得输入。第一层比较特殊,第一层的上一层没有输入,所以保持第一层的from为-1即可。

number:这个参数表示模块重复的次数,如果为3则表示该模块重复3次,这个时候也并不一定是这个模块的重复次数,也有可能是这个模块的子模块重复的次数,具体看你代码怎么写。对于C3模块来说,这个number就代表C3中Bottelneck模块重复的次数。

module:这个就代表你这层使用的模块的名称,比如第一层使用了Conv模块,第二层使用了C3模块,所有的模块都在common.py钟可以看到。

args:这个参数是整个配置文件中最重要也是最难确定的参数,在第二节中单独说明。

1.3 head部分

头部函数参数依然是,[from,number,module,args],在这里说明一下Concat与Detect,首先是Concat,-1代表上一层,6代表第六层(从第0层开始数),Concat要求的是拼接的两个特征图的尺寸是一样的,通道可以不一样!!!Add操作是要求模型的通道和尺寸都相同!Add操作其实就是将两个特征图的相应像素相加,得到一个新的特征图。Concat操作则是两个特征图在通道维度上连接起来,得到一个新的特征图。

Detect的from有三个数,[17,20,23],这三个就是最终网络的输出特征图,分别对应P3,P4,P5。

1.4 Conv函数

class Conv(nn.Module):
    """Standard convolution with args(ch_in, ch_out, kernel, stride, padding, groups, dilation, activation)."""

    default_act = nn.SiLU()  # default activation

    def __init__(self, c1, c2, k=1, s=1, p=None, g=1, d=1, act=True):
        """Initialize Conv layer with given arguments including activation."""
        super().__init__()
        self.conv = nn.Conv2d(c1, c2, k, s, autopad(k, p, d), groups=g, dilation=d, bias=False)
        self.bn = nn.BatchNorm2d(c2)
        self.act = self.default_act if act is True else act if isinstance(act, nn.Module) else nn.Identity()

    def forward(self, x):
        """Apply convolution, batch normalization and activation to input tensor."""
        return self.act(self.bn(self.conv(x)))

    def forward_fuse(self, x):
        """Perform transposed convolution of 2D data."""
        return self.act(self.conv(x))

在Conv模块中,共有7个形参,其中后5个形参已经有了默认值,以上面的Conv为例子,它的args是[64,6,2,2],这个64就代表的c2,6代表的就是k,2代表的就是s,最后一个2代表的就是p。

args的赋值是按顺序的。

将Conv这个模块的部分拆解出来,看一下计算步骤:

if m in [Conv, C3]:
    c1, c2 = ch[f], args[0]
    if c2 != no:  # if not output
        c2 = make_divisible(c2 * gw, 8)

    args = [c1, c2, *args[1:]]
    if m in [BottleneckCSP, C3, C3TR]:
        args.insert(2, n)  # number of repeats
        n = 1

这段代码的目的是根据不同的模块类型对输入特征图的channel数进行调整。

首先,c1和c2分别表示当前模块输入的特征图和输出的特征图的通道数。如果当前模块输出的不是最终输出,则通过make_divisible函数将c2乘上一个宽度倍数gw,然后将其向下取整为8的倍数。

然后,将c1和c2以及其他参数按顺序组成一个新的参数列表args。如果当前模块是BottleneckCSP、C3、C3TR中的一种,则将重复次数n插入到参数列表的第三个位置,并将n设置为1.

1.5 如何修改yaml文件

比如想在SPPF的上一层添加一层SE模块

修改后的yaml文件如下

   .....
   [-1, 9, C3, [512]],
   [-1, 1, Conv, [1024, 3, 2]],  # 7-P5/32
   [-1, 3, C3, [1024]],
   [-1, 1, SE, [16]],
   [-1, 1, SPPF, [1024, 5]],  # 9
  ]
   .....

注意修改Concat的from系数以及Detect的from系数

Concat的from系数要注意特征图的尺寸

Detect的from系数就是我们最终要输出的预测特征图

修改后的yaml文件如下:

# by CSDN 迪菲赫尔曼

# Parameters
nc: 80  # number of classes
depth_multiple: 0.33  # model depth multiple
width_multiple: 0.50  # layer channel multiple
anchors:
  - [10,13, 16,30, 33,23]  # P3/8
  - [30,61, 62,45, 59,119]  # P4/16
  - [116,90, 156,198, 373,326]  # P5/32

# YOLOv5 v6.0 backbone
backbone:
  # [from, number, module, args]
  [[-1, 1, Conv, [64, 6, 2, 2]],  # 0-P1/2
   [-1, 1, Conv, [128, 3, 2]],    # 1-P2/4
   [-1, 3, C3, [128]],
   [-1, 1, Conv, [256, 3, 2]],    # 3-P3/8
   [-1, 6, C3, [256]],
   [-1, 1, Conv, [512, 3, 2]],    # 5-P4/16
   [-1, 9, C3, [512]],
   [-1, 1, Conv, [1024, 3, 2]],   # 7-P5/32
   [-1, 3, C3, [1024]],
   [-1, 1, SE, [16]],    
   [-1, 1, SPPF, [1024, 5]],      # 10
  ]

# YOLOv5 v6.1 head
head:
  [[-1, 1, Conv, [512, 1, 1]],
   [-1, 1, nn.Upsample, [None, 2, 'nearest']],
   [[-1, 6], 1, Concat, [1]],  # cat backbone P4
   [-1, 3, C3, [512, False]],  # 14

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

   [-1, 1, Conv, [256, 3, 2]],
   [[-1, 15], 1, Concat, [1]],  # cat head P4
   [-1, 3, C3, [512, False]],   # 21 (P4/16-medium)

   [-1, 1, Conv, [512, 3, 2]],
   [[-1, 11], 1, Concat, [1]],  # cat head P5
   [-1, 3, C3, [1024, False]],  # 24 (P5/32-large)

   [[18, 21, 24], 1, Detect, [nc, anchors]],  # Detect(P3, P4, P5)
  ]

1.6 如何添加检测头

# YOLOv5 🚀 by Ultralytics, GPL-3.0 license

# Parameters
nc: 80  # number of classes
depth_multiple: 1.0  # model depth multiple
width_multiple: 1.0  # layer channel multiple
anchors: 3  # AutoAnchor evolves 3 anchors per P output layer

# YOLOv5 v6.0 backbone
backbone:
  # [from, number, module, args]
  [[-1, 1, Conv, [64, 6, 2, 2]],  # 0-P1/2
   [-1, 1, Conv, [128, 3, 2]],  # 1-P2/4
   [-1, 3, C3, [128]],
   [-1, 1, Conv, [256, 3, 2]],  # 3-P3/8
   [-1, 6, C3, [256]],
   [-1, 1, Conv, [512, 3, 2]],  # 5-P4/16
   [-1, 9, C3, [512]],
   [-1, 1, Conv, [1024, 3, 2]],  # 7-P5/32
   [-1, 3, C3, [1024]],
   [-1, 1, SPPF, [1024, 5]],  # 9
  ]

# YOLOv5 v6.0 head with (P2, P3, P4, P5) outputs
head:
  [[-1, 1, Conv, [512, 1, 1]],
   [-1, 1, nn.Upsample, [None, 2, 'nearest']],
   [[-1, 6], 1, Concat, [1]],  # cat backbone P4
   [-1, 3, C3, [512, False]],  # 13

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

   [-1, 1, Conv, [128, 1, 1]],
   [-1, 1, nn.Upsample, [None, 2, 'nearest']],
   [[-1, 2], 1, Concat, [1]],  # cat backbone P2
   [-1, 1, C3, [128, False]],  # 21 (P2/4-xsmall)

   [-1, 1, Conv, [128, 3, 2]],
   [[-1, 18], 1, Concat, [1]],  # cat head P3
   [-1, 3, C3, [256, False]],  # 24 (P3/8-small)

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

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

   [[21, 24, 27, 30], 1, Detect, [nc, anchors]],  # Detect(P2, P3, P4, P5)
  ]

1.7 如何减少检测头

# YOLOv5 🚀 by Ultralytics, GPL-3.0 license

# Parameters
nc: 80  # number of classes
depth_multiple: 0.33  # model depth multiple
width_multiple: 0.50  # layer channel multiple
anchors: 3  # AutoAnchor evolves 3 anchors per P output layer

# YOLOv5 v6.0 backbone
backbone:
  # [from, number, module, args]
  [ [ -1, 1, Conv, [ 64, 6, 2, 2 ] ],  # 0-P1/2
    [ -1, 1, Conv, [ 128, 3, 2 ] ],  # 1-P2/4
    [ -1, 3, C3, [ 128 ] ],
    [ -1, 1, Conv, [ 256, 3, 2 ] ],  # 3-P3/8
    [ -1, 6, C3, [ 256 ] ],
    [ -1, 1, Conv, [ 512, 3, 2 ] ],  # 5-P4/16
    [ -1, 9, C3, [ 512 ] ],
    [ -1, 1, Conv, [ 1024, 3, 2 ] ],  # 7-P5/32
    [ -1, 3, C3, [ 1024 ] ],
    [ -1, 1, SPPF, [ 1024, 5 ] ],  # 9
  ]

# YOLOv5 v6.0 head with (P3, P4) outputs
head:
  [ [ -1, 1, Conv, [ 512, 1, 1 ] ],
    [ -1, 1, nn.Upsample, [ None, 2, 'nearest' ] ],
    [ [ -1, 6 ], 1, Concat, [ 1 ] ],  # cat backbone P4
    [ -1, 3, C3, [ 512, False ] ],  # 13

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

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

    [ [ 17, 20 ], 1, Detect, [ nc, anchors ] ],  # Detect(P3, P4)
  ]
### Python解析YAML文件的方法及详解 #### 使用PyYAML库解析YAML文件 在Python中,`PyYAML`是一个常用的第三方库,用于读取和写入YAML格式的数据。它提供了丰富的功能来处理复杂的YAML结构。 要使用`PyYAML`,首先需要安装该库: ```bash pip install pyyaml ``` 导入必要的模块并加载YAML数据可以按照如下方式进行: ```python import yaml # 加载YAML字符串 data_str = """ name: Tom Smith age: 37 spouse: name: Jane Smith age: 25 children: - name: Jimmy Smith age: 15 - name: Jenny Smith age1: 12 """ # 解析YAML字符串到字典对象 data_dict = yaml.safe_load(data_str) print(data_dict) ``` 上述代码展示了如何将一个简单的YAML字符串转换成Python中的嵌套字典[^1]。 #### 自定义表示器(Representer)以支持复杂类型 当遇到非标准的Python对象时,可以通过自定义表示器将其转化为YAML可识别的形式。例如创建一个新的类实例,并希望将其保存至YAML文件中,则需先注册相应的表示器函数[^2]: 假设有一个名为Person的新类, ```python class Person: def __init__(self, first_name, last_name): self.first_name = first_name self.last_name = last_name def person_representer(dumper, obj): return dumper.represent_mapping('!person', {"first": obj.first_name, "last": obj.last_name}) yaml.add_representer(Person, person_representer) tom = Person("Tom", "Smith") with open('output.yaml', 'w') as f: yaml.dump(tom, f) ``` 此部分说明了通过添加自定义representer可以使特殊类型的对象被正确序列化为YAML文档的一部分[^2]。 #### 将数据存储回YAML文件 除了从现有的YAML源加载数据之外,还可以利用 `dump()` 方法把Python原生数据结构导出成为新的YAML文件[^4]: ```python import yaml data_to_write = { 'a': 1, 'b': [ {'key':'value'}, ['list item'] ], } with open('new_file.yaml','w') as outfile: yaml.dump(data_to_write,outfile,default_flow_style=False) ``` 以上例子演示了一个包含列表和其他复合元素在内的字典是如何被写出到外部YAML文件里的[^4]。 #### 处理大型或复杂配置项 对于更高级的应用场景来说,可能还会涉及到环境变量替换等功能,在这种情况下就需要深入理解锚点(`&`)与别名(`*`)机制以及如何结合这些特性构建动态化的配置管理系统[^1]. --- 相关问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

几两春秋梦_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值