关于SSD默认框产生的详细解读

关于SSD的训练脚本ssd_pascal.py请参看博主博文:点击打开链接

本文详细解读ssd默认框的产生过程。

1. 默认框产生的个数

        我们都知道SSD默认框从6层卷积层输出的特征图中产生,分别为conv4_3、fc7、conv6_2、conv7_2、conv8_2、conv9_2。这6个特征层产生的特征图的大小分别为38*38、19*19、10*10、5*5、3*3、1*1。每个n*n大小的特征图中有n*n个中心点,每个中心点产生k个默认框,六层中每层的每个中心点产生的k分别为4、6、6、6、4、4。所以6层中的每层取一个特征图共产生38*38*4+19*19*6+10*10*6+5*5*6+3*3*4+1*1*4=8732个默认框。

2. 特征图产生min_sizes和max_sizes的计算方式

        对ssd产生的默认框的大小计算首先要计算参数min_sizes和max_sizes,这些参数具体在ssd_pascal.py中有计算方法。代码如下:

#参数生成先验。  
#输入图像的最小尺寸  
min_dim = 300   #######维度  
# conv4_3 ==> 38 x 38  
# fc7 ==> 19 x 19  
# conv6_2 ==> 10 x 10  
# conv7_2 ==> 5 x 5  
# conv8_2 ==> 3 x 3  
# conv9_2 ==> 1 x 1  
mbox_source_layers = ['conv4_3', 'fc7', 'conv6_2', 'conv7_2', 'conv8_2', 'conv9_2'] #####prior_box来源层,可以更改。很多改进都是基于此处的调整。  
# in percent %  
min_ratio = 20 ####这里即是论文中所说的Smin=0.2,Smax=0.9的初始值,经过下面的运算即可得到min_sizes,max_sizes。具体如何计算以及两者代表什么,请关注我的博客SSD详解。这里产生很多改进。  
max_ratio = 90  
####math.floor()函数表示:求一个最接近它的整数,它的值小于或等于这个浮点数。  
step = int(math.floor((max_ratio - min_ratio) / (len(mbox_source_layers) - 2)))####取一个间距步长,即在下面for循环给ratio取值时起一个间距作用。可以用一个具体的数值代替,这里等于17。  
min_sizes = []  ###经过以下运算得到min_sizes和max_sizes。  
max_sizes = []  
for ratio in xrange(min_ratio, max_ratio + 1, step):  ####从min_ratio至max_ratio+1每隔step=17取一个值赋值给ratio。注意xrange函数的作用。  
########min_sizes.append()函数即把括号内部每次得到的值依次给了min_sizes。  
  min_sizes.append(min_dim * ratio / 100.)  
  max_sizes.append(min_dim * (ratio + step) / 100.)  
min_sizes = [min_dim * 10 / 100.] + min_sizes  
max_sizes = [min_dim * 20 / 100.] + max_sizes  
steps = [8, 16, 32, 64, 100, 300]  ###这一步要仔细理解,即计算卷积层产生的prior_box距离原图的步长,先验框中心点的坐标会乘以step,相当于从feature map位置映射回原图位置,比如conv4_3输出特征图大小为38*38,而输入的图片为300*300,所以38*8约等于300,所以映射步长为8。这是针对300*300的训练图片。  
aspect_ratios = [[2], [2, 3], [2, 3], [2, 3], [2], [2]]  #######这里指的是横纵比,六种尺度对应六个产生prior_box的卷积层。具体可查看生成的train.prototxt文件一一对应每层的aspect_ratio参数,此参数在caffe.proto中有定义,关于aspect_ratios如何把其内容传递给了aspect_ratio,在model_libs.py文件中有详细定义。  
##在此我们要说明一个事实,就是文中的长宽比是如何产生的,这里请读者一定要参看博主博文《SSD详解(一)》中的第2部分内容,关于prior_box的产生。  

如上代码再结合prior_box_layer.cpp产生先验框,然后再结合bbox_util.cpp对先验框进行匹配。

        首先根据以上代码,六个特征层共产生6组min_sizes和max_sizes。另外min_dim=300,ratio取20到90即min_ratio=20,max_ratio=90。

        然后根据代码的计算公式,我们还需要step,注意是step不是steps,两者的作用不一样,在代码中有博主的注释。这里计算后step=(max_ratio-min_ratio)/(len(mbox_source_layers)-2)=(90-20)/(6-2)=17。要说这个step的作用,其实就是取一个间隔,全文看完你就应该明白了。其实这里用了一个复杂的公式说白了就是显得代码高大上一点。

        然后就开始计算min_sizes和max_sizes了,首先定义数组min_sizes[]和max_sizes[]用来存放计算结果,没有初始化说明默认为0,。然后计算conv4_3产生的min_sizes和max_sizes。根据代码中的公式计算:min_sizes=[min_dim*10/100]+min_sizes和max_sizes=[min_dim*20/100]+max_sizes得到结果为min_sizes=[300*10/100]+0=30,而max_sizes=[300*20/100]+0=60。这样conv4_3的计算公式被计算分别为30和60。这里为什么要先计算下面两行产生conv4_3的结果而不是使用上面两行公式产生博主也没有搞明白,欢迎指教。

        然后根据公式min_sizes.append(min_dim*ratio/100)和公式max_sizes.append(min_dim*(ratio+step)/100)来计算剩下5层的min_size和max_sizes。这里需要用到ratio和step,我们前面讲了step=17,根据代码for ratio in xrange(min_ratio, max_ratio+1, step)(这句的意思我们在代码中有注释,即在min_ratio和max_ratio之间即20-90之间以step=17为间隔产生一组数据赋值给ratio),最终ratio=[20,37,54,71,88]。所以对于剩余5层所产生的min_sizes和max_sizes分别为:

