目录:
模型的整个前向传播过程
train.py入手
detector模块
backbone模块
build_box_head
先验框/数据集生成有关
build模块
transform模块
prior_bbox的生成
box_utils
余下的一些模块
loss模块
配置文件模块
SSD源码解析
本片文章主要是承接上一篇,记录了对pytorch SSD源码的一个解析(主要是怕自己过段时间忘了,当然也希望发出来和大家分享一下学习心得),过于细枝末节的东西不是很多,主要是对整个流程的结构进行梳理,整个梳理过程建议配合讲解SSD原理的文章食用,推荐:
小小将:目标检测|SSD原理与实现zhuanlan.zhihu.com的这篇硬核讲解
先看讲原理的文章(多半是蒙圈的),然后来看这里的代码细节,这样一来基本上就能够对整个SSD的核心流程有一个大概的把握。鉴于自己水平有限,难免会有理解不到位或者错误的地方,希望大佬拍砖
本文所用源码地址:
lufficc/SSDgithub.com模型的整个前向传播过程
train.py入手
从train.py入手,先看模型的整个调用关系
from
detector模块
- ssd/modeling/detector/_init_.py
from
- 找SSDDetector的定义位置
from
由此可知:build_backbone和build_box_head是关键,下面分别解释
backbone模块
- build_backbone:对于backbone部分的定义在ssd.modeling.backbone文件夹下面,作者提供了vggnet, mobileNetv2,efficient_net三个backbone。可以在代码中看到具体的定义,最需要关注的是从backbone不同阶段取出来(进行下一步卷积得到框的类别,位置)的几个特征图。以vggnet为例:
build_box_head
- build_box_head,这部分是最不好理解但又是极为关键的,
# ssd/modeling/box_head/下面定义的 SSDBoxHead 类
- make_box_predictor:上面的计算预测值的过程由ssd/modeling/box_head/box_predictor 中的make_box_predictor来执行,这是一个相当关键的步骤
这样一来,基本就理清楚了整个网络的前向过程,接下来需要搞清楚的是上面提到的我们的target是怎么来的,我们现在知道了模型总共预测了8732个框,也知道target中对应的gt_labels和gt_boxes负责和预测得到的cls_logits ,bbox_pred一一对应计算loss 所以接下来就是要知道target中的gt_labels([32, 8732])和gt_boxes[32, 8732, 4]是怎么来的。这里也就引出了SSD中很关键的一部分了,那就是prior boxes的产生。
先验框/数据集生成有关
target中对应的gt_labels和gt_boxes负责和预测得到的cls_logits ,bbox_pred一一对应计算loss。所以接下来从源码中来解读target中的gt_labels([32, 8732])和gt_boxes[32, 8732, 4]是怎么来的
build模块
还是回到train.py
from
下面要仔细的解释一下为什么我们的原始标签和bbox的坐标就突然和先验框联系起来了。上面的整个追溯流程中make_data_loader的定义是关键,
'''
transform模块
虽然说transform模块的工作就是对原始的标注数据作出各种数据增强的变换:随机裁剪,镜像,对比度/亮度,通道交换顺序等操作。但是在build_target_transform中还调用到了PriorBox,从而联系到了target_transform.py中调用的 box_utils模块,这其实就突破点。
要把这个说清楚,还得先搞清楚一个东西,那就是prior_bbox的产生
prior_bbox的生成
这个在网上许多讲SSD原理的文章中都会重点讲,其实前面的代码分析中也出现过一些铺垫。简而言之:就是在原图的尺度下产生了8732个先验框,这些框和我们取的6个特征图大小是有关的,按照这六个的大小设计会产生出原图尺度上的8732个框
#在ssd/modeling/anchors/prior_box.py
box_utils
- /ssd/data/transforms的init.py: 继续回到transform模块,可以在/ssd/data/transforms的init.py中第30行看到调用了Prior_box类!
def
- ssd/data/transforms/target_transform.py下面的SSDTargetTransform类:
#ssd/data/transforms/target_transform.py下面的SSDTargetTransform类
- 显然,这一步就需要去研究box_utils模块
#convert_locations_to_boxes其实是把ssd的输出location(这里的输出其实是位置的偏置)
前面理顺了网络的整体前向结构,刚刚又分析了prior_boxes有关的datasets的一系列操作,最后就是来分析一下loss和一些配置文件了
余下的一些模块
loss模块
整个关于loss的定义在loss.py模块下的MultiBoxLoss类,具体的计算公式在许多的讲SSD原理的文章中都有提到,结合下面原作者已经很详细的注释了的源码,其实也不难理解,所以此处不再赘述
class
配置文件模块
defaults.py:这个是整个工程的基本配置文件,有了上面的一系列铺垫,现在来看配置文件里面的各项参数设置就显得明了多了
#......