向AI转型的程序员都关注了这个号👇👇👇
本篇我们会介绍 yolo.py,这是YOLO的特定模块,和网络构建有关。在 YOLOv5源码中,模型的建立是依靠 yolo.py 中的函数和对象完成的,这个文件主要由三个部分:parse_model函数、Detect类和Model类组成。
yolo.py文件位置在./models/yolo.py
文章代码逐行手打注释,每个模块都有对应讲解,一文帮你梳理整个代码逻辑!
一、 导包和基本配置 1.1 导入安装好的python库
首先,导入一下常用的python库:
argparse: 它是一个用于命令项选项与参数解析的模块,通过在程序中定义好我们需要的参数,argparse 将会从 sys.argv 中解析出这些参数,并自动生成帮助和使用信息
sys:它是与python解释器交互的一个接口,该模块提供对解释器使用或维护的一些变量的访问和获取,它提供了许多函数和变量来处理 Python 运行时环境的不同部分
copy: Python 中赋值语句不复制对象,而是在目标和对象之间创建绑定关系。copy模块提供了通用的浅层复制和深层复制操作
pathlib: 这个库提供了一种面向对象的方式来与文件系统交互,可以让代码更简洁、更易读
1.2 获取当前文件的绝对路径
这段代码会获取 当前文件的绝对路径,并使用Path库将其转换为Path对象。
这一部分的主要作用有两个:
将当前项目添加到系统路径上,以使得项目中的模块可以调用。
将当前项目的相对路径保存在ROOT中,便于寻找项目中的文件。
1.3 加载自定义模块
这些都是用户自定义的库,由于上一步已经把路径加载上了,所以现在可以导入,这个顺序不可以调换。具体来说,代码从如下几个文件中导入了部分函数和类:
models.common: 这个是yolov5的网络结构
models.experimental: 实验性质的代码,包括MixConv2d、跨层权重Sum等
utils.autoanchor: 定义了自动生成锚框的方法
utils.general: 定义了一些常用的工具函数,比如检查文件是否存在、检查图像大小是否符合要求、打印命令行参数等等
utils.plots: 定义了Annotator类,可以在图像上绘制矩形框和标注信息
utils.torch_utils: 定义了一些与PyTorch有关的工具函数,比如选择设备、同步时间等
通过导入这些模块,可以更方便地进行目标检测的相关任务,并且减少了代码的复杂度和冗余。
二、parse_model函数
parse_model函数用在DetectionModel模块中,主要作用是解析模型yaml的模块,通过读取yaml文件中的配置,并且到common.py中找到相对于的模块,然后组成一个完整的模型解析模型文件(字典形式),并搭建网络结构。简单来说,就是把yaml文件中的网络结构实例化成对应的模型。后续如果需要动模型框架的话,需要对这个函数做相应的改动。
2.1 获取对应参数
这段代码主要是获取配置dict里面的参数,并打印最开始展示的网络结构表的表头。
我们先解释几个参数,d和ch,na和no:
d: yaml 配置文件(字典形式),yolov5s.yaml中的6个元素 + ch
ch: 记录模型每一层的输出channel,初始ch=[3],后面会删除
na: 判断anchor的数量
no: 根据anchor数量推断的输出维度
这里有一行代码我们上篇YOLOv5源码逐行超详细注释与解读(5)——配置文件yolov5s.yaml就见过了:
这里就是读取了 yaml 文件的相关参数(参数含义忘了的话再看看上篇哦)
2.2 搭建网络前准备
这段代码主要是遍历backbone和head的每一层,获取搭建网络前的一系列信息。
我们还是先解释参数,layers、save和c2:
layers: 保存每一层的层结构
save: 记录下所有层结构中from不是-1的层结构序号
c2: 保存当前层的输出channel
然后开始迭代循环backbone与head的配置。for i, (f, n, m, args) in enumerate(d['backbone'] + d['head']):中有几个参数
f:from,当前层输入来自哪些层
n:number,当前层次数 初定
m:module,当前层类别
args:当前层类参数 初定
接着还用到一个函数eval,主要作用是将字符串当成有效的表达式来求值,并且返回执行的结果。在这里简单来说,就是实现list、dict、tuple与str之间的转化。
2.3 更新当前层的参数,计算c2
这段代码主要是更新当前层的args,计算c2(当前层的输出channel)
首先网络将C3中的BottleNeck数量乘以模型缩放倍数n*gd控制模块的深度缩放,举个栗子,对于yolo5s来讲,gd为0.33,那么就是n*0.33,也就是把默认的深度缩放为原来的1/3。
然后将m实例化成同名模块,别看列举了那么多模块,目前只用到Conv,SPP,Focus,C3,nn.Upsample。对于以上的这几种类型的模块,ch是一个用来保存之前所有的模块输出的channle,ch[-1]代表着上一个模块的输出通道。args[0]是默认的输出通道。
这样以来,c1=ch[f]就代表输入通道c1为f指向的层的输出通道,c2=args[0]就代表输出通道c2为yaml的args中的第一个变量。注意,如果输出通道不等于255即Detect层的输出通道, 则将通道数乘上width_multiple,并调整为8的倍数。通过函数make_divisible来实现
make_divisible代码如下:
2.4 使用当前层的参数搭建当前层
这段代码主要是使用当前层的参数搭建当前层。
经过以上处理,args里面保存的前两个参数就是module的输入通道数、输出通道数。只有BottleneckCSP和C3这两种module会根据深度参数n调整该模块的重复迭加次数
然后进行的是其他几种类型的Module判断:
如果是BN层,只需要返回上一层的输出channel,通道数保持不变。
如果是Concat层,则将f中所有的输出累加得到这层的输出channel,f是所有需要拼接层的index,输出通道c2是所有层的和。
如果是Detect层,则对应检测头部分,这块下一小节细讲。
Contract和Expand目前未在模型中使用。
2.5 打印和保存layers
这段代码主要是打印当前层结构的一些基本信息并保存。
把构建的模块保存到layers里,把该层的输出通道数写入ch列表里。待全部循环结束后再构建成模型。
返回值:
return nn.Sequential(*layers): 网络的每一层的层结构
return sorted(save): 把所有层结构中from不是-1的值记下 并排序 [4, 6, 10, 14, 17, 20, 23]
至此模型就全部构建完毕了。
下面详细介绍一下各个模块。
🚀 三、Detect模块
Detect 模块是 YOLO 网络模型的最后一层 (对应 yaml 文件最后一行),通过 yaml 文件进行声明,格式为:
3.1 获取预测得到的参数
这段代码主要是获取预测得到的各种信息。
detection layer 相当于yolov3中的YOLOLayer层,我们解释一下包含的参数:
nc: 分类数量
no: 每个anchor的输出数,为(x,y,w,h,conf) + nc = 5 + nc 的总数
nl: 预测层数,此次为3
na: anchors的数量,此次为3
grid: 格子坐标系,左上角为(1,1),右下角为(input.w/stride,input.h/stride)
3.2 向前传播
这段代码主要是对三个feature map分别进行处理:(n, 255, 80, 80),(n, 255, 40, 40),(n, 255, 20, 20)
首先进行for循环,每次i的循环,产生一个z。维度重排列:(n, 255, _, _) -> (n, 3, nc+5, ny, nx) -> (n, 3, ny, nx, nc+5),三层分别预测了80*80、40*40、20*20次。
接着 构造网格,因为推理返回的不是归一化后的网格偏移量,需要再加上网格的位置,得到最终的推理坐标,再送入nms。所以这里构建网格就是为了纪律每个grid的网格坐标 方面后面使
最后按损失函数的回归方式来转换坐标,利用sigmoid激活函数计算定位参数,cat(dim=-1)为直接拼接。注意:训练阶段直接返回x ,而预测阶段返回3个特征图拼接的结果
3.3 相对坐标转换到grid绝对坐标系
这段代码主要是将相对坐标转换到grid绝对坐标系。
首先构造网格标尺坐标
indexing='ij' : 表示的是i是同一行,j表示同一列
indexing='xy' : 表示的是x是同一列,y表示同一行
grid复制成3倍,因为是3个框。anchor_grid是每个anchor宽高。anchor_grid = (self.anchors[i].clone * self.stride[i])。注意这里为啥要乘呢?因为在外面已经把anchors给除了对应的下采样率,这里再乘回来。
原文地址
机器学习算法AI大数据技术
搜索公众号添加: datanlp
阅读过本文的人还看了以下文章:
TensorFlow 2.0深度学习案例实战
基于40万表格数据集TableBank,用MaskRCNN做表格检测
《基于深度学习的自然语言处理》中/英PDF
Deep Learning 中文版初版-周志华团队
【全套视频课】最全的目标检测算法系列讲解,通俗易懂!
《美团机器学习实践》_美团算法团队.pdf
《深度学习入门:基于Python的理论与实现》高清中文PDF+源码
《深度学习:基于Keras的Python实践》PDF和代码
特征提取与图像处理(第二版).pdf
python就业班学习视频,从入门到实战项目
2019最新《PyTorch自然语言处理》英、中文版PDF+源码
《21个项目玩转深度学习:基于TensorFlow的实践详解》完整版PDF+附书代码
《深度学习之pytorch》pdf+附书源码
PyTorch深度学习快速实战入门《pytorch-handbook》
【下载】豆瓣评分8.1,《机器学习实战:基于Scikit-Learn和TensorFlow》
《Python数据分析与挖掘实战》PDF+完整源码
汽车行业完整知识图谱项目实战视频(全23课)
李沐大神开源《动手学深度学习》,加州伯克利深度学习(2019春)教材
笔记、代码清晰易懂!李航《统计学习方法》最新资源全套!
《神经网络与深度学习》最新2018版中英PDF+源码
将机器学习模型部署为REST API
yolo3 检测出图像中的不规则汉字
同样是机器学习算法工程师,你的面试为什么过不了?
前海征信大数据算法:风险概率预测
【Keras】完整实现‘交通标志’分类、‘票据’分类两个项目,让你掌握深度学习图像分类
特征工程(一)
特征工程(二) :文本数据的展开、过滤和分块
特征工程(三):特征缩放,从词袋到 TF-IDF
特征工程(四): 类别特征
特征工程(五): PCA 降维
特征工程(六): 非线性特征提取和模型堆叠
特征工程(七):图像特征提取和深度学习
如何利用全新的决策树集成级联结构gcForest做特征工程并打分?
Machine Learning Yearning 中文翻译稿
蚂蚁金服2018秋招-算法工程师(共四面)通过
全球AI挑战-场景分类的比赛源码(多模型融合)
斯坦福CS230官方指南:CNN、RNN及使用技巧速查(打印收藏)
中科院Kaggle全球文本匹配竞赛华人第1名团队-深度学习与特征工程
不断更新资源
深度学习、机器学习、数据分析、python
搜索公众号添加: datayx
网友评论
最新评论
讲解,一文帮你梳理整个代码逻辑!一、 导包和基本配置 1.1 导入安装好的python库 首先,导入一下常用的python库:argparse: 它是一个用于命令项选项与参数解析的模块,
数和类:models.common: 这个是yolov5的网络结构models.experimental: 实验性质的代码,包括MixConv2d、跨层权重Sum等
循环backbone与head的配置。for i, (f, n, m, args) in enumerate(d['backbone'] + d['head']):中有几个参数f:from,当前层
个文件中导入了部分函数和类:models.common: 这个是yolov5的网络结构models.experimental: 实验性质的代码,包括MixConv2d、跨层权重Sum