faster-rcnn 笔记

数据获取

dataset = Dataset(opt)

input: opt(配置文件)
output: 自定义 Dataset类
包含 __getitem__ __len__ 实现 为了在torch的dataloader中使用

dataloader = data_.DataLoader(dataset,
                                  batch_size=1,
                                  shuffle=True,
                                  # pin_memory=True,
                                  num_workers=opt.num_workers)

transform 图片 处理为RGB (-1,1) 随机翻转 resize

训练

 img, bbox, label = img.cuda().float(), bbox_.cuda(), label_.cuda()

使用GPU

trainer.train_step(img, bbox, label, scale)

该trainer为FasterRCNNTrainer

faster_rcnn = FasterRCNNVGG16()
trainer = FasterRCNNTrainer(faster_rcnn).cuda()

FasterRCNNTrainer.py
其中包含了模型的主要训练内容

前向传播

提取特征

features = self.faster_rcnn.extractor(imgs)

input : image (N,C,H,W)
output: features shape未知

经过rpn

input : features, img_size, scale(在dataloader中获取 是相对于原图的放缩,不是卷积的放缩)
out : rpn_locs, rpn_scores, rois, roi_indices, anchor

RPN网络一些参数:
channel : 512
ratios = [0.5, 1, 2]
anchor_scales = [8, 16, 32],
feat_stride = 16
proposal_creator函数参数
nms_thresh=0.7
n_train_pre_nms=12000 经过nms之前
n_train_post_nms=2000 经过nms之后
n_test_pre_nms=6000
n_test_post_nms=300 测试时减小数量

由于所有网络的父类都是nn.Module 所以在前向传播时,直接使用rpn()来执行
直接使用self()会调用自身的__call__函数,而__call__函数使用的正是其父类中的,该函数又会调用self.forward, 而此时执行的正是子类即自己写的网络中的forward函数

Rpn网络前向传播

在这里插入图片描述
feature应该是(1,3,H,W,512)
首先根据feature大小生成anchor (H * W * 9) 大概20000
feature map 通过 33512 卷积层 (疑惑 为什么通过一个卷积层)
通过1 *1*36 (4*9) 卷积 产生四个坐标 rpn_loc (这个是偏移 即dx,dy,dw,dh)
通过1*1*18 (2*9) 卷积 产生二分类 rpn_scores

此处通过卷积得到的分别是(N,C,H,W,18)维度和(N,C,H,W,36)维度的
18和36为其通道数
也就是对于feature map的每一个像素点,都会有一个18个值和36个值的描述

获取前景分数 rpn_fg_scores

proposal_creator 函数

(在该函数中anchor首先会被rpn_loc修正)
input : rpn_loc , rpn_fg_scores,anchor(生成的20000个),img_size, scale
output : roi (从anchor中挑选出大概2000个)

        for i in range(n):
            roi = self.proposal_layer(
                rpn_locs[i].cpu().data.numpy(),
                rpn_fg_scores[i].cpu().data.numpy(),
                anchor, img_size,
                scale=scale)
            batch_index = i * np.ones((len(roi),), dtype=np.int32)
            rois.append(roi)
            roi_indices.append(batch_index)

n为batch_size 该代码不支持batch_size>1
再次说明
经过RPN输出的是
rpn_locs (1,H,W,36)
rpn_scores (1, H , W, 18)
rois (2000个 (训练时,测试时会减少))
roi_indices (下标)
anchor (应该是修正之前的 返回这个是因为要用于计算loss反向传播)

------------------------------------手动分割-------------------------------------------------------------

在产生2000个roi即proposal之后
由proposal_target_creator()函数
产生128个样本

proposal_target_creator()

该函数仅在训练时使用
input : roi, bbox(真实坐标),label(真实标签),loc_normalize_mean,loc_normalize_std(之后要对loc标准化)
output: sample_roi (128个), gt_roi_loc, gt_roi_label
参数说明:
n_sample=128 采样数
pos_ratio=0.25 正样本率
pos_iou_thresh=0.5
neg_iou_thresh_hi=0.5
neg_iou_thresh_lo=0.0
说明:该函数产生的128个样本用于自我训练
gt_roi_loc要减去均值除以标准差,因为要参与反向传播

说明: sample_roi 产生128个样本喂入head网络
gt_roi_loc,gt_roi_label 用于计算loss

head网络

input:features, sample_roi, sample_roi_index
output : roi_cls_loc, roi_score

在这里插入图片描述

head = VGG16RoIHead(
            n_class=n_fg_class + 1,
            roi_size=7,
            spatial_scale=(1. / self.feat_stride),
            classifier=classifier
        )

使用vgg16后两层全连接权重

RoIPooling2D层

input : features,rois
output : 可以看成是一个 batch-size=128,通道数为 512,7×7 的 feature map

给定一张图片的 Feature map (512×H/16×W/16) ,和 128 个候选区域的座(128×4),RoI Pooling 将这些区域统一下采样到 (512×7×7),就得到了 128×512×7×7 的向量
后面接两个FC
分成21类 每个类由4个坐标

  1. loss

Loss 以及 反向传播

