14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
importdatetime
importtqdm
importtorch
importtorch.nnasnn
importtorch.nn.functionalasF
fromtorch.autogradimportVariable
importmatplotlib.pyplotasplt
importmatplotlib.patchesaspatches
frommatplotlib.tickerimportNullLocator
importtensorflowastf
fromtorchvisionimportdatasets
fromtorchvisionimporttransforms
importtorch.optimasoptim
fromterminaltablesimportAsciiTable
解析模型参数
构件模块
Darknet搭建
搭建模型
parse_cfg 解析模型参数,将 Net 、 Convolutional 、 Shortcut 、Upsample 、 Route 、 YOLO 等模型结构信息以列表的形
式返回,便于后面模型搭建
parse_data_config 解析数据集路径
解析配置文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
defparse_model_config(path):
"""Parsestheyolo-v3layerconfigurationfileandreturnsmoduledefinitions"""
file=open(path,'r')
lines=file.read().split('\n')
lines=[xforxinlinesifxandnotx.startswith('#')]
lines=[x.rstrip().lstrip()forxinlines]#getridoffringewhitespaces
module_defs=[]
forlineinlines:
ifline.startswith('['):#Thismarksthestartofanewblock
module_defs.append({})
module_defs[-1]['type']=line[1:-1].rstrip()
ifmodule_defs[-1]['type']=='convolutional':
module_defs[-1]['batch_normalize']=0
else:
key,value=line.split("=")
value=value.strip()
module_defs[-1][key.rstrip()]=value.strip()
returnmodule_defs
defparse_data_config(path):
"""Parsesthedataconfigurationfile"""
options=dict()
options['gpus']='0,1,2,3'
options['num_workers']='10'
withopen(path,'r')asfp:
lines=fp.readlines()
forlineinlines:
line=line.strip()
ifline==''orline.startswith('#'):
continue
key,value=line.split('=')
options[key.strip()]=value.strip()
returnoptions
convolutional卷积层
maxpool最大池化(可选)
upsample上采样
route层
shortcut跳跃连接
yolo层
create_modules 函数用 parse_cfg 函数返回的模型信息列表构建网络模块:
先定义变量 hyperparams,来存储该网络的信息
当添加 nn.ModuleList 作为 nn.Module 对象的一个成员时(即添加模块到网络),所有 nn.ModuleList 内部的 nn.Module 对象(模块)
的 parameter 也被添加 作为 nn.Module 对象(即网络添加 nn.ModuleList 作为其成员)的 parameter
卷积核的深度是由上一层的卷积核数量(或特征图深度)决定的,需要追踪上一层卷及数量。路由层(route layer)从前面层得到特征
图,不仅需要追踪前一层的卷积核数量,还需要追踪之前每一层,这意味着需要持续追踪被应用卷积层的卷积核数量,用变量
output_filters 保存
nn.Sequential 类能让nn.Module 对象有序执行,用 nn.Sequential将一个模块的多个层串起来
为什么要一个空的层?
如果像其它层一样,创建路由层需要构建一个 nn.Module 对象并初始化,然后在 forward 函数中拼接特征图,但拼接操作的代码相当简短
( torch.cat),像其它层一样设计route层将导致不必要的抽象,增加代码。可以用一个空的虚拟层代替路由层,然后 forward 函数中直
接执行拼接操作
shortcut层是一个简单的add操作,也用一个空的虚拟层代替
多尺度检测
在特征图上进行多尺度预测, 在grid每个位置都有三个不同尺度的锚点.predict_transform()利用一个scale得到的feature map预测得到的
每个anchor的属性(x,y,w,h,s,s_cls1,s_cls2...),其中x,y,w,h是在网络输入图片坐标系下的值,s是方框含有目标的置信度得分,
s_cls1,s_cls_2等是方框所含目标对应每类的概率
输入的feature map(prediction变量) 维度为【batch_size, num_anchors*bbox_attrs, grid_size, grid_size】(一个batch:
),这种格式对于输出处理过程(例如通过目标置信度进行阈值处理、添加对中心的网格偏移、应用锚点等)不方便
将维度变换成【batch_size, grid_sizegrid_sizenum_anchors, 5+类别数量】的tensor,同时得到每个方框在网络输入图片 坐
标系下的(x,y,w,h)以及方框含有目标的得分以及每个类的得分
构建模块