文章目录
论文信息
原文地址: Rich feature hierarchies for accurate object detection and semantic segmentation
系列论文:地址
代码实现:地址
作者:Ross Girshick, Jeff Donahue, Trevor Darrell, Jitendra Malik
成就:将CNN方法引入目标检测领域, 大大提高了目标检测效果,改变了目标检测领域的主要研究思路, 相对于2012年VOC的先前最佳结果,平均精度(mAP)提高了30%以上,达到53.3%的mAP。
RCNN 算法步骤
RCNN 算法分为 4 个步骤 :
-
候选区域生成(Region proposals): 采用Selective Search 方法,在一张图像生成约 2K个 候选区域 。
-
特征提取: 对每个候选区域,使用深度卷积网络提取特征 (CNN)。
-
类别判断: 特征送入 k 类 SVM 分类器,.将 k 个 SVM 分类器中得分最高的类作为分类结果,将所有得分都不高的region作为背景。
-
位置精修: 使用回归器精细修正候选框位置
![](https://i-blog.csdnimg.cn/blog_migrate/5dda2919b97b8be241e66e0f6776e863.png)
Selective Search
selective search 是一个语义分割的方法,通过像素级的标注,把颜色、边界、纹理等信息作为合并条件,使用多个尺度进行综合采样,划分出一系列的区域,这些区域要远远少于传统的滑动窗口的穷举法产生的候选区域。
![](https://i-blog.csdnimg.cn/blog_migrate/b0e4d65f2b0e4b85da011802c942275b.png)
区域合并方式
区域的合并方式是有层次的(hierarchical),类似于哈夫曼树的构造过程。
输入:彩色图片(三通道)
输出:物体位置的可能结果
L
L
L
-
使用 Efficient Graph-Based Image Segmentation 方法获取原始分割区域 R = r 1 , r 2 , … , r n R={r1,r2,…,rn} R=r1,r2,…,rn
-
初始化相似度集合 S = ∅ S=∅ S=∅
-
计算两两相邻区域之间的相似度,将其添加到相似度集合 S S S 中。
-
从相似度集合 S S S,中找出相似度最大的两个区域 r i ri ri 和 r j rj rj,将其合并成为一个区域 r t rt rt,从相似度集合中除去原先与 r i ri ri 和 r j rj rj 相邻区域之间计算的相似度,计算 r t rt rt 与其相邻区域(原先与 r i ri ri 或 r j rj rj 相邻的区域)的相似度,将其结果添加的到相似度集合 S S S 中。同时将新区域 r t rt rt 添加到区域集合 R R R 中。
-
获取相似度集合 S S S 中每个区域的 Bounding Boxes,这个结果就是物体位置的可能结果 L L L。
颜色空间多样化
作者采用了8中不同的颜色方式,主要是为了考虑场景以及光照条件等。这个策略主要应用于图像分割算法中原始区域的生成。主要使用的颜色空间有:(1)RGB,(2)灰度I,(3)Lab,(4)rgI(归一化的rg通道加上灰度),(5)HSV,(6)rgb(归一化的RGB),(7)C,(8)H(HSV的H通道)
相似度计算多样化
四种相似度的计算规则:
-
颜色(color)相似度
使用 L1-norm 归一化获取图像每个颜色通道的25 bins的直方图,这样每个区域都可以得到一个75维的向量。
-
纹理(texture)相似度
这里的纹理采用 SIFT-Like 特征。具体做法是对每个颜色通道的 8 个不同方向计算方差 σ = 1 σ=1 σ=1 的高斯微分(Gaussian Derivative),每个通道每个颜色获取 10 bins 的直方图(L1-norm归一化),这样就可以获取到一个240维的向量,区域之间纹理相似度计算方式和颜色相似度计算方式类似,合并之后新区域的纹理特征计算方式和颜色特征计算相同。
-
大小(size)相似度
这里的大小是指区域中包含像素点的个数。使用大小的相似度计算,主要是为了尽量让小的区域先合并。
-
吻合(fit)相似度
这里主要是为了衡量两个区域是否更加“吻合”,其指标是合并后的区域的Bounding Box(能够框住区域的最小矩形(没有旋转))越小,其吻合度越高。
上述四条规则只涉及区域的颜色直方图、梯度直方图、面积和位置。合并后的区域特征可以直接由子区域特征计算而来,速度较快。
Graph-Based Image Segmentation 分割算法
论文原文:地址
Graph-Based Segmentation 是基于图的贪心聚类算法,实现简单,速度比较快,精度也还行。目前直接用它做分割的应该比较少,很多算法用它作基层处理。
图的基本概念 :
-
图,是由顶点集 V ( v e r t i c e s ) V(vertices) V(vertices)和边集 E ( e d g e s ) E(edges) E(edges)组成,表示为 G = ( V , E ) G=(V, E) G=(V,E)。顶点 v ∈ V v∈V v∈V,即单个的像素点,连接一对顶点的边 ( v i , v j ) (vi, vj) (vi,vj) 具有权重 w ( v i , v j ) w(vi, vj) w(vi,vj),其意义为顶点之间的不相似度(dissimilarity),所用的是无向图。
-
树,是一种特殊的图,图中任意两个顶点,都有路径相连接,但是没有回路。
-
最小生成树(Minimum Spanning Tree),给定需要连接的顶点,选择边权之和最小的树。
论文中,初始化时每一个像素点都是一个顶点,然后逐渐合并得到一个区域,确切地说是得到连接这个区域中的像素点的一个MST。如下图,棕色圆圈为顶点,线段为边,合并棕色顶点所生成的MST,对应的就是一个分割区域。分割后的结果其实就是森林。
![](https://i-blog.csdnimg.cn/blog_migrate/59dc6f2d3a7791d16f54ca9128a651cf.png)
相似性:
- 对于孤立的两个像素点,用灰度的距离来衡量两点的相似性,论文是使用RGB的距离,即
static inline float diff(image<float> *r, image<float> *g, image<float> *b,
int x1, int y1, int x2, int y2) {
return sqrt(square(imRef(r, x1, y1)-imRef(r, x2, y2)) +
square(imRef(g, x1, y1)-imRef(g, x2, y2)) +
square(imRef(b, x1, y1)-imRef(b, x2, y2)));
}
- 对于灰度图像就只能使用亮度值了。此外,还可以先使用纹理特征滤波,如高斯滤波,这样做可以去掉一些噪声,再计算距离。
阈值:
![](https://i-blog.csdnimg.cn/blog_migrate/fcd3f4ffaf81f55898e627bca8219294.png)
-
显然,上面这张图应该聚成右图所示的3类,高频区 h, 斜坡区 s, 平坦区 p。
-
如果使用全局阈值,那么为了把 h 区要合并成一块,阈值要选很大,但是那样就会把 p 和 s 区域也包含进来,分割结果太粗。
-
如果以 p 为参考,只能使用特别小的阈值,h区就会合并成细碎的小块,分割结果太细。
显然,全局阈值并不合适,那么自然就得用自适应阈值:
![](https://i-blog.csdnimg.cn/blog_migrate/745a5d5a8f7780d109afb82339e62767.png)
-
类内差异:Mint,表示同一颗树下权重最大的边(最不相似的两个点)。
-
类间差异:Dif 表示链接两个树的最小权重边。
-
当 D i f ( c 1 , c 2 ) < = M i n ( M i n t ( c 1 ) , m i n t ( c 2 ) ) Dif(c1,c2) <= Min(Mint(c1),mint(c2)) Dif(c1,c2)<=Min(Mint(c1),mint(c2)) 时,两个区域应当合并。
-
对于初始图片,图片的每一个像素都是一个独立的 MST,初始阈值 ( C ) (C) (C)会随着树的变大渐趋向于0,使得自适应阈值起作用。
分割算法步骤:
![](https://i-blog.csdnimg.cn/blog_migrate/644d3a00ba76eab8048cb539bf11de72.png)
-
计算每一个像素点与其8邻域或4邻域的不相似度。
-
将边按照不相似度non-decreasing排列(从小到大)排序得到 e 1 , e 2 , . . . , e n e1, e2, ..., en e1,e2,...,en
-
选择 e i ei ei,进行合并判断。 若相似,则更新阈值以及类标号,若不相似,且 i < n i < n i<n,则按照排好的顺序,选择下一条边继续判断,否则结束。
候选框缩放
![](https://i-blog.csdnimg.cn/blog_migrate/19a91169147f3d34a8e7b8fe46fe101d.png)
Selective Search方法,可以提出2000个大小各不相同的矩形候选框,由于 CNN 所需要的输入图片大小是 227 ∗ 227 227*227 227∗227,因此作者对selective search 得到的是矩形框试验了两种不同的处理方法:
-
各向异性缩放
这种方法很简单,就是不管图片的长宽比例,管它是否扭曲,直接缩放就是了,全部缩放到CNN输入的大小227*227,如 ( D ) (D) (D)所示;
-
各向同性缩放,有两种办法
A、先扩充后裁剪: 直接在原始图片中,把bounding box的边界进行扩展延伸成正方形,然后再进行裁剪;如果已经延伸到了原始图片的外边界,那么就用bounding box中的颜色均值填充;如上图 ( B ) (B) (B)所示;
B、先裁剪后扩充:先把bounding box图片裁剪出来,然后用固定的背景颜色填充成正方形图片(背景颜色也是采用bounding box的像素颜色均值),如上图 ( C ) (C) (C)所示;
对于上面的异性、同性缩放,文献还有个 padding 处理,上面的示意图中第1、3行就是结合了padding=0,第2、4行结果图采用padding=16的结果。经过最后的试验,作者发现采用各向异性缩放、padding=16的精度最高。
CNN 特征提取
通过训练好的 AlexNet 模型,先将每个 region 固定到 227 ∗ 227 227*227 227∗227 的尺寸,然后对于每个 region 都提取一个 4096 维的特征。值得注意的是,在 resize到 227 ∗ 227 227*227 227∗227 的过程中,在 region 外面扩大了一个 16 个宽度的边框,region的范围也就相应扩大,考虑了更多的背景信息。
CNN 训练
-
首先使用 AlexNet 在 Imagenet 上训练的 CNN 作为 pre-train
-
然后将该网络的最后一个 fc 层的 1000 改为 N+1(N为类别的数目,1是加一个背景)来 fine-tuning 用于提取特征的CNN。
-
作者将大于 0.5 的 IOU 作为正样本,小于 0.5 的作为负样本,调整学习率为原来的 1/10,batch-size 大小为: 128,其中 32个为正样本,96个位负样本。
值得注意的是:
-
如果不针对特定任务进行fine-tuning,而是把CNN当做特征提取器,卷积层所学到的特征其实就是基础的共享特征提取层,就类似于SIFT算法一样。
-
而 f6 、f7 所学习到的特征是用于针对特定任务的特征。打个比方:对于人脸性别识别来说,一个CNN模型前面的卷积层所学习到的特征就类似于学习人脸共性特征,然后全连接层所学习的特征就是针对性别分类的特征了)
分类器训练
-
训练 N(N为类别数)个线性支持向量机(Linear Support Vector Machine,LSVM),分别对每一类做一个二分类,每个 svm 包含了4096个权值。
-
作者将大于 0.5 0.5 0.5 的 IOU 作为正样本,小于 0.3 0.3 0.3 的 IOU 作为负样本,至于为啥这里不是 0.5 0.5 0.5,因为当设置为 0.5 0.5 0.5的时候,mAp下降 5 % 5\% 5% ,设置为 0 0 0 的时候下降 4 % 4\% 4%,最后取中间 0.3 0.3 0.3。
作者发现在 VOC 2007上测试时,softmax 的 mAP 为 50.9%,没有svm的 54.2% 的效果好。作者认为这是由于 softmax 的负样本(也可以理解为背景样本)是随机选择的即在整个网络中是共享的,而 svm 的负样本是相互独立的,每个类别都分别有自己的负样本,svm 的负样本更加的“hard”,所以 svm 的分类的准确率更高。
边框回归 Bounding-Box regression
下图中,绿色的框表示真实值 Ground Truth,红色的框为 Selective Search 提取的候选区域/框 Region Proposal。那么即便红色的框被分类器识别为飞机,但是由于红色的框定位不准(IoU < 0.5), 这张图也相当于没有正确的检测出飞机。
![](https://i-blog.csdnimg.cn/blog_migrate/ba69597f198554ddb398b384639d0574.png)
对于窗口一般使用四维向量 ( x , y , w , h ) (x,y,w,h) (x,y,w,h) 来表示, 分别表示窗口的中心点坐标和宽高。红色的框 P 代表原始的 Proposal,绿色的框 G 代表目标的 Ground Truth。
![](https://i-blog.csdnimg.cn/blog_migrate/39f9f3be0cd96b699f82495820277590.png)
边框回归的目的是:输入原始的窗口 P 经过映射得到一个跟真实窗口 G 更接近的回归窗口 G ^ \hat G G^,即,给定 ( P x , P y , P w , P h ) (P_x, P_y, P_w, P_h) (Px,Py,Pw,Ph) 寻找一种映射 f f f, 使得 f ( P x , P y , P w , P h ) = ( G x ^ , G y ^ , G w ^ , G h ^ ) f(P_x, P_y, P_w, P_h) = (\hat{G_x}, \hat{G_y}, \hat{G_w}, \hat{G_h}) f(Px,Py,Pw,Ph)=(Gx^,Gy^,Gw^,Gh^) 并且 ( G x ^ , G y ^ , G w ^ , G h ^ ) ≈ ( G x , G y , G w , G h ) (\hat{G_x}, \hat{G_y}, \hat{G_w}, \hat{G_h}) \approx (G_x, G_y, G_w, G_h) (Gx^,Gy^,Gw^,Gh^)≈(Gx,Gy,Gw,Gh)
边框回归的实现:
- 先计算平移 ( Δ x , Δ y ) (\Delta x, \Delta y) (Δx,Δy):
Δ x = P w d x ( P ) \Delta x = P_w d_x(P) Δx=Pwdx(P)
Δ y = P h d y ( P ) \Delta y = P_h d_y(P) Δy=Phdy(P)
- 对应论文中的公式:
G ^ x = P w d x ( P ) + P x \hat G_x = P_w d_x(P) + P_x G^x=Pwdx(P)+Px
G ^ y = P h d y ( P ) + P y \hat G_y= P_h d_y(P) + P_y G^y=Phdy(P)+Py
- 然后再做尺度缩放 ( S w , S h ) (S_w, S_h) (Sw,Sh):
S w = e x p ( d w ( P ) ) S_w = exp(d_w(P)) Sw=exp(dw(P))
S h = e x p ( d h ( P ) ) S_h = exp(d_h(P)) Sh=exp(dh(P))
- 对应论文中的公式:
G ^ w = P w e x p ( d w ( P ) ) \hat G_w= P_w exp(d_w(P)) G^w=Pwexp(dw(P))
G ^ h = P h e x p ( d h ( P ) ) \hat G_h= P_h exp(d_h(P)) G^h=Phexp(dh(P))
边框回归的输入:
输入值是窗口 R e g i o n P r o p o s a l → P = ( P x , P y , P w , P h ) Region Proposal \to P = (P_x, P_y, P_w, P_h ) RegionProposal→P=(Px,Py,Pw,Ph) 对应的 CNN 特征,也就是 R-CNN 中的 Pool5 feature(特征向量)。 (注:训练阶段输入还包括 Ground Truth, 也就是下边提到的 t ∗ = ( t x , t y , t w , t h ) t_* = (t_x, t_y, t_w, t_h) t∗=(tx,ty,tw,th)
边框回归的输出:
输出值是平移变换和尺度缩放系数: Δ x , Δ y , S w , S h \Delta x, \Delta y, S_w, S_h Δx,Δy,Sw,Sh,最终预测的 G r o u n d T r u t h = ( t x , t y , t w , t h ) Ground Truth = (t_x, t_y, t_w, t_h) GroundTruth=(tx,ty,tw,th) 的计算如下:
t x = ( G x − P x ) / P w t_x = (G_x - P_x) / P_w tx=(Gx−Px)/Pw
t y = ( G y − P y ) / P h t_y = (G_y - P_y) / P_h ty=(Gy−Py)/Ph
t w = log ( G w / P w ) t_w = \log (G_w / P_w) tw=log(Gw/Pw)
t h = log ( G h / P h ) t_h = \log(G_h / P_h) th=log(Gh/Ph)
-
由于不同尺度的相同对象的特征相同,将x,y 坐标除以宽高,可以使相同对象在不同尺度下函数映射值相等。
-
由于宽高放缩的尺度必须大于0,使用 EXP 函数可以保证学习的 t w , t h tw,th tw,th 大于0,反过来推导就是Log函数的来源了。
边框回归的目标函数:
边框回归的目标函数可以表示为:
d ∗ ( P ) = w ∗ T Φ 5 ( P ) d_*(P) = w_*^T\Phi_5(P) d∗(P)=w∗TΦ5(P)
-
其中 Φ 5 ( P ) \Phi_5(P) Φ5(P) 是输入 Proposal 的特征向量
-
w ∗ w_∗ w∗ 是要学习的参数( ∗ * ∗ 表示 x , y , w , h x,y,w,h x,y,w,h, 也就是每一个变换对应一个目标函数)
-
d ∗ ( P ) d_*(P) d∗(P)是得到的预测值。 要让预测值跟真实值 t ∗ = ( t x , t y , t w , t h ) t_* = (t_x, t_y, t_w, t_h) t∗=(tx,ty,tw,th) 差距最小, 得到损失函数为:
L o s s = ∑ i N ( t ∗ i − w ^ ∗ T ϕ 5 ( P i ) ) 2 Loss = \sum_i^N(t_*^i - \hat w_*^T\phi_5(P^i))^2 Loss=i∑N(t∗i−w^∗Tϕ5(Pi))2
- 函数优化目标为:
W ∗ = a r g m i n w ∗ ∑ i N ( t ∗ i − w ^ ∗ T ϕ 5 ( P i ) ) 2 + λ ∣ ∣ w ^ ∗ ∣ ∣ 2 W_* = argmin_{w_*} \sum_i^N(t_*^i - \hat w_*^T\phi_5(P^i))^2 + \lambda || \hat w_*||^2 W∗=argminw∗i∑N(t∗i−w^∗Tϕ5(Pi))2+λ∣∣w^∗∣∣2