N为batch_size 在改程序中为1
R为bboxs的数量
bboxs (N, R, 4)
labels (N,R)

AnchorTargetCreator : 负责在训练 RPN 的时候,从上万个 anchor 中选择一些 (比如 256) 进行训练,以使得正负样本比例大概是 1:1. 同时给出训练的位置参数目标。 即返回gt_rpn_loc和gt_rpn_label。

ProposalTargetCreator: 负责在训练 RoIHead/Fast R-CNN 的时候,从 RoIs 选择一部分 (比如 128 个) 用以训练。同时给定训练目标, 返回(sample_RoI, gt_RoI_loc, gt_RoI_label)

ProposalCreator: 在 RPN 中,从上万个 anchor 中,选择一定数目(2000 或者 300),调整大小和位置,生成 RoIs,用以 Fast R-CNN 训练或者测试。

其中AnchorTargetCreator和ProposalTargetCreator是为了生成训练的目标,只在训练阶段用到,ProposalCreator是 RPN 为 Fast R-CNN 生成 RoIs,在训练和测试阶段都会用到。三个共同点在于他们都不需要考虑反向传播(因此不同框架间可以共享 numpy 实现)
在训练时,head网络的输入是由ProposalCreator生成的2000个rois经过ProposalTargetCreator提取出的128个用以训练,而在测试阶段,是直接由ProposalCreator生成的300个rois作为输入,在rpn中做出的位置回归是针对于feature map的所有点的anchor即20000个anchor做出的回归,在根据前景该概率生成12000,利用非极大抑制选出2000个,此处是初步选出rois
RPN网络可以单独拿出来训练
训练数据来自extractor提取出的feature以及真实的标签(前背景)以及bbox
通过网络要得出的是anchor相对于bboxs的偏移(即大约(20000,4) , 20000为H/16*W/16*9,也就是网络的输出,(h,w,9
4) 该数值不固定,因为输入图片大小是可以不固定的)
那么根据的真实数据是什么呢?
就是anchor与已知bbox的偏移
当然还有score也是同样的
*

anchor_target_creator

input :bboxs(R,4), anchor(S,4), img_size()(H, W)
output: gt_loc (S,4) label(S, ) (1=positive, 0=negative, -1=ignore)
参数说明:
n_sample=256 采样数
pos_iou_thresh=0.7 正样本采样率
neg_iou_thresh=0.3 负样本采样率
pos_ratio=0.5 正样本率

loc = bbox2loc(anchor, bbox[argmax_ious])

所有的anchor(20000个)进行回归(为什么???)求出相对于bbox的偏差
此处的argmax_ious的意思就是可能会有多个物体的bboxs,那么anchor只是与其最接近的一个计算位置偏差

RPN losses

rpn——loc loss

只计算正样本(前景)的损失,不计算负样本的位置损失
input : rpn_loc(此为rpn网络的输出)gt_rpn_loc(由anchor_target_creator产生)gt_rpn_label(由anchor_target_creator产生) rpn_sigma(该参数与smooth_l1_loss有关)
output: rpn_loc_loss

rpn——score

此处用的是256个样本,而非所有的anchor
根据rpn_score,gt_rpn_label 计算 rpn_cls_loss(cross_entropy)

ROI losses (fast rcnn loss)

roi_loc

根据gt_roi_loc和gt_roi_label计算roi_loc
gt_roi_loc和gt_roi_label由proposal_target_creator()生成
为什么不直接使用RPN产生的2000个rois进行训练呢?
因为之前的只是前景背景,只是两类,而现在需要生成21类gt_label和相应偏差
作为真实值,使得网络在接收到feature和别的rois时可以较好的估计出偏差以及label,最后rois加上偏差才会更加接近真实值。

一个 RoI 在经过 FC 84 后会输出一个 84 维的 loc 向量. 如果这个 RoI 是负样本, 则这 84 维向量不参与计算 L1_Loss

如果这个 RoI 是正样本, 属于 label K, 那么它的第 K×4, K×4+1 ,K×4+2, K×4+3 这 4 个数参与计算损失,其余的不参与计算损失。

roi_cls_loss

cross_entropy

  1. 预测

预测

input : image
output : _bboxes((R, 4),R is the number of bounding boxes in a image)
_labels: (R,) value: [0, L - 1]
_scores: (R,) how confident the prediction is
注:

a = np.array([1,2,3,4])
a.shape
# (4,)

predict

img_size = x.shape[2:]
h = self.extractor(x)
rpn_locs, rpn_scores, rois, roi_indices, anchor = \
self.rpn(h, img_size, scale)
roi_cls_locs, roi_scores = self.head(h, rois, roi_indices)

在预测时只需要用到RPN产生的rois, roi_indices
最后用nms

Other

RPN网络的输入只有feature,RPN负责根据feature预分类,找出前景anchor
在筛选出最可能的N个anchor,喂入ROI_Head网络
相当于Head网络多接受了一组信息,即可能的位置,所以产生更加精细的划分。
注意:网络估计的都是loc 即偏移量
在这里插入图片描述
图片来自于: https://blog.csdn.net/e01528/article/details/79615987

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值