细讲:RCNN、Fast R-CNN和Faster R-CNN
作者:互联网
细讲:RCNN、Fast R-CNN和Faster R-CNN
R-CNN
R-CNN模型结构
R-CNN是一种two-stage的目标检测模型,one-stage 中Region Proposal采用Selective search,two-stage 的分类采用CNN(AlexNet)提取特征+FC,然后使用SVM分类。
one-stage :Region Proposal
one-stage直接使用Selective search生成大约2K的窗口。测试的时候会使用NMS去掉IOU比较高的的region。
Selective search
步骤:
- 通过 Efficient Graph-Based Image Segmentation 算法生成最初的小 初始化原始区域
- 我们使用贪心策略,计算每两个相邻的区域的相似度。
- 每次合并最相似的两块,直到最终只剩下一块完整的图片。
- 这其中每次产生的图像块包括合并的图像块我们都保存下来,这样就得到图像的分层表示。
- 给予最先合并的图片块较大的权重,比如最后一块完整图像权重为1,倒数第二次合并的区域权重为2以此类推。R-CNN中采用Selective Search Fast,分别用了HSV和Lab两种颜色空间,然后使用了C+T+S+F和T+S+F两种相似度计算方法,由于是2中策略,每一种策略里的region都会有个分,2种策略就会存在两个region相同分。因此,每个region的分数会乘以一个随机数(region被选择看运气),然后对于相同的区域多次出现的也叠加下权重。这样我就得到了所有区域的目标分数,也就可以根据自己的需要选择需要多少个区域了。(实际在选择的时候从了按分数高到低,还会考虑边长、面积的阈值)
相似度的计算方法:
将原始色彩空间转换到多达八种的色彩空间。然后通过多样性的距离计算方式,综合颜色、纹理等所有的特征。
1.颜色距离:
s
c
o
l
o
u
r
(
r
i
,
r
j
)
=
∑
k
=
1
n
m
i
n
(
c
i
k
,
c
j
k
)
s_{colour}(r_i,r_j)=\sum^n_{k=1}min(c_i^k,c_j^k)
scolour(ri,rj)=∑k=1nmin(cik,cjk)
就是各个通道计算颜色直方图,然后取各个对应bins的直方图最小值,合并后直方图大小加权区域大小然后除以总区域大小就可以得到合并后的图的颜色直方图
2.纹理距离:
s
t
e
x
t
u
r
e
(
r
i
,
r
j
)
=
∑
k
=
1
n
m
i
n
(
t
i
k
,
t
j
k
)
s_{texture}(r_i,r_j)=\sum^n_{k=1}min(t_i^k,t_j^k)
stexture(ri,rj)=∑k=1nmin(tik,tjk)
计算每个区域的快速sift特征,其中方向个数为8,3个通道中每个通道bins为10,对于每幅图像得到240维的纹理直方图,然后通过上式计算距离
3.优先合并小的区域:
s
s
i
z
e
(
r
i
,
r
j
)
=
1
−
s
i
z
e
(
r
i
)
−
s
i
z
e
(
r
j
)
s
i
z
e
(
i
m
)
s_{size}(r_i,r_j)=1-\frac{size(r_i)-size(r_j)}{size(im)}
ssize(ri,rj)=1−size(im)size(ri)−size(rj)
给小的区域更多的权重,这样保证在图像每个位置都是多尺度的在合并。避免通过颜色和纹理特征合并会很容易使得合并后的区域不断吞并周围的区域,导致多尺度只应用在了那个局部,而不是全局的多尺度。
4.区域的合适度度距离:
f
i
l
l
(
r
i
,
r
j
)
=
1
−
s
i
z
e
(
B
B
i
j
)
−
s
i
z
e
(
r
i
)
−
s
i
z
e
(
r
j
)
s
i
z
e
(
i
m
)
fill(r_i,r_j)=1-\frac{size(BB_{ij})-size(r_i)-size(r_j)}{size(im)}
fill(ri,rj)=1−size(im)size(BBij)−size(ri)−size(rj)
不仅要考虑每个区域特征的吻合程度,区域的吻合度也是重要的,吻合度的意思是合并后的区域要尽量规范,不能合并后出现断崖的区域,这样明显不符合常识,体现出来就是区域的外接矩形的重合面积要大。
5.综合各种距离:
s
(
r
i
,
r
j
)
=
a
1
s
c
o
l
o
u
r
(
r
i
,
r
j
)
+
a
2
s
t
e
x
t
u
r
e
(
r
i
,
r
j
)
+
a
3
s
s
i
z
e
(
r
i
,
r
j
)
+
a
4
f
i
l
l
(
r
i
,
r
j
)
s(r_i,r_j)=a_1s_{colour}(r_i,r_j)+a_2s_{texture}(r_i,r_j)+a_3s_{size}(r_i,r_j)+a_4fill(r_i,r_j)
s(ri,rj)=a1scolour(ri,rj)+a2stexture(ri,rj)+a3ssize(ri,rj)+a4fill(ri,rj),
a
i
=
0
,
1
a_i={0,1}
ai=0,1,
a
i
=
0
a_i=0
ai=0代表不使用这方法,
a
i
=
1
a_i=1
ai=1代表使用。
two-stage :Classification and bounding box regression
概念解释:
正样本:ground truth.
负样本:如果某个region proposal和当前图像上的所有ground truth中重叠面积最大的那个的IOU<0.2,则该region proposal作为作为负样本。
Classification
训练的时候除了使用正样本和它的ground truth外还会使用负样本,比例为3:7。
将Region Proposal生成的region提取出来再reshpe成227x227(reshape方法有两种,一种直接reshape,一种如yolov3一样采用填充短边),然后输入AlexNet提取特征图。网络输出的类别数为
C
+
1
C+1
C+1,
C
C
C类+背景类。
fine-tunning完网络后会再加入SVM(SVM适合小样本,所以正样本只占0.3)。将网络分类层的前一层FC(维度为4096),作为SVM的输入特征,然后训练SVM。
最后测试分类的时候是用AlexNet输出特征,然后将AlexNet输出的特征送入SVM里进行分类。
bounding box regression
bounding box regression是为了精修Region Proposal输出的region,避免region出现偏差或者空白太多。
用AlexNet最后一层pooling的特征6x6x256维和bounding box的ground truth来训练回归,每种类型的回归器单独训练。输入是AlexNet最后一层pooling的特征,以及每个样本对的坐标和长宽值,然后接1层FC,维度为4。FC的4个值代表的意思看Faster R-CNN的bbox regressor。
测试的时候根据classification给出的类别使用对应的回归器预测bounding box。
Loss
classification loss:交叉熵(在没有送入SVM前需要fine-tunning分类层前的两层FC,所以需要classification loss)。
bounding box regression:
l
o
s
s
=
1
N
∑
i
=
1
N
(
t
∗
i
−
w
∗
T
^
ϕ
5
(
P
i
)
)
2
+
λ
∣
∣
w
∗
^
∣
∣
2
loss=\frac{1}{N}\sum^N_{i=1}(t_*^i-\hat{w_*^T}\phi_5(P^i))^2+\lambda||\hat{w_*}||^2
loss=N1∑i=1N(t∗i−w∗T^ϕ5(Pi))2+λ∣∣w∗^∣∣2
ϕ
5
(
P
i
)
\phi_5(P^i)
ϕ5(Pi)代表AlexNet的pooling5的输出,
w
∗
^
\hat{w_*}
w∗^为bounding box regression要学习的参数,
t
∗
i
t_*^i
t∗i为ground truth经过线性变换后的值。
Fast R-CNN
Fast R-CNN模型结构
Fast R-CNN的region proposal还是采用Selective search生成2K个,主要的改进地方在于不再是每个region proposal都输入CNN里,而是将原图输入CNN里,然后将region proposal映射的区域crop出来,接着加2层FC,然后分出两条支路分别进行类别预测(R-CNN使用SVM)和box regression(R-CNN会为每个类别训练一个box regression,而Fast R-CNN只有一个box regression)。
RoI feature
backbone采用VGG16,选择conv5的输出作为backbone的输出feature map,然后将region proposal在feature map里的映射区域提取出来,再采用使用双线性插值+下采样到7x7大小。之后,接两个FC(维度可变),然后分开送入分类和box regression支路。
SVD
奇异值分解(SVD)应用于FC里,加速FC的计算。因为每个region proposal对应的feature map都有进行FC里,导致FC的计算需要耗费大量的时间。为此,作者提出了SVD来加速FC计算。
SVD的原理:
- 假设全连接层输入数据为 x x x,输出数据为 y y y,全连接层参数为 W W W,尺寸为 u u ux v v v,那么该层全连接计算为: y = W x y=Wx y=Wx(计算复杂度为 u × v u×v u×v)
- 若将 W W W进行SVD分解,并用前 t t t个特征值近似代替,即: W = U ∑ V T ≈ U ( u , 1 : t ) ⋅ ∑ ( 1 : t , 1 : t ) ⋅ V T ( v , 1 : t ) W=U\sum V^T≈U(u,1:t)⋅\sum (1:t,1:t)⋅V^T(v,1:t) W=U∑VT≈U(u,1:t)⋅∑(1:t,1:t)⋅VT(v,1:t)
- 那么原来的前向传播分解成两步: y = W x = U ⋅ ( ∑ ⋅ V T ) ⋅ x = U ⋅ z y=Wx=U⋅(\sum⋅V^T)⋅x=U⋅z y=Wx=U⋅(∑⋅VT)⋅x=U⋅z
计算复杂度为
u
×
t
+
v
×
t
u×t+v×t
u×t+v×t,若
t
<
m
i
n
(
u
,
v
)
t<min(u,v)
t<min(u,v)(
u
,
v
u, v
u,v分别是全连接层的维度和feature map的维度),则这种分解会大大减少计算量;
在实现时,相当于把一个全连接层拆分为两个全连接层,第一个全连接层不含偏置,第二个全连接层含偏置。
Classification
Classification的维度为C+1,C类+背景。
box regression
box regression的维度为(C+1)x4,对每一类都进行box预测,精修region proposal,测试的时候会使用NMS。(训练的时候输入都是不重叠的region)
Loss
L
(
p
,
u
,
t
u
,
v
)
=
L
c
l
s
(
p
,
u
)
+
λ
[
u
≥
1
]
L
l
o
c
(
t
u
,
v
)
L(p,u,t^u,v)=L_{cls}(p,u)+\lambda[u\geq1]L_{loc}(t^u,v)
L(p,u,tu,v)=Lcls(p,u)+λ[u≥1]Lloc(tu,v)
同Faster R-CNN的two-stage loss。
Fast R-CNN解决了什么
- 不用再为每个类别单独训练一个SVM。
- 不用再为每个类别单独训练一个regressors。
- 不用再每个region proposal都重复进行Conv操作。
Faster R-CNN
Faster R-CNN模型结构
Faster R-CNN是一种双阶段(two-stage)的网络,第一阶段为目标检测,第二阶段为目标分类。
Backbone
采用去除其中的全连接层,只留下卷基层的VGG16或Resnet101提取图像特征,输出下采样后的特征图。
One-Stage: RPN
RPN:候选检测框生成网络(Region Proposal Networks)
one-stage主要进行候选检测框的生产,这部分先进行slide window(3x3 Conv),然后分成两条路,上面的进行每个anchor(共9个)是前景或背景的分类,下面的那条进行bounding box的预测,如下图。
Slide Window
输入的图像为(w,h),无论采用哪个backbone,feature map的(w,h)会被缩放到(w/16,h/16),然后在feature map上进行slide window。采用3x3的卷积进行slide window操作的原因如下:
- 想用feature map来判断它的感受野是否是前景,但是对象并不总是正方形的(因此我们需要将128,256,512;分别与1:1,1:2,2:1做3x3的多尺度anchor,生成不同比例的前景区域),于是我们需要对感受野做一个替换。而feature map里的每一个像素要提取不同尺寸下的anchor,那么它对应的感受野要 ≥ \geq ≥anchor的最大尺寸。Faster R-CNN使用的不同尺度的9个anchor如下,其中最大的尺寸为512,ZFNet对应的感受野为171x171,而171x3=513>512(VGG16感受野为228,同理也是3),所以选用3x3的卷积。(也有说对一个3*3的滑动窗口,其中心在原图的位置生成9个anchor,但个人觉得是感受野的原因)
anchor尺寸:128x128 128x64 64x128 256x256 256x128 128x256 512x512 512x256 256x512
前景预测
采用1x1x18的卷积替换FC层对每个anchor进行前景预测,由于positive和negative为2个选项,anchor为9个所以卷积维度为18。
此时feature map shape为(n,18,w/16,h/16),采用reshape变成(n,2,w/16*9,h/16),然后等softmax候再reshape回来。进行这两次的reshape是为了腾空一个维度进行softmax,softmax的公式如下。
如果不腾空的话
j
j
j的范围就成了从
0
−
17
0-17
0−17,但positive和negative只有2类,腾空后
j
j
j的取值范围就成了
0
−
1
0-1
0−1。
bounding box predicition
RPN里的bounding box predicition主要是进行前景的anchor偏移量预测 ( t x , t y , t w , t h ) (t_x, t_y, t_w, t_h) (tx,ty,tw,th)。其中1x1x18的卷积替换FC层每个bounding box有4个值,9个anchor就共有36个值。
Proposal
Proposal进行的工作是挑选合适出ROI(Region of Interests)。先过滤掉
n
e
g
a
t
i
v
e
>
p
o
s
t
i
v
e
negative>postive
negative>postive的anchor+bounding box,然后将每个所有bounding box都按score(positive的值)大小进行排列,然后使用NMS选择bounding box,最后取score前300(有的说2000)的bounding box输出(不足300就有多少输出多少,一般都不止300)。
NMS中计算IOU的时候需要bounding box regression,公式如下:
t
x
=
x
−
x
a
w
a
,
t
y
=
y
−
y
a
h
a
,
t
h
=
l
o
g
(
w
w
a
)
,
t
h
=
l
o
g
(
h
h
a
)
t_x=\frac{x-x_a}{w_a}, t_y=\frac{y-y_a}{h_a}, t_h=log(\frac{w}{w_a}), t_h=log(\frac{h}{h_a})
tx=wax−xa,ty=hay−ya,th=log(waw),th=log(hah)=>
x
=
t
x
w
a
+
x
a
,
y
=
t
y
w
a
+
y
a
,
w
=
e
t
h
w
a
,
h
=
e
t
h
h
a
x=t_xw_a+x_a, y=t_yw_a+y_a, w=e^{t_h}w_a, h=e^{t_h}h_a
x=txwa+xa,y=tywa+ya,w=ethwa,h=ethha
(
x
,
y
x,y
x,y为ground truth[GT]的中心点,
w
,
h
w,h
w,h为GT的宽和长,
t
x
t_x
tx、
t
y
t_y
ty、
t
w
t_w
tw、
t
h
t_h
th是bouding box的预测的平移量和缩放因子[scale],
x
a
x_a
xa、
y
a
y_a
ya是每个grid的中心、
w
a
w_a
wa、
h
a
h_a
ha是不同尺度下anchor的长宽,除以
w
a
o
r
h
a
w_a or h_a
waorha是为了将偏移量缩放到0-1间)
Two-Stage: ROI Pooling and Classfier
如上图,Two-Stage主要由ROIPooling、bbox_pred和cls_prob组成。
ROIPooling
ROIPooling的工作是从feature map中扣取Proposal输出的每个框,扣取方法如下:
- 首先从Proposal输出了多个框,并可以计算出了对于原图的位置(有了x,y,w,h,可以计算出框在原图的左上角和右下角)
- 将原图的位置映射到feature上[左上角映射后的位置(x-w/2,y-h/2)/16,右下角映射后的位置]的区域抠出来(crop),然后使用双线性插值到14x14,然后使用stride=2的最大值池化方法将crop后的区域变成7x7大小的feature map(也可以用可适应最大值池化转换shape),原理如下图(图中只是个原理,数值和实际有点出入)。(个人觉得这里有个问题,如果crop后的图存在边小于7的话的出来的7x7的feature map,可能这里就是Faster R-CNN对比较小的物体识别效果不好的原因)
统一的固定尺寸(7x7)可以方便做目标的分类和预测框的修正处理。(为了一起做,这样更快,一个个来太慢了)
在ROIPooling之后将所有object flatten,然后接两个FC+ReLU。原来(n,7,7,c)变成(n,7x7xc),c是backbone输出的feature map的维度,n是Proposal输出的anchor的数量,在训练的时候由于输入的batchsize张图像,所以实际维度为(batchsize,n,7,7,c)=>(batchsize*n,7x7xc),考虑到要是某张图存在n<2000,所以需要进行特殊处理,例如补0到2000,这样方便计算,等后面计算loss或sofrmax时再处理回来就行了。测试的时候就比较好处理。
bbox regressor
(分类就是对每个框映射的区域进行分类,就不细讲了)
two-stage进行bbox regressor是为了精修的bounding box position,再次对proposal进行回归得到更精确的位置。
bbox regressor的FC长度为4C,C为类别数,即每个类都有一个boxes信息。
Loss
faster-rcnn loss主要分为两个部分RPN的loss和fast-rcnn部分的loss,然后训练模型的时候是先训练RPN,训练完后再训练fast-rcnn(连阶段分开训练)。
前景与背景的区分:前景的阈值为0.7,即anchor box与ground truth的IOU超过0.7就为前景,背景的阈值为0.3,即低于0.3为背景,0.3-0.7之前的为不关心部分,在RPN loss中不关心部分不参与loss计算。
one-stage loss: RPN Loss
训练RPN 时需要用到背景,此时RPN输出的是前景中score前300的bounding box和所有的背景对于的bou box。可能有布置300个score超过0.7,但多余的皆认为不关心。
L
(
{
p
i
}
,
{
t
i
}
)
=
1
N
c
l
s
∑
i
L
c
l
s
(
p
i
,
p
i
∗
)
+
λ
1
N
r
e
g
∑
p
i
∗
L
r
e
g
(
t
i
,
t
i
∗
)
L(\lbrace p_i\rbrace,\lbrace t_i\rbrace)=\frac{1}{N_{cls}}\sum_iL_{cls}(p_i,p_i^*)+\lambda\frac{1}{N_{reg}}\sum p_i^*L_{reg}(t_i,t_i^*)
L({pi},{ti})=Ncls1i∑Lcls(pi,pi∗)+λNreg1∑pi∗Lreg(ti,ti∗)
L
c
l
s
(
p
i
,
p
i
∗
)
L_{cls}(p_i,p_i^*)
Lcls(pi,pi∗)为二进制交叉熵损失,每个anchor有9个bounding box,每个bounding box都有各自的前景和背景的置信度,每个anchor的9个bounding box就组成了
p
i
∗
p_i^*
pi∗。所以每个
p
i
∗
p_i^*
pi∗代表了每个anchor的9个bounding box,又普通的多分类交叉熵只会计算ground truth那一类的loss,但这里ground truth并不是只有一类,而是多类,所以只能使用多标签分类的二进制交叉熵损失函数作为loss(所有的前景和背景都会参与)。
L
r
e
g
(
t
u
,
v
)
=
∑
i
ϵ
{
x
,
y
,
w
,
h
}
s
m
o
o
t
h
L
1
(
t
i
u
−
v
i
∗
)
L_{reg}(t^u,v)=\sum_{i\epsilon\lbrace x,y,w,h\rbrace}smooth_{L_1}(t^u_i-v_i^*)
Lreg(tu,v)=iϵ{x,y,w,h}∑smoothL1(tiu−vi∗)这里的
i
i
i和上面的
i
i
i是不同的,
u
u
u是指positive的bounding box。
s
m
o
o
t
h
L
1
(
x
)
=
{
0.5
x
2
,
if
∣
x
∣
<
1
∣
x
∣
−
0.5
,
otherwise
smooth_{L_1}(x) = \begin{cases} 0.5x^2, & \text{if $|x|<1$} \\ |x|-0.5, & \text{otherwise} \\ \end{cases}
smoothL1(x)={0.5x2,∣x∣−0.5,if ∣x∣<1otherwise
bounding box loss(后半部分的loss)使用smooth L1 loss,文章中的说是因为这样对异常点更加鲁棒,x大于1之后,梯度都是常量了。这边要注意的就是,他并不是对(x,y,w,h)原值进行回归,(x,y)使用对应的b-box进行了normalize,(w,h)也是用b-box对应的参数相除之后求对数。我的理解是做归一化后,达到同一尺度,可以加快训练或者提升训练效果。归一化的方法可以看Proposal里的bounding box regression。
two-stage loss
此时RPN输出的bounding box和正常的一样,只有前景里的前300个,不需要背景的bouding box,底下loss之所以会有背景是为了精修。
L
(
p
,
u
,
t
u
,
v
)
=
L
c
l
s
(
p
,
u
)
+
λ
[
u
≥
1
]
L
l
o
c
(
t
u
,
v
)
L(p,u,t^u,v)=L_{cls}(p,u)+\lambda[u\geq1]L_{loc}(t^u,v)
L(p,u,tu,v)=Lcls(p,u)+λ[u≥1]Lloc(tu,v)
L
c
l
s
(
p
,
u
)
L_{cls}(p,u)
Lcls(p,u)为交叉熵,此时
p
p
p指的是某一点anchor下的某一bounding box被预测为class
u
u
u的概率,
u
u
u为真实标签,
u
=
0
u=0
u=0为背景,
u
!
=
0
u!=0
u!=0代表为class
u
u
u。
后半部分的loss只有不是背景的bounding box参与,所以有
u
≥
1
u\geq1
u≥1。
L
l
o
c
(
t
u
,
v
)
L_{loc}(t^u,v)
Lloc(tu,v)和RPN Loss里的
L
r
e
g
(
t
u
,
v
)
L_{reg}(t^u,v)
Lreg(tu,v)一样。
在这个loss里面之所以会有背景是因为RPN给出的前景bounding box不一定准确。
Faster RCNN相比于Fast RCNN的优点
Faster RCNN对Fast RCNN的改进点在于获得region proposals的速度要快很多。
Faster R-CNN解决的问题
使用新的region proposal解决了Selective search太慢的问题,并且生成的region少,也加快了。
NMS、IOU可看:yolov3
标签:box,loss,细讲,region,bounding,CNN,RCNN,anchor 来源: https://blog.csdn.net/weixin_39994739/article/details/123111095