MASK RCN

resnet输入图像尺寸 resnet图片尺寸_ide

这里的s表示stride,残差网络res2,3,4,5负责改变channel数和利用stride=2减半特征图的长宽。但是,对于res2来说,因为输入长宽和输出长宽一样,所以stride=1. res2,3,4,5内部可以堆叠任意多个不改变channel大小的resblock,根据这些block数量的不同,resnet又分为resnet18 resnet50等等。可以设置一个最小的特征图尺寸,比如(H/8,W/8),它相当于对原图进行stride=8的卷积,那么res4和res5的stride就应该改为1. 相应的,在上采样的过程中,由于res5,res4和res3的特征图尺寸一样, 所以只需要从res3的特征图开始上采样即可。

resnet输入图像尺寸 resnet图片尺寸_ci_02

图像resize

图像resize的时候需要指定一个max_size和min_size,优先把原图的短边resize到min_size, 如果此时图片的长边超过了max_size则转而把原图的长边resize到max_size.
实际resize后的图像尺寸计算如下:

def get_size(self, image_size):
    # always rescale accorting to the short edge and size
    w, h = image_size
    size = self.min_size
    if self.scale_jittering:
        size = self.min_size_random_group[np.random.randint(self.group_size)]

    max_size = self.max_size
    if max_size is not None:
        min_original_size = float(min((w, h)))
        max_original_size = float(max((w, h)))
        if max_original_size / min_original_size * size > max_size:
            size = int(round(max_size * min_original_size / max_original_size))

    if (w <= h and w == size) or (h <= w and h == size):
        return (h, w)

    if w < h:
        ow = size
        oh = int(size * h / w)
    else:
        oh = size
        ow = int(size * w / h)
    # print('size:', (oh, ow))
    return (oh, ow)

RPN

  • nms 非极大值抑制
  1. 将多个框体按照置信度排序
  2. 选出置信度最大的框体,删除剩余框体与该框体IoU大于阈值的框体。(这一步确定了一个物体的框体,并删除了其他可能重复预测的框体)
  3. 重复步骤ii,直至处理完所有框体
  • soft nms
  • resnet输入图像尺寸 resnet图片尺寸_ci_03

    resnet输入图像尺寸 resnet图片尺寸_卷积_04

  • 生成anchor
    对于backbone输出的每一个特征图(Resnet 有5个),RPN输出一个 cls_logit(H/n,W/n,3) 和一个bbox_pred(H/n,W/n,3x4). 其中3代表3个不同长宽比的anchor(eg0.5,1,2),n代表对于原图的缩放倍数(分别为4,8,16,32,64)
  • 生成proposals
    对5种不同尺度的特征图,都执行以下操作
  1. 取出置信度前pre_nms_top_n的anchors;(eg pre_nms_top_n=2000)
  2. 根据regression结果和anchor坐标,计算出proposals坐标
  3. 执行一次NMS(第一次),并限制proposals最大个数为post_nms_top_n
  4. 收集5个特征分支的proposals,选择置信度最高的fpn_post_nms_top_n个最后再把真实的gt-box加入到proposals中
  • 为所有anchor制作label
  1. (前景标签为1) :与gt最大IoU超过high_threshold=0.7的anchor 与gt IoU最大的anchor(有可能最大的IoU没有超过阈值,通过该规则将其捡回来)满足以下条件的anchor设置为负标签0
  2. (背景标签为1):与gt最大IoU小于low_threshold=0.3的anchor其他与gt最大IoU介于阈值之间的(0.3,0.7)记为其他类,不算损失。再计算anchor与对应gt的回归目标
  • 正负样本均衡化(筛选)
  1. batch_size_per_image:每张图片用于计算损失的anchor数目,eg 256
  2. positive_fraction:正样本所占比例, eg 0.5 正样本取num_pos=min(0.5*256, fg),即若生成的anchor中正样本数目超过128,则取128;若少于128,则保留所有正样本。
  3. 负样本为num_neg =batch_size_per_image - num_pos
  • 计算损失
    前后景预测的损失和前景回归损失
  • resnet输入图像尺寸 resnet图片尺寸_深度学习_05

