锚框 讨论区

http://zh.diveintodeeplearning.org/chapter_computer-vision/anchor.html

关于锚框的生成:每个像素我们一共生成n+m−1个锚框。 为什么要减1,我怎么理解的是m+n呢?不理解。

(1, 2) 和 (a, b, c) 组合后为: (1,a), (1, b), (1, c), (1, a), ( 2, a)。
其中(1, a)出现两次。所以一共有2+3-1=4个有效组合。

我的问题是:
为什么生成框的个数要是n+m-1,为什么不生成 nm个。nm 不是更合理吗?
@astonzhang

n*m会太多产生太多锚框。目前用n+m-1已经是上百万个锚框,如果用n*m,会多数倍,这样使得模型会过于复杂。

请问锚框size是如何生成的:


sizes[]是否可以根据标签的w,h统计来确定呢?

学习了下,补个自己的理解:

根据ssd论文里讲的:
image
找到faster rcnn里的具体实现如下:
image

利用ZFnet来提出框,其大小统计如下,ref

最后的检测结果在不同框下的对比:
image

在使用模型给定size[]的情况下训练出来的框整体偏大(IOU小),在想能不能调节一下size[]去得到更小更精确的框呢?

没看明白老哥,什么意思?

明白了。。

可以对自己训练集里的 Object Size 做一个 K-Means 聚类,根据聚类结果,去设计自己的 Anchor Size

谢谢,统计了下训练集的框,优化下Anchor Size再训练试试。

out = contrib.nd.MultiBoxTarget(anchors.expand_dims(axis=0),
                                ground_truth.expand_dims(axis=0),
                                nd.zeros((1, 3, 4)))

各位大佬:上面的nd.zeros((1, 3, 4)) 是什么意思,为什么要加这个?还有每个图片的 ground_truth个数是不同的,而且图片大小也不一样,生成的anchor也不一样大,那么这里还加个批量的维度有什么意义?

看了下 MultiBoxTarget 的注释,nd.zeros((1, 3, 4)) 是 cls_pred,意思是对于一幅图像,有 3 个 Object(可能是 Pad 的结果),一共有 4 类(不算 Background,因为这是在做 MultiClassEncoder 之前。)

我感觉是没有必要加的,因为默认 negative mining 是关闭的,所以不管 cls_pred 是什么数值,它都不会被用上。

至于 每个图片的 Groundtruth Truth 不一样,对于 Training 这是不影响的,因为 Training 时候真正的样本是 Anchor,只要图片大小一样,Anchor 个数就一样,所以我觉得图片应该要 resize 成一样大小(或许有不这么做的对策,我还不知道。)对于 Validation/Test,需要在 DataLoader 的 batchify_fn 里面有一个 Pad 操作(pad_val = -1),这么做是为了计算 mAP 时候方便,DataLoader 返回的是一个 MXNet.NDArray,而不是一个 大小不整齐的 list。

至于加个批量的维度有什么意义? 这就是为什么要用 Mini-Batch SGD 而不用 SGD 的原因了,课程和教程里都有讲。

1赞

谢谢。理解一些了,你看的C++ 的代码吗? python版本好像没有源码,就一个空壳。

不会 C++ :joy:

GluonCV有一个 SSDAnchorGenerator 是 Python 写得,可以看那个,代码写得很清楚。

ok 谢了

给定正负iou的时候 不应当是把feature map上的点映射回原图然后生成anchor box吗? 这一点MultiBoxPrior 有没有体现?

看生成规则,举个例子就明白了:
假设 sizes=[0.75, 0.5, 0.25], ratios=[1, 2, 0.5]。n为3,m为2
以rotio第一个元素,1.2为准,size分别为0.75、0.5、0.25。得到锚框为3
以sizes第一个原则,0.75为准,ratio分别为1.2、0.5。得到锚框为2
但是有没有发现,0.75、1.2被计算了两次,所以要减一,锚框总数为3+2-1。即n+m-1

所以通常我们会将其进行非线性变化来使得其数值上更加均匀来方便模型预测。
===这句话该怎么理解,有没有例子能够解释下。感谢各位大神

请问,contrib.nd.MultiBoxTarget 的第三个参数nd.zeros((1, 3, 4)),文档中 (https://mxnet.incubator.apache.org/api/python/symbol/contrib.html#mxnet.symbol.contrib.MultiBoxTarget) – 说是用来存放 Class predictions。 但我实际测试了一下,随便填入数值,只要形状正确,里面的值是什么并不影响最后的结果。那是不是就可以理解为,这里的输入只要形状正确,就可以了?那这个参数存在的意义就是提取形状?

我看了也是,觉得函数里没有用到。看锚框那节讲解生成标号根本没有用到cls_preds,你最后知道怎么回事了吗?