ssd网络是全卷积的,理论上可以输入任意尺寸的图片。我在测试任意尺寸输入时发现一下问题:
训练:448×448的图
测试:896×896的图
测试时使用训练时2倍的尺寸,运行网络输出结果,明显发现检测的矩形框与应当得出的检测框大小呈2倍关系,折腾了几个小时,终于明白了。
解答:anchor的size是归一化到训练图像(和特征图高度直接相关)高度的,anchor是有绝对大小,只修改测试图像大小不修改size会使anchor的绝对大小变化。
怎么知道anchor是归一化到高度的?
mxnet源码中multibox_prior.cc
float w = size * in_height / in_width / 2;
float h = size / 2;
在根据size生成anchor时,由于anchor的宽高要分别归一化到图像(特征图)的宽高,要计算出anchor实际大小再分别归一化。可以看到归一化w时乘以height所以anchor是按高度归一化的。
这就不难理解前面出现的问题了,假设size=0.1,某个fmap训练时大小224×224
训练阶段:
float w = size * 224/224 / 2=0.05
float h = size / 2=0.05;
测试阶段:
float w = size * 448/448 / 2=0.05;
float h = size / 2=0.05;
anchr的w、h相对于输入图的比例没变,但是anchor 的w、h乘以图像(特征图)宽高对应的真实大小翻倍了,这是有问题的,anchor实际上是有绝对大小的,我们需要保持anchor在训练和测试阶段大小的一致。所以如果在
修改ssd输入图片尺寸时,需要将size除以系数[测试高度/训练高度]。另外,还有一种解决方案,虽然检测框的大小不对,但是其中心坐标是对的,所以可以直接修改最终检测框,将其宽高除以系数。
核心:anchor的大小归一化到训练图像高度的