ROI Head

  • ROI Align

resnet输入图像尺寸 resnet图片尺寸_深度学习_06


  • 左图是fast rcnn中的roi pooling,需要经过两次取整, 一次是从原图中的ROI(带小数)映射到特征图上,另一次是在特征图上做pooling操作。 而在ROI Align中两次操作都可以保留小数,原因是做了一个插值:

右图中的池化目标3x3
首先在每个cell内采样,此处采样系数为2,因此在池化范围内采样2*2=4个点。将cell划分成4部分,每一部分的中心点作为采样点(图中蓝色点)
每一个蓝色点的值通过双线性插值计算
取四个蓝色点中最大的值作为该cell的池化结果

  • box feature extractor
  1. 先对2000个proposal做筛选(这里2000是为了保证训练和测试一致,因为测试时并不知道gt)。计算proposals与gt的IoU,大于0.7的设置为前景,小于0.3的设置为背景。总共取512个proposals,正样本最多为0.25×512=128个,其余为负样本。
  2. 使用ROI Align取出proposal对应的特征。ROI尺寸设置为7,features的channel=256,则取出来的特征维度为512 * 256 * 7 * 7,reshape成512×12544
  3. 送入两个全连接层(12544,1024)、(1024,1024),得到特征512*1024
  • box predictor
  1. 分支一,全连接层 (1024, num_calsses)预测类别
  2. 分支二,全连接(1024, 8) 预测坐标变换系数
  3. 计算512个proposals的交叉熵分类损失
  4. 计算正样本回归损失
  • mask feature extractor
    如果和box feature 不公用特征的话
  1. 取出512个proposals中的前景proposals,假设有20个
  2. 使用ROI Align取出proposal对应的特征。ROI尺寸设置为14,features的channel=256,则取出来的特征维度为20 * 256 * 14 * 14
  • mask predictor
  1. 输入20×256×14×14的tensor
  2. 经过一个转置卷积,输出20×256×28×28
  3. 再经过一个1×1的卷积,输出20×num_class×28×28
  • mask loss
  1. 根据前景proposals和gt的IoU,得到每个proposals对应的实例及其mask
  2. 用proposals裁剪mask,并将maskresize到28×28,作为实际值用于计算loss
  3. 取出mask predictor输出中对应gt类别的Channel,和上一步得到的mask_target计算交叉熵损失。

YOLO v3

resnet输入图像尺寸 resnet图片尺寸_ide_07

  • 在82层卷积处输出第一个检测结果。假设图片的输入大小为416×416,此时特征图的大小为13×13。每一个cell设置3个anchor,每一个anchor预测(4+1+C)个值,假设类别为60类,那么共计输出3×(4+1+60)=255个值,即输出维度为13×13×255。
  • 第79层的卷积的输出结果继续进行卷积操作,上采样,和浅层特征融合,卷积,得到第二种尺寸的检测输出。输出维度为26×26×255
    后面进行与第二步类似的操作,输出维度为52×52×255
  • 在YOLOv3中,预设的anchor个数共有 ( 13 ∗ 13 + 26 ∗ 26 ∗ 52 ∗ 52 ) ∗ 3 = 10647 (1313+26265252)3=10647 (13∗13+26∗26∗52∗52)∗3=10647;YOLOv2中共有 13 ∗ 13 ∗ 5 = 845 1313*5=845 13∗13∗5=845。
  • 每一种scale中预设的anchor是从数据集中聚类得到的9种中的三种。
  • 使用不同尺度的特征图来预测,改善了YOLO对小物体的检测效果。

cornerNet

  • backbone
    Hourglass先由卷积和池化将feature maps下采样到一个很小的尺度,之后再用nearest neighbor upsampling的方法进行上采样,将feature maps还原到最开始的尺度。不难看出,下采样和上采样是对称的,并且在每个upsampling层都有一个skip connection,skip connection上是一个residual modules。
    使用这种沙漏结构的目的是为了反复获取不同尺度下图片所包含的信息。例如一些局部信息,包括脸部和手部信息。人体姿态估计也需要对整个人体做一个理解,也就是一些全局信息,包括人体的方位,肢体的动作以及相邻关节点的关系。最后通过上采样和残差结构将局部信息和全局信息组合起来。
    CornerNet采用了2个Hourglass组成的Hourglass Network

