这几天学习了目标检测/R-CNN/SPP-Net/Fast R-CNN/Faster-R CNN这几个框架,
想做点笔记加深印象,如有理解错误,请指出,Thanks!
目标检测主要有两个任务:
- 定位图片中的物体
- 识别物体的类别
故目标检测是一个定位 + 分类的任务,比图像分类更有难度。
传统的目标检测大体流程可以表示如下:
随着深度学习的兴起,以及CNN所表现出的强大的视觉处理性能,目标检测也有传统方法想深度学习方向进化。
R-CNN
1.首先是原图,然后在原图上使用一定的方法产生一些感兴趣的区域,也就是可能含有目标的区域(region proposals),有2k个左右。
其中R-CNN 产生region proposals 的方法是ss 方法,步骤如下:
(1)按照一定的规则生成区域集R
(2)计算区域集R中每个相邻区域的相似度S={s1, s2, …}
(3)找出相似度最高的两个区域,将其合并并添加进R
(4)从S中移除所有与3中有关的子集
(5)计算新集与所有子集的相似度
(6)跳至3,直至S为空。
(个人觉得这部分不重要,虽然这个算法会伴随着后面几个模型,自己也没太看懂。。。)
2.将产生的候选区域resize到一个固定大小。至于原因,是为了后面能输入固定尺寸的feature map给全连接层,这也是后面可以改进的一个地方。
3.将resize后的图像输入到一个CNN网络(这个网络可以是现成的模型,比如VGG、AlexNet,然后微调即可,原文使用的是AlexNet),CNN网络会提取出固定维度的特征向量(图片经过AlexNet,缩放比例是固定的,而输入图片大小也是固定的,所以输出当然也是固定的了。。刚好满足全连接层固定大小输入的需求。。)
4.再将提取到的特征输入给预先训练好的一组SVM分类器(一共有k个,k即是类别总数,每个都是二分类器),识别出区域中的目标是什么,随后做box regression,修正物体的box位置。
其中要注意用于分类和回归是两套不同的特征,分类的特征来源于fc7层,回归的特征来源于cov5层,这里的fc7层和cov5层都是AlexNet中的层。
给出R-CNN具体的结构如下图:
图中看出,选取2000个region proposals并warp/crop后,需要对每个region proposal 进行特征提取,这就需要2000次CNN,这是很耗费时间的(后面有改进)。
R-CNN的微调
M - 在ImageNet上对CNN模型进行pre-train(比如AlexNet、VGG,现成的可以直接拿来用)
M’ - 在SS生成的所有区域对M进行fine-tune(目的是为了后面分类,使模型分类性能在该目标检测下有较好的泛化能力,毕竟AlexNet是现成训练好的,而这种在图片里面识别物体比较特殊,AlexNet对此不一定有很好的泛化能力,所以需要fine-tune)
fine-tune注意:
- softmax层改为(N+1) - way,其余不变,N+1是类别数目,包括一个背景类。原文中所谓的特定任务是PASCAL VOC,使用了PASCAL VOC 2010的数据集,其中只需要区分20个类别。
- 正样本-N类:跟Grounth-truth重合IOU>=0.5;负样本-1类:IOU < 0.5。
R-CNN的分类部分
训练流程:
在M’的fc7特征上训练线性SVM分类器。
- 1 loss:Hinge loss(SVM 特有)
- 2 每个类别对应一个分类器
- 3 正样本:所有的Ground-truth区域得到的CNN特征向量
- 4 负样本:跟Ground-truth重合IOU<0.3的SS区域得到的CNN特征向量(注意这里正负样本的定义要比CNN严格)
注意SVM的训练是单独的,需要先训练好CNN来提取特征,并作为SVM的输入。
CNN已经具备分类的能力,为什么还要用SVM:要重新构造数据集,单独来训练,同时还要用训练好的CNN来提取特征作为输入????
R-CNN的回归部分
在M’的fc7特征上训练Bounding box回归模型
1、每个类别(N类)训练一个回归模型。
-
将SS提供的Bounding box重重新映射P-> G
-
训练输入。
-
P的IOU > 0.6
-
Squared loss
2、测试阶段
- 参数w已经训练好。
R-CNN的测试阶段
- SS算法提取~2000区域/图片
- 将所有区域warp/crop到227 * 227大小
- 使用fine-tune过的AlexNet计算两套特征,一套来源于fc7,用于SVM分类,一套来源于cov5,用于box-regression
- fc7特征 -> SVM分类器 -> 类别分值
- 使用非极大值抑制(IOU>0.5)获取无冗余的区域子集
- cov5特征 -> Bounding box回归模型 -> Bbox偏差
- 使用Bbox偏差修正区域子集
R-CNN的缺点
- 速度很慢
- 卷积特征重复计算量太大-每张图片的~2000区域都会计算CNN特征
SPP-Net
对比R-CNN的改进
- 直接输入整张图,对整张图做卷积,在cov5输出上提取所有区域的特征
- 引入空间金字塔池化
1、为不同尺寸的区域,在con5输出上提取特征
2、将每个区域的特征映射到尺寸固定的全连接层上(解决了卷积层到全连接层之间尺寸变换的问题,这样就能使输入的图片可以任意尺寸大小了)
SPP-Net架构
其中SPP层替代了cov5后的池化层。
为什么会得固定大小的输出?
注意我们上面曾提到使用多个窗口(pooling窗口,上图中蓝色,青绿,银灰的窗口, 然后对feature maps 进行pooling,将分别得到的结果进行合并就会得到固定长度的输出),这也相当于引入了多尺度特征,使融合后的特征信息更全面。
注意需要对~2000区域的feature map做SPP,一张图片经过Spp后就得到2000 * 固定尺寸的特征矩阵。图片conv5的feature map中的某个区域做SPP如下,跟上图差不多。。
在cov5 feature map上怎么找到原始图像中~2000区域的在feature map上的对应区域呢
对卷积层发现:输入图片的某个位置的特征反应在feature map上也是在相同位置,基于此,对于某个RIO区域的特征提取只需要在特征图上的相应位置提取就可以了。
SPP-Net的训练流程
- M - 在ImageNet上对CNN模型进行pre-train
- F - 计算所有SS区域的SPP特征(来源于cov5)
- M’ - 使用F特征fine tune 新的fc6 -> fc7 -> fc8层
这里要注意跟R-CNN的区别:
(1)SPP特征 - Pool5特征
(2)只fine-tune全连接层(为什么呢?R-CNN fine-tune所有层?)
- F’ - 计算M’的fc7特征
- C - 使用F’特征训练SVM分类器
- R - 使用F特征训练Boundig box回归模型
SPP-Net缺点
继承R-CNN的问题:
- 依然需要存储大量特征
- 复杂的多阶段训练
- 速度慢
带来新问题:
- SPP层之前的所有卷积层参数不能fine-tune(为什么?)
Fast R-CNN网络
改进
- 实现end - to - end的单阶段训练(region proposals的产生还是用的selective search)
- 所有层的参数都可以fine-tune
- 网络同时输出类别判断和回归建议(同级输出),不在分开训练SVM和回归器(故会引入多任务损失函数)
- 引入ROI pooling layer(单尺度),代替SPP层(多尺度)
Fast R-CNN架构
感兴趣区域池化RoI pooling
- Fast R-CNN中对金字塔池化进行改进,使用了其特例(只使用了一层),变成了ROI pooling,它的输入维度不定h * w,输出维度固定H * W
- 将RoI区域的卷积特征拆分成H * W网格(VGG 是7 * 7)
- 将每个Bin内的所有特征进行Max pooling
多任务损失(Multi-task loss)
从网络结构可以看出,网路有两个同级输出:分类和回归,这样举不需要分开训练分类器和回归器,但是也涉及到了多任务训练,两个任务需要共享输入和底层参数,在根据各自任务进行不同的输出。
网络的损失函数包含分类器损失和回归L1 loss。
Fast R-CNN的训练
- 预训练,与R-CNN一样,使用大的数据集训练一个大的网络,或者实现现成的CNN模型,比如VGG
- 在预训练模型上做finetune。
(1)先改变网络结构:1)将最后一个池化层改为ROI Pooling;2)将输出层改为两个同级输出,一个用于分类,一个用于回归。(挖坑:新加入的节点参数如何设置??)
(2)构造数据集,使用Mini-batch sampling抽样方法。
Batch尺寸(128) = 每个batch的图片数量(2) * 每个图片的RoI数量(64)
这个batch设置应该可变。
全连接层加速计算
就Fast R-CNN而言,RoI池化层后的全连接层需要进行约2k次,因此在Fast R-CNN中可以采用SVD分解加速全连接层的计算。
设全连接层输入是X,输出数据为Y,全连接层权值矩阵为W,尺寸为u * v,那么全连接层的计算为Y = W * X。
其中
SVD分解如下:
Faster R-CNN
改进:
Faster R-CNN = Fast R-CNN + RPN
前面的Fast R-CNN的region proposals依然是SS算法产生的,跑在CPU上,消耗大量的时间。故Faster R-CNN使用神经网络的方式生成region proposals,使其都能能跑在GPU上。Faster R-CNN引入RPN网络产生region proposals。
Faster R-CNN的结构图如下:
红色框部分是RPN网络。
Region Proposal Network(RPN)网络
- 3 * 3,256-d卷积层 + Relu层 <- 输出图片的Conv5 feature map,为什么要这样做?conv5输出已经是256-d(256通道) 的特征图,为何要经过3 * 3得到还是256-d的特征图? ----为了扩大感受野
- 1 * 1,4k-d(4k个通道数)卷积层 -> 输出k组proposal的offsets(r,c,w,h),用于回归
- 1 * 1,2k-d卷积层 -> 输出k组(object score,non-object score)
其中M * N是原图输入的原始尺寸,见上上图,W * H是经过conv5层后得到的feature map尺寸。
红色的框就是sliding window(注意sliding window只是选择位置,除此之外没有其它作用,和后面的3 * 3的卷积区分),大小为n * n(实现时n=3),intermediate layer是3 * 3卷积层。卷积核数量是256个 3 * 3卷积核
Anchor box
Anchor box 类型 k = 9
包含:
- 3个尺度scale(128, 256, 512)
- 3个宽高比ratio(1:1,1:2,2:1)
- Anchor 的总数量是W * H * k
- W * H 是feature map的尺寸大小
- conv5 feature map每个点上有k个anchor
-
RPN想在这个feature map(视为一张有256个通道的图片)上滑动一个小网络来对其每个点在归一化图像上对应的9个anchor boxes进行打分(判断每个box是否为前景)和回归(每个box的位置修正意见)。对应上图就是2k和4k的输出(k=9),2代表了前景背景,4代表了修正意见的4个值。
我们通过下图帮助理解:
Faster R-CNN的训练流程
- Step1 - 训练RPN网络
卷积层初始化 <- ImageNet上的pretrained模型参数 - Step2 - 训练Fast R-CNN网络
卷积层初始化 <- ImageNet上的pretrained模型参数
Region proposals有Step1的RPN生成。 - Step3 - 调优RPN
卷积层初始化 <- Fast R-CNN的卷积层参数
固定卷积层,finetune剩余层 - Step4 - 调优Fast R-CNN
固定卷积层,finetune剩余层
Region proposals由Step3的RPN生成。
Step1和Step2的卷积层没有共享,Step3和Step4的卷积层共享,为什么??
参考:
https://www.zhihu.com/people/lhc-90-53/posts
https://zhuanlan.zhihu.com/qianxiaosi
https://zhuanlan.zhihu.com/p/30720870
https://zhuanlan.zhihu.com/p/30368989
https://blog.csdn.net/v1_vivian/article/details/73275259
https://blog.csdn.net/xjz18298268521/article/details/52681966
https://zhuanlan.zhihu.com/p/30316608