参见:https://blog.csdn.net/qq_36735489/article/details/83653816
default_params = SSDParams(
img_shape=(300, 300),
num_classes=21,
no_annotation_label=21,
feat_layers=['block4', 'block7', 'block8', 'block9', 'block10', 'block11'],
feat_shapes=[(38, 38), (19, 19), (10, 10), (5, 5), (3, 3), (1, 1)],
anchor_size_bounds=[0.15, 0.90],
# anchor_size_bounds=[0.20, 0.90],
anchor_sizes=[(21., 45.),
(45., 99.),
(99., 153.),
(153., 207.),
(207., 261.),
(261., 315.)],
# anchor_sizes=[(30., 60.),
# (60., 111.),
# (111., 162.),
# (162., 213.),
# (213., 264.),
# (264., 315.)],
anchor_ratios=[[2, .5],
[2, .5, 3, 1./3],
[2, .5, 3, 1./3],
[2, .5, 3, 1./3],
[2, .5],
[2, .5]],
anchor_steps=[8, 16, 32, 64, 100, 300],
anchor_offset=0.5,
normalizations=[20, -1, -1, -1, -1, -1],
prior_scaling=[0.1, 0.1, 0.2, 0.2]
)
其中这个anchor_sizes
是最magic的一组数字,他到底是怎么来的呢?
首先你要知道这个公式:
Sk是每个特征层的先验框大小与原图片大小之比,Smax和Smin分别是最大,最小的比例.
在SSD中一共有6个用于分类和回归的特征层(feature map),
分别是feat_layers=['block4', 'block7', 'block8', 'block9', 'block10', 'block11'],
m是就是特征层的个数,按理说分母应该是6-1=5,但是这里是5-1=4, 因为作者将第一层S1, 单独拿出来设置了.
k是第几个特征层的意思,注意k的范围是1~m, 也就是1~6.
知道这些就可以开始计算了.
Sk在实际计算中考虑到取整的问题,所有与上式有所区别:
需要向下取整.
所以你将m=5, Smin, Smax=(0.2, 0.9) 就是anchor_size_bounds=[0.20, 0.90],带入之后,
得到S1~S6: 20, 37, 54, 71, 88, 105, 其实就是挨个+17.
此时你还需要将其除以100还原回来,也就是:
0.2, 0.37, 0.54, 0.71, 0.88, 1.05
然后,我们这个是比例, 我们需要得到其在原图上的尺寸,所以需要依次乘以300, 得到:
60, 111, 162, 213, 264, 315.
最后,你会问: 30呢? 这就要说到S1’了,S1’=0.5*S1, 就是0.1, 再乘以300, 就是30.
这样, 我们有七个数, 6个区间段, 也就是6组min_size和max_size. 就可以计算每个特征层的anchor_box 的尺寸了.详细见下片博文.
可以看出作者为了不让我们搞懂他的代码,也是煞费苦心啊…
最后, 既然我们高明白了anchor_size, 这个参数直接决定了当前特征层的box 的大小, 可以看出越靠近输入层, box越小, 越靠近输出层, box越大, 所以 SSD的底层用于检测小目标, 高层用于检测大目标.