-predictor

resnet输入图像尺寸 resnet图片尺寸_resnet输入图像尺寸_08


resnet输入图像尺寸 resnet图片尺寸_卷积_09

主干网后紧跟两个prediction modules,其中一个检测top-left corners ,另一个检测bottom-right corners,最后对两组corner进行筛选,组合,修正得到object的一对corners,从而定位object的box。Embeddings

  • Heatmaps
    Heatmaps预测哪些点最有可能是Corners点
  1. 损失函数为

resnet输入图像尺寸 resnet图片尺寸_深度学习_10


其中resnet输入图像尺寸 resnet图片尺寸_resnet输入图像尺寸_11由高斯公式算出,距离真正的角点越近,值就越大
原focal loss为

resnet输入图像尺寸 resnet图片尺寸_深度学习_12


可以看出这里(1-resnet输入图像尺寸 resnet图片尺寸_resnet输入图像尺寸_11)用来降低正真交点附近预测点的惩罚

  1. Embeddings
    Embeddings用于表征属于相同对象的corner的相似度。训练的时候拉近同一对象的角点的距离,拉开不同对象角点的距离
  • Offsets

resnet输入图像尺寸 resnet图片尺寸_ide_14

resnet输入图像尺寸 resnet图片尺寸_卷积_15

  • 这里直接回归在heatmap上预测出一个corner后,映射回image时坐标精度的损失

resnet输入图像尺寸 resnet图片尺寸_卷积_16

centernet

由于采用全卷积网络直接得到4倍下采样的热力图,所以不需要提前设定anchors, 所以大大减少了网络参数量和计算量。热力图的通道数等于要检测的目标类别数,热力图的前100个峰值作为网络提取的目标中心点,然后设定一个阈值进行筛选得到最终的目标中心点。
Centernet 中所有的上采样前都有deformable卷积,这种卷积的作用就是使得网络的感受野变得更加精确,而不是限定为3*3的矩形卷积框内。同时4倍的下采样feature map 比一般网络的分辨率高很多,所有不需要进行多尺度预测和特征金字塔也可以同时较好的检测大小目标。
Centernet 不需要NMS,因为所有检测的中心点是由热力图的峰值得到的,这样就已经有一个非极大值抑制的过程,而且NMS是十分耗时的,所以Centernet才能又好又快。
Centernet 采用编码解码的全卷积骨干网络,上采样用到的是转置卷积,与一般上采样中的双线性差值有很大区别,转置卷积可以更好的还原图像的语义信息和位置信息

训练的时候直接利用gt的中心点在特征图(和heatmap不同分支)上对应的特征点来预测长宽和精度损失
并且和类别无关(不用每一个类别都算一遍,只有计算中心点heatmap时和类别有关),减少了计算量
那么怎么在训练时把中心点和长宽特征图关联起来呢? 可以在制作groundtruth的时候,保存每一个实例的中心点在长宽特征图中的索引,所以有gt_wh:[batch, max_instance_num,2]和gt_index:[batch, max_instance_num,index], gt_mask:[batch,max_instance_num]

计算关键点时,假设每个实例有k个关键点,模型先计算特征图

resnet输入图像尺寸 resnet图片尺寸_resnet输入图像尺寸_17


2表示特征点对于实例中心点的偏移量。模型另外还专门计算关键点的heatmap

resnet输入图像尺寸 resnet图片尺寸_卷积_18


推理过程:

对于模型输出的中心点heatmap,先用maxpool 代替nms:

pad = (pool_size - 1) // 2
        fmap_max = F.max_pool2d(fmap, pool_size, stride=1, padding=pad)
        keep = (fmap_max == fmap).float()

然后对每张图取score最大的100个中心点。
推理关键点时,先用偏移量算出每个中心点对应的所有关键点,然后用它们去查找heatmap中score>0.1 并且在包围框内的真正关键点。