是YOLOv3的网络构建

ops/2024/10/10 15:39:24/

YOLOv3的网络构建是一个从配置文件(cfg文件)到创建模型并定义其前向传播过程的复杂过程,以下是详细说明:

1. cfg文件

  • 作用和支持的层类型
    • YOLOv3中,cfg文件用于描述网络结构。通过修改cfg文件,可以很容易地调整网络架构。
    • 它支持多种层类型,包括convolutional(卷积层)、maxpool(最大池化层)、upsample(上采样层)、route(特征图连接层)、shortcut(跨层连接层,类似ResNet的shortcut连接)、yoloYOLO检测层)等。
  • 网络结构可视化
    • 为了更直观地理解cfg文件所描述的网络结构,可以使用一些工具,如Netron。以yolov3 - tiny.cfg为例,通过Netron可视化可以清晰地看到网络的输入输出以及各层之间的连接关系。

2. 网络模型构建

2.1 module_defs
  • 解析cfg文件得到module_defs
    • 通过parse_model_cfg函数解析cfg文件,得到module_defs对象。这个对象是一个包含多个字典的列表,每个字典保存了一个模块的相关信息。
    • 例如,对于卷积层模块,字典中可能包含batch_normalize(是否进行BN操作)、filters(输出特征图数量)、size(卷积核尺寸)、stride(卷积步长)、pad(填充大小)、activation(激活函数类型)等键值对。
  • 解析过程中的参数处理
    • 在解析过程中,函数会去除cfg文件中以#开头的注释行,然后逐行解析。当遇到[开头的行时,表示一个新模块的开始,会创建一个新的字典并添加到module_defs列表中。
    • 对于不同类型的模块,会根据其特定的参数格式进行解析。例如,对于convolutional层,如果batch_normalize为1,则在字典中设置相应的值;对于anchors参数,会将其解析为numpy数组形式。同时,函数还会检查所有解析出的参数是否符合支持的参数类型列表,如果存在不支持的字段,会抛出异常。
2.2 module_list&routs
  • 构建ModuleList和routs
    • 通过create_modules函数,根据module_defs构建ModuleListroutsModuleList类似于一个模块的列表,用于存储网络中的各个层;routs则用于存储一些层的索引信息,在routeshortcut操作中会用到。
  • 不同层类型的构建方式
    • 卷积层:对于convolutional类型的模块,根据解析出的参数创建nn.Conv2d层,并根据是否进行BN操作添加nn.BatchNorm2d层,以及设置相应的激活函数层(如nn.LeakyReLU)。同时,根据不同的激活函数类型和模型配置(如arc参数),可能会有不同的设置。
    • 最大池化层:对于maxpool类型的模块,创建nn.MaxPool2d层,并根据sizestride参数设置池化大小和步长。如果size == 2stride == 1(如在yolov3 - tiny中某些情况),还会添加nn.ZeroPad2d层进行填充。
    • 上采样层:对于upsample类型的模块,创建nn.Upsample层,并根据stride参数设置上采样因子。
    • Route层:对于route类型的模块,根据layers参数指定的层索引,计算输出特征图的通道数(通过对相应层的输出通道数求和),并将指定的层索引添加到routs中。
    • Shortcut层:对于shortcut类型的模块,根据from参数指定的索引,获取相应层的输出特征图通道数,并将相关索引添加到routs中。
    • yolo层:对于yolo类型的模块,创建YOLOLayer层,设置anchorsnc(类别数量)、img_size等参数。同时,根据不同的arc参数,会对卷积层的bias进行特殊设置。例如,对于defaultFdefaultpw等不同的arc值,会设置不同的objclsbias值,以解决样本不平衡问题,具体是在原有bias基础上进行调整,使其在初始训练阶段避免过度激活,提高模型训练的稳定性和性能。
2.3 yolo_layers
  • 获取yolo层的序号
    • 通过get_yolo_layers函数获取yolo层在整个模型中的序号。该函数通过解析module_defs,查找类型为yolo的模块,并返回其在列表中的索引。例如,对于yolov3.cfg文件,可能返回[82, 94, 106]等序号,表示第83、94、106个层是yolo层。

3. forward函数

  • 前向传播过程描述
    • forward函数中,实现了模型的前向传播过程。它通过遍历module_defsmodule_list中的模块,根据模块类型进行相应的操作。
  • 不同层类型在前向传播中的处理
    • 卷积层、上采样层、池化层:对于convolutionalupsamplemaxpool类型的模块,直接调用相应模块的forward函数进行前向传播,将输入数据传递给下一层。
    • Route层:对于route类型的模块,如果layers参数只有一个值,则直接获取对应层的输出作为当前层的输出;如果有多个值,则将指定的多层输出在通道维度上进行拼接(使用torch.cat函数)作为当前层的输出。如果在拼接过程中遇到darknet reorg层相关的情况,可能需要对其中一层进行下采样操作(使用F.interpolate函数)后再进行拼接。
    • Shortcut层:对于shortcut类型的模块,将当前层的输入与指定层(根据from参数)的输出相加作为当前层的输出。
    • yolo层:对于yolo类型的模块,调用YOLOLayerforward函数进行处理,并将输出添加到output列表中。如果是训练模式,直接返回output列表;如果是测试模式或ONNX_EXPORT模式,则根据不同的模式要求对output列表进行进一步处理,如在测试模式下,对输出进行一些后处理操作(如对坐标进行激活函数处理、根据arc参数对类别进行处理等),并将处理后的结果进行适当的形状调整后返回。
      YOLOv3的前向传播过程是数据在网络中依次经过各个层进行处理的过程,以下是详细解释:

YOLOv3__43">4. YOLOv3 的前向传播过程

