文章目录
说明:
- 代码来源:PyTorch-YOLOv3:https://github.com/eriklindernoren/PyTorch-YOLOv3
- 模型是通过论文作者的 .cfg 配置文件自动生成的。
模型构建如下:
1. 模型构建过程
1. 第一步:理解 模型配置文件 yolov3.cfg
YOLO 模型根据一个.cfg 配置文件生成的。配置文件路径:opt.model_def
的默认地址是 “config/yolov3.cfg”
“yolov3.cfg” 文件的部分内容如下:
[net]
# Testing
#batch=1
#subdivisions=1
# Training
batch=16
subdivisions=1
width=416
........
[convolutional]
batch_normalize=1
filters=32
size=3
.......
[shortcut]
from=-3
activation=linear
......
[yolo]
mask = 6,7,8
anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326
classes=80
num=9
jitter=.3
ignore_thresh = .7
truth_thresh = 1
random=1
[route]
layers = -4
......
[upsample]
stride=2
......
2. 第二步:解析 config_path 配置文件,生成 module_defs 列表
self.module_defs = parse_model_config(config_path) # model.py 文件中解析
parse_model_config
函数:解析 “config/yolov3.cfg” 文件内容成字典,
parse_model_config(config_path)
解析后的结果 self.module_defs
(字典)如下:
module_defs 列表 内容如下:
[{'type': 'net', 'batch': '16', 'subdivisions': '1', 'width': '416', 'height': '416', 'channels': '3', 'momentum': '0.9', 'decay': '0.0005', 'angle': '0', 'saturation': '1.5', 'exposure': '1.5', 'hue': '.1', 'learning_rate': '0.001', 'burn_in': '1000', 'max_batches': '500200', 'policy': 'steps', 'steps': '400000,450000', 'scales': '.1,.1'},
{'type': 'convolutional', 'batch_normalize': '1', 'filters': '32', 'size': '3', 'stride': '1', 'pad': '1', 'activation': 'leaky'},
{'type': 'convolutional', 'batch_normalize': '1', 'filters': '64', 'size': '3', 'stride': '2', 'pad': '1', 'activation': 'leaky'},
{'type': 'convolutional', 'batch_normalize': '1', 'filters': '32', 'size': '1', 'stride': '1', 'pad': '1', 'activation': 'leaky'},
{'type': 'convolutional', 'batch_normalize': '1', 'filters': '64', .....
......
}
3. 第三步:根据 module_defs 列表,创建 module_list 模型列表
- module_list 模型列表,即一个
nn.ModuleList()
列表, 将网路的各个层nn.Sequential()
依次添加在其中。(如 conv、maxpool、upsample、route、shortcut、yolo 层) - 构建模型列表是为了给 model.forward() 函数使用的。
self.hyperparams, self.module_list = create_modules(self.module_defs)
print(len(self.module_defs)) # 107
print(len(self.module_list)) # 107
self.hyperparams
的内容(由 module_defs 列表中第一个字典的内容 构造的)如下:
{'type': 'net', 'batch': '16', 'subdivisions': '1',
'width': '416', 'height': '416', 'channels': '3',
'momentum': '0.9', 'decay': '0.0005', 'angle': '0',
'saturation': '1.5', 'exposure': '1.5', 'hue': '.1',
'learning_rate': '0.001', 'burn_in': '1000',
'max_batches': '500200', 'policy': 'steps',
'steps': '400000,450000', 'scales': '.1,.1'}
self.module_list
的内容(由 module_defs 列表中除了第一个字典的其他内容 构造的)如下:
module_list 内容如下:
ModuleList(
(0): Sequential(
(conv_0): Conv2d(3, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(batch_norm_0): BatchNorm2d(32, eps=1e-05, momentum=0.9, affine=True, track_running_stats=True)
(leaky_0): LeakyReLU(negative_slope=0.1)
)
(1): Sequential(
(conv_1): Conv2d(32, 64, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
(batch_norm_1): BatchNorm2d(64, eps=1e-05, momentum=0.9, affine=True, track_running_stats=True)
(leaky_1): LeakyReLU(negative_slope=0.1)
)
......
(4): Sequential(
(shortcut_4): EmptyLayer()
)
......
(11): Sequential(
(shortcut_11): EmptyLayer()
)
(12): Sequential(
(conv_12): Conv2d(128, 256, kern