前言
自进入吉大,开始硕士生活之后,本人便很少有时间写一些blog,毕竟忙起来之后时间真的比较紧,不过细想想感觉自己也没忙出个什么。这次,导师给安排的项目是病变细胞检测的项目(Emmmmm,这是我的第三个项目,我研一),在深度学习领域上,属于目标检测的范畴。我主要采用的是RetinaNet,那么今天简单总结一下anchor的相关知识。
什么是Anchor
为什么会出现anchor、anchor处理之前目标检测用的是什么技术?这些问题本次一一不涉及
从学术的角度来说,anchor就是拥有多尺度、多种宽高比例的box,也就是multi-scale and different aspect ratio 。
我们知道,图片分类和实例分割分别属于image-level和pix-level,而目标检测则属于region-level。那么region的信息,我们是如何向网络提供的呢?
anchor的设置,相当于提前在图片上做预选,通常在生成anchor时,每一张图片上将会对应成千上万的anchor也就是候选框,可想而知,如此庞大的候选框数量,肯定能够满足对图上实例进行检测的需要,效果如下图所示:
可以看到,整张图片上存在许多不同形状的小框框,但是这些框框的总数也只是原anchor数量的1%。
那么有了这些框框,网络便可以学习这些框框中的事物以及框框的位置,最终可以进行分类和回归(还涉及IOU的计算等等,本篇文章不涉及)。
numpy + python 实现anchor
我们以Retinanet网络中的anchor为例,使用numpy和python生成,具体RetinaNet网络中的anchor是什么形式的,请移步ICCV2017kaiming大神的论文,可详细了解。
anchor-size:[32,64,128,256,512]
每个anchor-size对应着三种scale和三个ratio,那么每个anchor-size将对应生成9个先验框,同时生成的所有先验框均满足:
- 同一种scale,面积相同,形状不同
- 同一种ratio,形状相同,面积不同
- 对于scale和ratio的理解:scale指anchor的大小(可以当做宽)、ratio即为宽高比
下面为代码思路,我们以32为例:
- 首先,由于存在三种scale和三种ratio,则对于w=h=32的基本anchor,则有存在9种anchor。
- 其次对于每一个anchor,我么要保存其左上角和右下角两个点的坐标,需要四个位置进行保存。
- 综上,我们生成形状为 [9,4]的数组。
sizes = [32, 64, 128, 256, 512]
strides = [8, 16, 32, 64, 128]
ratios = np.array([0.5, 1, 2], keras.backend.floatx())
scales = np.array([2 ** 0, 2 ** (1.0 / 3.0), 2 ** (2.0 / 3.0)],keras.backend.floatx())
num_anchors = len(ratios) * len(scales)
anchors = np.zeros((num_anchors, 4))
生成9*4的numpy数组
[[ 0. 0. 0. 0.]
[ 0. 0. 0. 0.]
[ 0. 0. 0. 0.]
[ 0. 0. 0. 0.]
[ 0. 0. 0. 0.]
[