fc7:min_sizes=min_dim*ratio/100=300*20/100=60,max_sizes=min_dim*(ratio+step)/100=300*(20+17)/100=111;

conv6_2:min_sizes=min_dim*ratio/100=300*37/100=111,max_sizes=min_dim*(ratio+step)/100=300*(37+17)/100=162;

conv7_2:min_sizes=min_dim*ratio/100=300*54/100=162,max_sizes=min_dim*(ratio+step)/100=300*(54+17)/100=213;

conv8_2:min_sizes=min_dim*ratio/100=300*71/100=213,max_sizes=min_dim*(ratio+step)/100=300*(71+17)/100=264;

conv9_2:min_sizes=min_dim*ratio/100=300*88/100=213,max_sizes=min_dim*(ratio+step)/100=300*(88+17)/100=315;

        所以,最终计算的结果为:


3. 产生默认框的大小的计算方式

文中代码显示,给出的长宽比为

aspect_ratios = [[2], [2, 3], [2, 3], [2, 3], [2], [2]] 

        这里并不是paper中所给出的ar={1,2,3,1/2,1/3},这个比例是计算出来的。

        首先我们要知道,我们在前面也讲了,每层的特征图的每个中心点分别会产生4、6、6、6、4、4个默认框,但我们要知道为什么是这几个默认框,这里就和aspect_ratios有关系了。

        在SSD中6层卷积层的每个特征图的每个中心点会产生2个不同大小的正方形默认框,另外每设置一个aspect_ratio则会增加两个长方形默认框,而文中代码对于6层的aspect_ratio个数分别为1、2、2、2、1、1,所以这也就是为什么会产生4、6、6、6、4、4个默认框了。例如conv4_3默认生成两个不同大小的正方形默认框,另外又有一个aspect_ratio=2产生了两个长方形默认框,所以总共有4个。再如fc7,默认生成两个正方形默认框,另外又有aspect_ratio=[2,3],所以又生成了4个不同的长方形默认框,共有6个不同大小的默认框。

        接着我们再讲这些产生的默认框的大小计算。这里参考paper中的计算公式,我们可以知道,对于产生的正方形的默认框,一大一小共两个,其边长计算公式为:小边长=min_size,而大边长=sqrt(min_size*max_size)。对于产生的长方形默认框,我们需要计算它的高(height)和宽(width),其中,height=1/sqrt(aspect_ratio)*min_size,width=sqrt(aspect_ratio)*min_size,对其高和宽翻转后得到另一个面积相同但宽高相互置换的长方形。如图所示:


根据以上分析,我们可以计算6层中每个特征图的每个中心点所产生的默认框的大小,分别如下:

conv4_3:小正方形边长=min_size=30,大正方形边长=sqrt(min_size*max_size)=sprt(30*60)=42.42;

                   长方形的宽=sqrt(aspect_ratio)*min_size=sqrt(2)*30,高=1/sqrt(aspect_ratio)*min_size=30/sqrt(2),宽高比刚好为2:1;

                    将以上宽高旋转90度产生另一个长方形,宽高比变为1:2。

fc7:小正方形边长=min_size=60,大正方形边长=sqrt(min_size*max_size)=sprt(60*111)=81.6;

                   第1组长方形的宽=sqrt(aspect_ratio)*min_size=sqrt(2)*60,高=1/sqrt(aspect_ratio)*min_size=60/sqrt(2),宽高比刚好为2:1;

                              将以上宽高旋转90度产生另一个长方形,宽高比变为1:2。

                   第2组长方形的宽=sqrt(aspect_ratio)*min_size=sqrt(3)*60,高=1/sqrt(aspect_ratio)*min_size=60/sqrt(3),宽高比刚好为3:1;

                              将以上宽高旋转90度产生另一个长方形,宽高比变为1:3。

conv6_2:小正方形边长=min_size=111,大正方形边长=sqrt(min_size*max_size)=sprt(111*162);

                   第1组长方形的宽=sqrt(aspect_ratio)*min_size=sqrt(2)*111,高=1/sqrt(aspect_ratio)*min_size=111/sqrt(2),宽高比刚好为2:1;

                              将以上宽高旋转90度产生另一个长方形,宽高比变为1:2。

                   第2组长方形的宽=sqrt(aspect_ratio)*min_size=sqrt(3)*111,高=1/sqrt(aspect_ratio)*min_size=111/sqrt(3),宽高比刚好为3:1;

                              将以上宽高旋转90度产生另一个长方形,宽高比变为1:3。

        conv7_2、conv8_2、conv9_2我们这里就不再计算了,相信大家看完以上应该明白了如何计算,具体实现的步骤请大家参考脚本prior_box_layer.cpp。这就是我们先验框的计算方式。

       另外先验框与ground truth框的匹配通过函数CHECK_GT()函数实现,具体在bbox_util.cpp脚本中实现,请大家一一阅读。如有意见请私信或留言。




评论 36
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值