常见网络

常见网络

目标检测

R-CNN

  • 参考:https://blog.csdn.net/weixin_41923961/article/details/80113669
    • 测试过程
      1. 输入一张测试图像, 使用selective search算法提取出大约1000-2000个建议框
        • selective search算法的OpenCV使用
        
        im = cv2.imread('./test.jpg')
        ss = cv2.ximgproc.segmentation.createSelectiveSearchSegmentation()
        ss.setBaseImage(im)
        ss.switchToSelectiveSearchFast()
        # ss.switchToSelectiveSearchQuality()
        
        rects = ss.process()
        print('Total number of region proposals: ', len(rects))
        
        for i, rect in enumerate(rects):
            x, y, w, h = rect
            cv2.rectangle(im, (x, y), (x + w, y + h), (0, 0, 255), 1, cv2.LINE_AA)
        cv2.imshow('output.jpeg', im)
        cv2.waitKey(0)
      2. 取出一个建议框, 取出里面的图片, resize到227x227(R-CNN使用的AlexNet, AlexNet需要输入227x277大小的图片), 将其输入到AlexNet中, 每一个建议框都这样操作, 一个建议框得到4096个特征, 如果有2000个建议狂, 则有2000x4096个维度
      3. 将得到的2000x4096的特征放入到20个SVM(SVM是一个2分类的分类器, 这里有20个类别)分类器中, 得到2000x20维度的矩阵
      4. 2000x20个矩阵每一列就是一个物体的得分, 从2000列中挑选出同一类别的列向量, 对他们的建议框进行NMS抑制去掉重叠的框
      5. 使用20个回归器对物体的建议框进行修正, 得到bounding box, 在训练时, 因为建议框是通过selective search得到的, 不能够修改, 学习的是建议框到bounding box的变化
    • 流程图
    1418650-20190708232934314-176515679.png

Fast R-CNN

  • 之前的R-CNN的效率很低, 因为它对原图进行selective search, 生成大约2000个候选框, 在分别把这2000个候选框输入到网络中, 分别预测类别和回归框; 此外对输入的图片的尺寸越有要求, 要277x277, 所以对图片要么crop, 要么warp, 这其实都不是很可靠
  • Fast R-CNN提出RoIPooling和特征框
    • 特征框: 既然在原图上生成候选框再将这些候选框都输入到网络中很耗时间, Fast R-CNN就将原始图直接输入到AlexNet网络中, 得到的就是了feature maps, 将原图提取到的候选框映射到feature maps上, 成了特征框
    • RoIPooling: 参考了SPPNet中SPP池化, RoIPooling是SPP池化的单尺度形式, 加入FC要接受4维特征, 则RoIPooling将feature maps中的特征框划分成4份, 对每一份取最大值就可以了

      • 下图是输入到RoIPooling的特征图, fc接受的是4, 因此需要池化到2x2
        !1418650-20190708232643965-562455134.png

      • 黑色框为特征框

      1418650-20190708232656224-1511482498.png

      • 将RoI分成4份, 因为无法整除, 所以大小不一

      1418650-20190708232706468-1465096283.png

      • 注意: 在Fast R-CNN中, region proposal得到的x,y,w,h为小数, 这里将他们取整, 这里有一个细节: 取整之后, 此时的region proposal已经和一开始的region proposal有了偏差, 在目标检测中问题不大, 但是在图像分割会有很大的误差, 因为mask是逐像素的
        • 1418650-20190708232718284-1821423710.png
    • 全连接的参数使用SVD分解来加速算法
  • 流程图

1418650-20190708232745887-1443459254.png

Faster R-CNN

  • Fast R-CNN速度还是太慢了, 通过selective search方法生成候选框的实现要比分类更耗时, Faster R-CNN不在使用selective search生成候选框, 而是通过一个RPN网络得出出候选框

  • RPN有anchor的概念, 原图经过卷积之后输入到RPN分支网络, RPN取slide window对feature maps进行滑动, 在slide window中的每一个像素都有9个anchor, 分别为1:1, 2:1, 1:2比例的, 还要判断anchor中有无物体, 有则保留, 没有则去掉, 再使用NMS去重, 得出了候选框, 剩余分布和Fast R-CNN一样

  • 流程图

1418650-20190708232757121-111521822.png

  • 详细一点的

1418650-20190708232810246-752076143.png

  • 别人的
    1418650-20190708232832834-1694825875.png

1418650-20190708232819236-1912572077.png

1418650-20190708232843307-344456541.png

Mask R-CNN

  • Mask R-CNN可以理解为FPN-ResNet + Faster-RCNN, 把Faster-RCNN的RoIPooling改成了RoiAlign(提高mask的精度, 处理对齐问题, 采用双线性插值), 使用FPN-ResNet提取特征, 多一个分支来训练mask
  • 总的流程图
    • 1418650-20190708232853575-1417667685.png
  • mask损失
    • 与FCN分割的损失不同, FCN是上采样得到和原图一样尺寸的图, 通道数为类别个数, 一口气对每个像素的多个类别进行softmax
    • 而Mask R-CNN不同, 则为了避免类之间的竞争, 采用sigmoid函数, 比较之后此类的损失, 而不是一口气直接比较多个类的损失

池化

SPPNet

  • 实现代码

class SPPLayer(nn.Module):

    
    def __init__(self, sides):
        """
        Parameters
        ----------
        sides : array-like
            A list of side lengths
        """
        super(SPPLayer, self).__init__()
        self.sides = sides
    
    def forward(self, x):
        out = None
        for side in self.sides:
            ksize = tuple(map(lambda v: math.ceil(v / side), x.size()[2:]))
            strides = tuple(map(lambda v: math.floor(v / side), x.size()[2:]))
            paddings = (math.floor(ksize[0] * side - x.size()[2]), math.floor(ksize[1] * side - x.size()[3]))
            output = nn.MaxPool2d(ksize, strides, paddings)(x)
            if out is None:
                out = output.view(-1)
            else:
                out = t.cat([out, output.view(-1)])
        return out
  • 结构
    spp

    损失函数

L1

  • 公式: \(L_1={1\over{m}}\sum_{i=1}^{m}|h(x)-\hat{y}|\)
  • 一个样本且不求均值时的导数: \(L'_1=\pm{h'(x)}\)

L2

  • 公式: \(L_2={1\over{m}}\sum_{i=1}^m{(h(x)-\hat{y})}^2\)
  • 一个样本且不求均值时的导数: \(L'_2=2h'(x)(h(x)-\hat{y})\)

Smooth L1 Loss

  • 公式:
    \[ Loss_{smooth}=\begin{cases}0.5x^2 &|x|\lt 0.5\\ |x|-0.5 &otherwise \end{cases} \]其中\(x\)\(h(x)-\hat{y}\)
  • \(L2\)的图像差别

1418650-20190708232908782-1956371615.png

  • 由上图可知, 如果在训练的时候出现一个离群点, L2的只会特别的高, 对应的梯度也很高, 可能导致梯度爆炸, 而smooth loss即使是在离群点时, 梯度最大也才为1; smooth loss1与l1相比, 因为结合了l2, 收敛速度快, 对于异常值有很好的robust, 有在0处导数, 便于收敛

采样

上采样

  • 转置卷积: 容易导致棋盘效应; 还要额外训练参数; 相比插值上采样较复杂
  • 最近邻上采样
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值