持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第14天,点击查看活动详情
RCNN的设计思路相对较为简单,其网络处理过程中的区域提取类似于暴力搜索,需要对每一个区域进行遍历,较为耗时。
对于RCNN的文章,可以在下面的获取。
https://arxiv.org/pdf/1311.2524.pdf
下面通过一幅图来说明RCNN的四个步骤。
第一步:生成候选区域,这一步会对输入的图像进行随机(选择性)搜索几个高质量的候选区域。基本思想就是对图像基于像素信息做一个快速的分割,然后将最相似的两个区域进行合并,然后一直重复上面的操作,直至将分割的区域重新拼接为一幅图。最后,将拼合后的图片生成多个有层次结构的提议区,并为每一个区域生成物体类别的真实边框。
第二步:选取一个预训练的卷积神经网络,然后将输出层丢弃,制作为一个特征提取模块。结合第一步的提议区,将每一个区域进行大小变换,变换到符合卷积神经网络输入的尺寸。
第三步:SVM分类器,将每一个提议区连同其标注信息生成一个样本,然后训练多个SVM进行分类。
第四步:边界框回归,在生成的样本中训练一个回归模型越策真实边框。
下面对FastRCNN的代码进行分析
class FasterRCNNTrainer(nn.Module):
def __init__(self, faster_rcnn):
super(FasterRCNNTrainer, self).__init__()
self.faster_rcnn = faster_rcnn
self.rpn_sigma = opt.rpn_sigma
self.roi_sigma = opt.roi_sigma
self.anchor_target_creator = AnchorTargetCreator()
self.proposal_target_creator = ProposalTargetCreator()
self.loc_normalize_mean = faster_rcnn.loc_normalize_mean
self.loc_normalize_std = faster_rcnn.loc_normalize_std
self.optimizer = self.faster_rcnn.get_optimizer()
self.vis = Visualizer(env=opt.env)
self.rpn_cm = ConfusionMeter(2)
self.roi_cm = ConfusionMeter(21)
self.meters = {k: AverageValueMeter() for k in LossTuple._fields} # average loss
然后是对loss函数进行的分析
def _fast_rcnn_loc_loss(pred_loc, gt_loc, gt_label, sigma):
in_weight = t.zeros(gt_loc.shape).cuda()
in_weight[(gt_label > 0).view(-1, 1).expand_as(in_weight).cuda()] = 1
loc_loss = _smooth_l1_loss(pred_loc, gt_loc, in_weight.detach(), sigma)
loc_loss /= ((gt_label >= 0).sum().float()) # ignore gt_label==-1 for rpn_loss
return loc_loss
作者在论文中做了丰富的实验,通过在VOC数据集中出色的表现,说明了作者提出的网络在某方面的优异性。
通过比较几组实验,作者发现RCNN可以提取到更多的不变性特征,使得整个网络的泛化性更好,能够学习到更多的有用信息。
这一组实验更能直观的展现作者使用提议区的优势。
RCNN提出了一种简单且可扩展的对象检测算法,第一个是将大容量卷积神经网络应用于自底向上的区域提议,以定位和分割对象。第二种是在标记训练数据稀缺的情况下训练大型cnn的范例。作者经过实验表明,对于数据丰富的辅助任务(图像分类),使用监督对网络进行预训练是非常有效的,然后对数据稀缺的目标任务(检测)进行微调网络。最后,作者指出,通过结合使用来自计算机视觉和深度学习的经典工具(自底向上区域提议和卷积神经网络),获得了这些结果。