Fast RCNN

论文原文地址为: Fast R-CNN

1. RoI Pooling详解

RoI Pooling其实是SPP pooling的一种特殊情况。SPP pooling可以采用多个金字塔层,RoI只采用一种。具体做法为: 对于映射到feature map上的RoI(Region Proposal通过变换得来),假设该RoI大小为 h×w h × w ,RoI Pooling的输出为 H×W H × W ( H,W H , W 为超参数)。将 h×w h × w RoI R o I 分解成 H×W H × W 的子网格,每个格子大小近似为 hH×wW h H × w W 。然后再对 H×W H × W 个格子,每个格子取 maxpooling m a x p o o l i n g 。这样最后对于每个RoI,不论其大小如何,都能得到一个大小为 H×W H × W 的feature map。

如下:
1. 输入feture map
这里写图片描述
2. region proposal投影(左上角,右下角坐标):(0,3),(7,8)。
这里写图片描述
3. 将其划分为(2*2)个sections(因为输出大小为2*2),我们可以得到:
这里写图片描述
4. 对每个section做max pooling,可以得到:
这里写图片描述

2. Fast RCNN的的主要贡献

RCNN的缺点非常明显。SPP在此基础上进行了一些改进,但SPP也存在很大问题。SPP仍然是分阶段训练而不是一个端到端的过程,分为:提取特征,使用log损失对网络进行微调,训练SVM分类器,最后拟合检测框回归。特征也写入磁盘。并且SPP提出的fine tuning方法不能跟新SPP之前的卷积层。因为SPP并不是一个端到端的过程。这种固定的卷积层限制也限制了深层网络的精度。RCNN主要贡献有:

  • 比RCNN和SPPNet有更高的目标检测精度(mAP)
  • 训练采用的是多任务损失(multi-task loss),并且是单阶段,端到端的(end-to-end)
  • 训练可以更新所有网络层参数
  • 不需要磁盘空间缓存特征

3. Fast RCNN的网络结构

这里写图片描述
Fast RCNN的输入有两个: 一整张图像和一些列的object proposals。网络首先对整张图像进行conv和pooling的处理,得到一个feature map。然后对于每个Region proposal, 使用RoI Pooling层提取一个固定长度的特征向量(feature vector)。特征向量送入一系列全连接层,其最终分支产生两个同级输出层:一个用来产生softmax概率(K个object再加1个background)。另外一个用来产生4个实数值,每个实数值对应1个object class的bounding box。每组4个值表示K个类别的一个类别的检测框位置的修正后的值。

4. 预训练

将ImageNet上面训练好的网络进行调整。
1. 将最后的一个Max Pooling层由RoI Pooling层代替。
2. 网络的最后一个全连接层和Softmax被替换为前面描述的两个同级层(一个全连接层和K+1的softmax分类层以及bounding box回归层)。
3. 网络的输入该为接受两个输入:list of images and list of RoIs in those images。

4. 训练过程

用反向传播更新所有网络层的权重是Fast RCNN的重要能力。SPPNet无法更新低于金字塔池化层的权重的原因是当每个RoI来自不同的图像时(SPPNet的做法),每个RoI可能会有一个非常大的感受野,通常是贯穿整个图像的。由于前向传播要处理整张图像,训练的输入太大。

文中提出了一个分层次抽样的方法。分为两步:

  • 抽样出 N N 张图片
  • 每张图片抽样出RN个RoI

来自同一张图片的RoI在前向传播和反向传播中是共享计算和内存的。减小N就减小了小批量的计算。例如 N=2,R=128 N = 2 , R = 128 比从128张图片中,每张图片取1个RoI要快64倍(RCNN和SPPNet的做法)。

这个策略的一个令人担心的问题是它可能导致训练收敛变慢,因为来自相同图像的RoI是相关的。但实验证明这个问题不存在。

5. 多任务损失

除了分层采样,Fast R-CNN使用了一个精细的训练过程,在微调阶段联合优化Softmax分类器和检测框回归,而不是分别在三个独立的阶段训练softmax分类器,SVM和回归器。

Fast RCNN的输出有2部分。一个是分类损失,一个是bounding box回归损失:

