SSD-实时目标检测

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

 SSD 实时目标检测 SSD是为了实现实时目标检测而设计的。Faster R­CNN使用一个区域建议网络 region proposal network (RPN)产生可能包含物体的建议区域(一般训练时2000,测试时600),并且利用这些建议区域进行微调对物体进行分类和定位。Faster RCNN 整个处理过程大约是每秒 7 帧,这远远不能满足实时性。SSD通过取消 RPN 来加速处理过程。为了弥补精度上的损失,SSD采取了一些改进方法如:1. 提取了不同尺度的特征图来做检测,大尺度特征图(较靠前的特征图)可以用来检测小物体,而小尺度特征图(较靠后的特征图)用来检测大物体。这些改进方法允许SSD使用较低分辨率的图像就可以达到Faster R­CNN的精度,而且处理速度更快。从下图可以看出,SSD达到了实时处理的速度并且精度还强于Faster R­CNN。(精度的评价指标是mAP­预测平均精度)。2. 采用了不同尺度和长宽比的先验框(Prior boxes, Default boxes,在 Faster R­CNN 中叫做锚,Anchors)。3. 采用CNN来直接进行检测,而不是像 Faster RCNN Yolo 那样在全连接层之后做检测,实现了全卷积4. 将空洞卷积应用于目标检测。这些改进方法使得 SSD 在使用较低分辨率的图像( lower resolution images)就可以达到 Faster R­CNN 的精度,而且处理速度更快。从下图可以看出,SSD达到了实时处理的速度并且精度还超过了 Faster R­CNN。SSD is a classaware RPN with a lot of bells and whistles.SSD SSD 包含两个部分:提取特征图应用卷积核检测物体ModelmAPTraining CommandTraining logSSD 使用 VGG16 作为特征提取网络 backbone,当然你也可以用其他的 backbone,例如 mobilenet,resnet等等,不过奇怪的是使用 resnet 貌似提升不大。不过其实对于物体较大的简单任务,使用mobilenet还是其他什么的区别不是很大,因此具体选哪个得看自己的任务了。下面是 GluonCV 得到的结果,使用了一些 tricks 得到了超越原论文的表现:­cv.mxnet.io/model_zoo/detection.html#ssdssd_300_vgg16_atrous_voc [1]77.6shell scriptlogssd_512_vgg16_atrous_voc [1]79.2shell scriptlogssd_512_resnet50_v1_voc [1]80.1shell scriptlogssd_512_mobilenet1.0_voc [1]75.4shell scriptlog可以看到由 VGG 换为 resnet50提升只有 0.9%,甚至有时候还会下降,这点比较奇怪。而 Faster RCNN 由 VGG16 变为 ResNet101 可以提升 5%。VGG 太大了,由上面的图可以看到,基本没有比 VGG 还大的了。SSD 使用 Conv4_3 的卷积层(VGG 下采样16倍之前的所有网络层)来检测物体。为了方便说明,我们假设图片经过 Conv4_3 变成了一个 8×8 的特征图(它应该是38×38,因为下采样了 8 倍)。对于每个 cell (也称为location),它进行了 4 个预测。  左:原始图片 右:每个 cell 4 个预测。每个预测结果包含一个边界框 bbox 以及这个bbox 属于这 21 个类别的得分(其中一个是背景类别),我们选择其中昀高的得分所属类别作为该bbox的分类类别。Conv4_3 总共会做出 38x38x4 个预测:每个 cell 4 个预测,跟特征图的深度无关。显然,很多预测结果中都不包含物体。SSD 将这些不包含物体的归类为0。  每个预测结果包含一个边界框 bbox 以及这个bbox 属于这 21 个类别的得分(其中一个是背景类别)VGG网络部分源码: # vgg(base['300'], 3) SSD 中的VGG16配置:# base['300'] = [64, 64, 'M', 128, 128, 'M', 256, 256, 256, 'C', 512, 512, 512, 'M',512, 512, 512]#  VGG16 官方的特征提取部分配置:#               [64, 64, 'M', 128, 128, 'M', 256, 256, 256, 'M', 512, 512, 512, 'M', 512, 512, 512, 'M']# 可以看到去掉了昀后的maxpooling层,并且对于其中一个maxpooling改变了ceil_mode,这在 75 进行maxpooling时会使得# 75 == 37.5 == 38 而不是变成 37# 不太明白为什么要这样,不过应该没太大的影响,可能还是为了尺寸方面考虑# 300 == 150 == 75 == 38 == 19'M':表示使用 kernel size = 2,stride = 2 的 max pooling 'C':表示与‘M’相同的 max pooling,但 ceil_mode = True,需要注意的是这与原始的VGG不同,原始的VGG没有这个选项def vgg(cfg, i, batch_norm=False):          (vgg): ModuleList(    (0): Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) Conv1_1    (1): ReLU(inplace)    (2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))Conv1_2    (3): ReLU(inplace)    (4): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)    (5): Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) Conv2_1    (6): ReLU(inplace)    (7): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) Conv2_2    (8): ReLU(inplace)    (9): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)    (10): Conv2d(128, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) Conv3_1    (11): ReLU(inplace)    (12): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) Conv3_2    (13): ReLU(inplace)    (14): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) Conv3_3123456789101112131415161718192021222324252627282930    (14): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) Conv3_3    (15): ReLU(inplace)    (16): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=True)    (17): Conv2d(256, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) Conv4_1    (18): ReLU(inplace)    (19): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) Conv4_2    (20): ReLU(inplace)    (21): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) Conv4_3 检测所用的特征图    (22): ReLU(inplace)    (23): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)    (24): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) Conv5_1    (25): ReLU(inplace)    (26): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) Conv5_2    (27): ReLU(inplace)    (28): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) Conv5_3    (29): ReLU(inplace)    ###############################################################################################    (30): MaxPool2d(kernel_size=3, stride=1, padding=1, dilation=1, ceil_mode=False) pool5    (31): Conv2d(512, 1024, kernel_size=(3, 3), stride=(1, 1), padding=(6, 6), dilation=(6, 6)) conv6    (32): ReLU(inplace)    (33): Conv2d(1024, 1024, kernel_size=(1, 1), stride=(1, 1)) conv7 检测所用的特征图    (34): ReLU(inplace)  )        layers = []    in_channels = i    for v in cfg:        if v == 'M':            layers += [nn.MaxPool2d(kernel_size=2, stride=2)]        elif v == 'C':            # ceil模式shape向上取整            layers += [nn.MaxPool2d(kernel_size=2, stride=2, ceil_mode=True)]        else:            conv2d = nn.Conv2d(in_channels, v, kernel_size=3

1 / 20
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功