forward函数中实现了前向传播过程。它通过遍历module_defs(存储cfg文件解析后的模块信息)和module_list(构建的网络模块列表)中的模块,根据模块类型进行相应的操作,最终得到YOLO层的输出。

5. 不同层类型的处理

卷积层、上采样层、池化层
  • 对于convolutional(卷积层)、upsample(上采样层)、maxpool(最大池化层)类型的模块,在前向传播过程中只需要经过相应模块的forward函数即可。
  • 即直接将输入数据x传递给模块的forward函数进行处理,得到输出后继续传递给下一层。例如对于卷积层,会进行卷积运算、BN操作(如果有)以及激活函数操作(如果有)。
Route层
  • Route层用于将几个层的内容进行拼接。
  • 首先获取layers参数指定的层索引,如果layers只有一个值,那么直接获取对应层的输出作为当前层的输出,即x = layer_outputs[layers[0]]
  • 如果layers有多个值,尝试将指定的多层输出在通道维度上进行拼接(使用torch.cat函数)。如果在拼接过程中遇到问题(例如可能涉及darknet reorg层相关的情况),可能需要对其中一层进行下采样操作(使用F.interpolate函数),然后再进行拼接,最终得到x = torch.cat([layer_outputs[i] for i in layers], 1)
Shortcut层
  • Shortcut层类似于ResNet的跨层连接操作。
  • 它将当前层的输入与指定层(根据from参数)的输出相加作为当前层的输出,即x = x + layer_outputs[int(mdef['from'])]
yolo层
  • 对于yolo类型的模块,调用YOLOLayerforward函数进行处理,并将输出添加到output列表中。
  • 在训练模式下,如果self.trainingTrue,则直接返回output列表,这个列表包含了各个yolo层的输出,符合YOLO要求的Tensor格式。
  • 在测试模式或ONNX_EXPORT模式下:
    • 如果是ONNX_EXPORT模式,需要对output进行一些特殊处理,例如将output中的数据进行拼接和调整形状,最终返回符合ONNX格式要求的结果。
    • 在测试模式下,首先获取output列表中的数据,对其进行一些后处理操作。例如对于坐标部分,会根据公式进行激活函数处理(如io[..., :2] = torch.sigmoid(io[..., :2]) + self.grid_xy),根据arc参数对类别部分进行处理(如使用sigmoidsoftmax等激活函数),然后将处理后的结果进行适当的形状调整(如return io.view(bs, -1, self.no), p)后返回。

6. 记录中间结果

在整个前向传播过程中,使用layer_outputs列表记录每个层的输出(除了route层中不需要记录的部分),以便后续层使用。例如,shortcut层和route层(部分情况)会用到前面层的输出。同时,根据不同的阶段(训练、测试、ONNX_EXPORT),对最终的输出进行相应的处理和返回。


http://www.ppmy.cn/ops/123560.html

相关文章

MMDetection研究-1.入门及框架

记录MMDetection研究过程 0.前言 参考: 1.MMDetection框架入门教程(完全版) 2. 1.框架概述 MMDetection是商汤和港中文大学针对目标检测任务推出的一个开源项目,它基于Pytorch实现了大量的目标检测算法,把数据集构建、模型搭建、训练策略等过程都封装成了一个个模块,…

WordPress修改固定链接后301的重定向方法

网站改版实际上是很忌讳的,尤其是针对已被搜索引擎收录的网站,新站不用考虑这些问题,而已经收录的网站网页在不遵守搜索引擎规则的前提下,是会被降权,关键词排名下滑、流量IP会被剥夺、收录会减少 、业务成交量会急剧下…

eNSP网络配置指南:IP设置、DNS、Telnet、DHCP与路由表管理

1.eNSP基本操作和路由器IP配置命令 登录设备:通过Console口或通过eNSP的Telnet/SSH客户端登录到设备。进入特权模式:输入system-view进入系统视图。接口配置: 进入接口视图,例如interface GigabitEthernet0/0/0。配置IP地址和子网…

spring boot发送邮件

文章目录 项目目录结构添加maven依赖application.yml配置发信人信息编码测试创建 Email 工具类 EmailUtil测试发送邮件 项目目录结构 添加maven依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-mail&l…

从0开始linux(12)——命令行参数与环境变量

欢迎来到博主的专栏&#xff1a;从0开始linux 博主ID&#xff1a;代码小豪 文章目录 命令行参数环境变量 我们先打断一下关于进程的话题&#xff0c;博主先来介绍两个东西&#xff0c;分别是命令行参数与环境变量。那么有人看到这就会问了&#xff0c;难道说命令行参数和环境变…

使用Materialize制作unity的贴图,Materialize的简单教程,Materialize学习日志

Materialize 官网下载地址&#xff1a;http://boundingboxsoftware.com/materialize/ github源码地址&#xff1a;https://github.com/BoundingBoxSoftware/Materialize 下载地址&#xff1a;http://boundingboxsoftware.com/materialize/getkey.php 下载后解压运行exe即可 …

萤火php端: 查询数据的时候报错: “message“: “Undefined index: pay_status“,

代码&#xff1a;getGoodsFromHistory <?php // ---------------------------------------------------------------------- // | 萤火商城系统 [ 致力于通过产品和服务&#xff0c;帮助商家高效化开拓市场 ] // -----------------------------------------------------…

【QT Quick】C++交互:调用QML函数

在本节中&#xff0c;我们将深入探讨如何在C中调用QML函数。这项功能非常常用&#xff0c;尤其是在需要将C逻辑与QML界面进行交互时。我们将重点关注invokeMethod函数&#xff0c;它支持多种参数形式&#xff0c;并允许我们灵活地处理不同的调用场景。 invokeMethod概述 invo…