L(p,u,tu,v)=Lcls(p,u)+λ[u1]Lloc(tu,v) L ( p , u , t u , v ) = L c l s ( p , u ) + λ [ u ≥ 1 ] L l o c ( t u , v )

其中 Lcls(p,u L c l s ( p , u 是对数分类损失。而第二项是bounding box回归损失。前面乘以一个indicator function: [u1] [ u ≥ 1 ] 表示当 u=0 u = 0 时是背景,此时是没有bounding box的。其中: tu=(tux,tuy,tuw,tuh) t u = ( t x u , t y u , t w u , t h u ) v=(vux,vuy,vuw,vuh v = ( v x u , v y u , v w u , v h u ) 是ground truth。bounding box回归使用的损失函数为:
Lloc(tu,v)=i{x,y,w,y}smoothL1(tuivi) L l o c ( t u , v ) = ∑ i ∈ { x , y , w , y } s m o o t h L 1 ( t i u − v i )

其中:
smoothL1(x)={0.5x2if|x|<1|x|0.5otherwise(2) (2) s m o o t h L 1 ( x ) = { 0.5 x 2 i f | x | < 1 | x | − 0.5 o t h e r w i s e

使用 smoothL1 s m o o t h L 1 损失的原因是,当预测值与目标值相差太大的时候,并且这种差别其实是没有界限的。这样在计算损失的时候,如果采用 L2 L 2 损失,则: L2=|f(x)Y|2 L 2 = | f ( x ) − Y | 2 。导数为: 2(f(x)Y)f(x) 2 ( f ( x ) − Y ) f ′ ( x ) 。因为其中包含了 f(x)Y f ( x ) − Y 这一项,可能会产生梯度爆炸现象。而采用 smoothL1 s m o o t h L 1 损失之后,当预测值与目标值差距太大时,导数为 ±f(x) ± f ′ ( x ) 。这样,原来 L2 L 2 损失里面的 f(x)Y f ( x ) − Y 被替换成 ±1 ± 1 。能够避免梯度爆炸。

另一方面,预测值与目标值差距大一般是因为噪声数据造成的。因此该方法也能增强鲁棒性,对抗噪声数据。

最后为了2个loss之间的平衡,将回归的bounding的数值都进行归一化,变成0均值和单位方差。实验中 λ λ 1 1 <script type="math/tex" id="MathJax-Element-66">1</script>。

6. 使用截断SVD来加快检测

文中对全连接层的矩阵乘法应用了SVD矩阵分解的方法来加快计算过程。

7. 需要fine tuning的卷积层

首先,并不是所有的卷积层都需要微调。在较小的网络(S和M)中,conv1(第一个卷积层)是通用的和任务独立的(一个众所周知的事实1)。允许conv1学习或不学习,对mAP没有很有意义的影响。对于VGG16,我们发现只需要更新conv3_1及以上(13个卷积层中的9个)的层。这种观察是实用的:

  • (1)从conv2_1更新使训练变慢1.3倍(12.5小时对比9.5小时)

  • (2)从conv1_1更新GPU内存不够用。当从conv2_1学习时mAP仅为增加0.3个点。

因此所有Fast R-CNN在本文中结果都使用VGG16微调层conv3_1及以上的层,所有实验用模型S和M微调层conv2及以上的层。

8. 检测框数量对精度的影响

随着Region Proposal数量的增加,发现mAP上升,然后随着候选区域计数增加而略微下降。实验表明,用更多的候选区域没有帮助,甚至稍微有点伤害准确性。

<think>好的,我现在需要回答用户关于Fast R-CNN的问题。首先,用户已经提到了R-CNN系列的其他算法,比如R-CNN、SPPNet、Faster R-CNN和Mask R-CNN,并引用了相关的资料[^1][^2]。用户可能已经对这些算法有了一定的了解,现在想重点了解Fast R-CNN的原理、实现和应用场景。 首先,我应该回顾Fast R-CNN的基本原理。根据之前的R-CNN发展,R-CNN的一个主要问题是速度慢,因为它对每个候选区域单独进行卷积运算,导致量重复计算。SPPNet通过空间金字塔池化(SPP)层解决了这个问题,允许网络对任意小的区域进行特征提取,但训练过程仍然是阶段的。Fast R-CNN在此基础上做了改进,整合了特征提取、分类和边界框回归,实现了端到端的训练,同时提高了速度和精度。 接下来需要整理Fast R-CNN的关键改进点。首先是ROI Pooling,取代了SPP层,将不同小的候选区域转换为固定小的特征图。其次是任务损失函数,将分类损失和回归损失结合在一起,简化了训练流程。此外,Fast R-CNN不需要将特征存储在磁盘上,减少了内存消耗。 然后需要说明算法流程。输入图像经过CNN得到特征图,然后提取候选区域(如通过Selective Search),通过ROI Pooling处理这些区域,最后通过全连接层进行分类和回归。这部分需要简明扼要,突出步骤间的逻辑。 关于实现方法,用户可能关心代码结构。需要提供一个简化的PyTorch示例,包括模型定义、ROI Pooling的使用以及任务损失的计算。代码应展示关键部分,如特征提取、ROI处理和损失函数,但不需要完整实现,避免过于复杂。 应用场景方面,Fast R-CNN适用于需要较高检测精度和实时性要求的场合,比如自动驾驶、视频监控等。可以举例说明其在工业界和学术界的应用。 最后,生成相关问题时要围绕Fast R-CNN的改进点、与其他算法的对比、实现细节和应用展开,帮助用户深入理解。 需要确保所有数学公式和术语符合格式要求,使用中文回答,结构清晰。同时检查引用是否正确,引用标识是否自然添加。避免使用Markdown格式,保持回答流畅自然。</think>### Fast R-CNN 算法详解 #### 一、算法背景 Fast R-CNN 是 R-CNN 系列的第二代改进模型,解决了 R-CNN 和 SPPNet 的计算冗余和阶段训练问题[^1]。其核心改进在于**端到端训练**和**特征共享**,将检测速度提升至 R-CNN 的 200 倍以上。 #### 二、核心原理 1. **特征共享** 输入整张图像至卷积神经网络(CNN),生成共享特征图,避免重复计算候选区域的特征[^2]。 2. **ROI Pooling 层** 将不同尺寸的候选区域(Region of Interest, ROI)映射为固定小(如 $7×7$)的特征图。公式描述: $$ \text{ROI Pooling}(x_i, h, w) = \max_{0≤m< \frac{h}{H}} \max_{0≤n< \frac{w}{W}} x_i(m,n) $$ 其中 $H×W$ 是输出尺寸,$h×w$ 是输入区域尺寸。 3. **任务损失函数** - 分类损失:Softmax 交叉熵 - 边界框回归损失:Smooth L1 损失 总损失函数为二者加权和: $$ L = L_{\text{cls}} + \lambda L_{\text{reg}} $$ #### 三、算法流程 1. 输入图像通过 CNN 生成特征图 2. 使用 Selective Search 提取约 2000 个候选区域 3. ROI Pooling 将候选区域特征标准化 4. 全连接层输出分类结果和边界框回归参数 #### 四、PyTorch 简化实现 ```python import torch import torchvision from torch import nn class FastRCNN(nn.Module): def __init__(self, num_classes): super().__init__() # 特征提取层(使用预训练VGG16) self.backbone = torchvision.models.vgg16(pretrained=True).features # ROI Pooling层 self.roi_pool = torchvision.ops.RoIPool((7,7), spatial_scale=1/16) # 分类与回归头 self.fc = nn.Sequential( nn.Linear(512*7*7, 4096), nn.ReLU(), nn.Linear(4096, 4096), nn.ReLU() ) self.cls_head = nn.Linear(4096, num_classes) self.reg_head = nn.Linear(4096, 4*num_classes) def forward(self, images, rois): # 提取共享特征 features = self.backbone(images) # [batch, 512, H/16, W/16] # ROI Pooling pooled = self.roi_pool(features, rois) # [num_rois, 512,7,7] # 全连接处理 flattened = pooled.flatten(1) # [num_rois, 512*7*7] fc_out = self.fc(flattened) # 输出结果 cls_scores = self.cls_head(fc_out) # [num_rois, num_classes] reg_params = self.reg_head(fc_out) # [num_rois, 4*num_classes] return cls_scores, reg_params ``` #### 五、应用场景 1. **实时视频分析**:如监控系统中的人/车检测 2. **医学影像处理**:病灶区域定位 3. **自动驾驶**:道路目标实时检测
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值