Faster RCNN学习记录

本文从维度角度深入解析Faster RCNN的工作原理,包括图像预处理、RPN网络、ROI Heads等关键步骤。详细阐述了如何通过RPN生成候选框、RoI Pooling、分类和边界框回归,以及训练过程中的损失计算。
摘要由CSDN通过智能技术生成

Faster RCNN学习记录(从维度的角度来理解)

https://www.bilibili.com/video/BV1af4y1m7iL faster rcnn理论讲解(视频)

https://www.bilibili.com/video/BV1of4y1m7nj faster rcnn代码讲解(视频)

https://zhuanlan.zhihu.com/p/31426458 faster rcnn理论讲解

https://zhuanlan.zhihu.com/p/145842317 faster rcnn代码讲解

一 Faster RCNN原理

Faster RCNN的具体步骤可以总结如下:

(1)对图像进行预处理

(2)将处理好的图像输入至特征提取网络中(backbone)得到相应的特征图(feature maps)

(3)使用RPN(Region Proposal Networks)结构生成候选框(proposals),接着将生成的候选框投影到特征图中得到相应的特征矩阵

(4)将每个特征矩阵通过roi pooling层缩放至7×7大小的特征图,接着将特征图展平后通过一系列全连接层得到预测结果

二 Faster RCNN的结构

来自https://www.bilibili.com/video/BV1of4y1m7nj?p=9
在这里插入图片描述

三 Faster RCNN的算法流程

1 获取数据集(读取pascal voc数据集)

pascal voc数据集是人工标注的一些图片(xml格式),其中包含了图片的宽高、ground_truth值(xmin,ymin,xmax,ymax)的形式,标签值等。

通过读取pascal voc数据集数据集我们获得以下值:

(1)image:即具体的图片信息

(2)targets:包含boxes、labels、image_id、area、iscrowed五个索引的字典

其中boxes是[xmin,ymin,xmax,ymax]的形式,lables中存储的是labels对应的标签值

<annotation>
	<folder>VOC2012</folder>
	<filename>2007_000033.jpg</filename>
	<source>
		<database>The VOC2007 Database</database>
		<annotation>PASCAL VOC2007</annotation>
		<image>flickr</image>
	</source>
	<size>
		<width>500</width>
		<height>366</height>
		<depth>3</depth>
	</size>
	<segmented>1</segmented>
	<object>
		<name>aeroplane</name>
		<pose>Unspecified</pose>
		<truncated>0</truncated>
		<difficult>0</difficult>
		<bndbox>
			<xmin>9</xmin>
			<ymin>107</ymin>
			<xmax>499</xmax>
			<ymax>263</ymax>
		</bndbox>
	</object>
</annotation>

2 图片的预处理(GeneralizedRCNNTransform类)

这里的对图片的处理主要包括Normalize、Resize

在初始化函数中传入参数min_size、max_size、image_mean、image_std

在forward函数中传入参数images,targets

注:在训练脚本中,dataloader传入的batch_size即为一次选择多少图片进行训练,此时dataloader会调用VOC2012DataSet中的____getitem____()方法,一次可以获取一个batch_size张图片并进行返回。

  1. 首先获取一个batch_size中所有的图片信息

对于res_50_fpn训练脚本:batch_size设置为2,返回的images为

[torch.size([3,h1,w1]),
 torch.size([3,h2,w2])]

targets信息为

[{
   "boxes":torch.size([3,4]),
  "labels":torch.size([3]),
  "image_id":torch.size([1]),
  "area":torch.size([3]),
  "iscrowed":torch.size([3])}{
   "boxes":torch.size([2,4]),
  "labels":torch.size([2]),
  "image_id":torch.size([1]),
  "area":torch.size([2]),
  "iscrowed":torch.size([2])}]
  1. 遍历一个batch_size中的所有图片,得到每一张图片的image和target_index,分别对每一张图片进行标准化处理(减去均值,除以方差)
(image - mean[:, None, None]) / std[:, None, None]

注:这里的mean[:, None, None]将mean增加两个维度,None的位置维度为1,之后采用广播计算

  1. 将图片进行Resize处理
resize(image, target_index)
  • 获取输入图片(image)的高度和宽度,并找到宽度和高度中的最大值(max_size)和最小值(min_size)

  • 用size / min_size计算缩放比例(scale_factor)

  • 如果max_size * scale_factor > self.max_size,则scale_factor 换为self.max_size / max_size

  • 采用双线性插值的方法将图片以scale_factor为缩放因子对图片进行Resize

  • 根据图片的缩放比例对boxes进行缩放(根据resize后的图像和resize前的图像计算在宽度和高度上的缩放比例,得到[ratios_hight,ratios_width],将xmin和xmax乘ratios_width,ymin和ymax乘ratios_hight即可得到resize后的boxes值)

  1. 用resize后的图片和boxes替换原来的值

  2. 记录resize之后的图像的尺寸,此时的images仍是list2

image_sizes = [img.shape[-2:] for img in images]

注:image_sizes的shape为[torch.size([h1,w1]),torch.size([h2,w2])]

  1. 将一个batch中的图像打包成一个batch
batch_images(images)
  • 找到一个batch中所有图像最大的高度和宽度max_size[c,h_max,w_max]

  • 将h_max,w_max向上调整至32的整数倍得到ceil_h_max,ceil_w_max(这是因为经过backbone后feature map为原来的1/32)

  • 设定batch_shape = [len(images)] + max_size([batch, channel, height, width])

  • 创建shape为batch_shape且值全部为0的tensor

  • 将输入images中的每张图片复制到新的batched_imgs的每张图片中,对齐左上角,保证bboxes的坐标不变

  • 返回batched_imgs的shape为torch.size([2,3,h_max,w_max])

  1. 将image_sizes由List[Tensor,Tensor]变换为List[tuple,tuple],即 [(h1,w1),(h2,w2)]

  2. GeneralizedRCNNTransform类的返回值:

(1) image_list:Imagelist类型,

image_list.image_sizes,对应resize后的图像尺寸 [(h1,w1),(h2,w2)]的形式;

image_list.tensors,表示一个batch中的所有图片信息torch.size([2,3,ceil_h_max,ceil_w_max])的形式

(2) targets:List[dict]类型

targets = [{
   "boxes":torch.size([3,4]),
  			"labels":torch.size([3]),
  			"image_id":torch.size([1]),
 			 "area":torch.size([3]),
  			"iscrowed":torch.size([3])}{
   "boxes":torch.size([2,4]),
  			 "labels":torch.size([2]),
  			 "image_id":torch.size([1]),
 			 "area":torch.size([2]),
  			 "iscrowed":torch.size([2])}]

3 输入到backbone中进行特征提取

对于res_50_fpn:获得的features为一个有序字典(OrderedDict类型)

OrderedDict([('0':torch.size([2,256,192,256])),
             '1':torch.size([2,256,96,128]),
             '2':torch.size([2,256,48,64]),
             '3':torch.size([2,256,24,32]),
             'pool':torch.size([2,256,12,16])])

4 RPN(Region Proposal Networks)

初始化函数中设定:

anchor_generator:用来在原图上生成一系列的anchors
head:rpn_head部分,用来计算feature map中每个点为前景的概率以及边界框回归值
box_coder:用来计算边界框回归参数以及计算边界框坐标值
box_similarity:用来计算iou值
proposal_matcher:根据iou值设定正样本、负样本、丢弃的样本
fg_bg_sampler:计算损失时采样正负样本
self._pre_nms_top_n = pre_nms_top_n  选取每个feature map中前2000个score  
self._post_nms_top_n = post_nms_top_n  在选取的约8000个proposals中选取前2000个
self.nms_thresh = nms_thresh  nms的阈值
self.min_size = 1.

forward函数中传入:images、features、targets

images:image_list.image_sizes,对应resize后的图像尺寸 [(h1,w1),(h2,w2)]的形式;

image_list.tensors,表示一个batch中的所有图片信息torch.size([2,3,ceil_h_max,ceil_w_max])的形式

features:为一个有序字典(OrderedDict类型)

OrderedDict([('0':torch.size([2,256,192,256])),
             '1':torch.size([2,256,96,128]),
             '2':torch.size([2,256,48,64]),
             '3':torch.size([2,256,24,32]),
             'pool':torch.size([2,256,12,16])])

在使用的时候,features将变为list5类型

features.shape = [torch.size([2,256,192,256]),
             	  torch.size([2,256,96,128]),
                  torch.size([2,256,48,64]),
                  torch.size([2,256,24,32]),
                  torch.size([2,256,12,16])]

targets:list2

targets = [{
   "boxes":torch.size([3,4]),
  			"labels":torch.size([3]),
  			"image_id":torch.size([1]),
 			 "area":torch.size([3]),
  			"iscrowed":torch.size([3])}{
   "boxes":torch.size([2,4]),
  			 "labels":torch.size([2]),
  			 "image_id":torch.size([1]),
 			 "area":torch.size([2]),
  			 "iscrowed":torch.size([2])}]
4.1 AnchorsGenerator类
  1. 首先获取每个预测特征层的尺寸,得到grid_sizes,由于有5个预测特征层,因此grid_sizes的shape为List5,
grid_sizes.shape=[torch.size([168,256]),
                  torch.size([84,128]),
                  torch.size([42,64]),
                  torch.size([21,32]),
                  torch.size([11,16])]  #feature map的shape不一定和这些相同
  1. 获取输入图像的height和width,这里的height和width已经调整为32的整数倍,torch.size([672,1024])
image_size.shape = torch.size([672,1024])
  1. 计算特征图上的一步相当于原图上的多少步,strides为List5
strides.shape = [[torch.size(4),torch.size(4)],
                 [torch.size(8),torch.size(8)],
                 [torch.size(16),torch.size(16)],
                 [torch.size(32),torch.size(32)],
                 [torch.size(61),torch.size(64)]]
  1. 根据提供的scales=((32,), (64,), (128,), (256,), (512,))和aspect_ratios=((0.5, 1.0, 2.0),) * len(anchor_sizes)生成anchors模板,这里针对5个预测特征层,在每个预测特征层用1中尺度,三种比例生成模板,得到cell_anchors为List5
cell_anchors.shape = [torch.size([3,4]),
                      torch.size([3,4]),
                      torch.size([3,4]),
                      torch.size([3
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值