学习路线指引(点击解锁) | 知识定位 | 人群定位 |
---|---|---|
Python实战微信订餐小程序 | 进阶级 | 本课程是python flask+微信小程序的完美结合,从项目搭建到腾讯云部署上线,打造一个全栈订餐系统。 |
Python量化交易实战 | 入门级 | 手把手带你打造一个易扩展、更安全、效率更高的量化交易系统 |
本系列为 斯坦福CS231n 《深度学习与计算机视觉(Deep Learning for Computer Vision)》的全套学习笔记,对应的课程视频可以在 这里 查看。更多资料获取方式见文末。
ShowMeAI在前面的内容中给大家做了很多图像分类的介绍,主要围绕卷积神经网络(LeNet / AlexNet / NIN / VGG / Google / ResNet / MobileNet / squeezenet)讲解,但计算机视觉领域有其他一些更为复杂的任务,例如本篇开始介绍的目标检测(object detection)问题。
大家知道人工智能领域的3大热点方向是计算机视觉(CV,computer vision)、自然语言处理(Natural Language Process, NLP )和语音识别(Speech Recognition) 应用 。而计算机视觉领域又有图像分类、目标检测、图像分割三大任务,如下图所示
这3大任务其实对应机器视觉理解图像的3个主要层次:
图像分类任务中,我们要将图像识别判定为某个类别。它是最简单、最基础的图像理解任务,也是深度学习模型最先取得突破和实现大规模应用的任务。大家在前面也了解到了 ImageNet 这个权威评测集,每年的ILSVRC催生了大量的优秀深度网络结构,为其他任务提供了基础。
有一些其他的应用,包括人脸识别、场景识别等都可以化归为分类任务来解决。
图像分类任务关心整体图片类别,而目标检测则关注特定的物体目标,要求在图片中,同时识别出目标物的类别信息和位置信息(是一个classification + localization的问题)。
相比分类,目标检测任务要求我们需要从背景中分离出感兴趣的目标,并确定这一目标的描述(类别和位置),检测模型的输出形式通常是一个列表,列表的每一项使用一个数组给出检出目标的类别和位置(常用矩形检测框的坐标表示)。
图像分割包括语义分割(semantic segmentation)和实例分割(instance segmentation),前者是对前背景分离的拓展,要求分离开具有不同语义的图像部分(相当于像素级别的分类),而后者是检测任务的拓展,要求描述出目标的轮廓(相比检测框更为精细)。
分割是对图像的像素级描述,它赋予每个像素类别意义,适用于理解要求较高的场景,如无人驾驶中对道路和非道路的分割,医疗影像中对于不同区域的划分。
图像分类对应将图像划分为单个类别的过程,它通常对应于图像中最突出的物体。实际现实世界的很多图像通常包含多个物体,如果仅仅使用图像分类模型分配单一标签是非常粗糙的,并不准确。而目标检测(object detection)模型可以识别一张图片的多个物体,并可以给出不同物体的具体位置(边界框)。目标检测在很多场景有用,如无人驾驶和安防系统。
常见的经典目标检测算法如下图所示:
目标检测的基本思路是:解决定位(localization) + 识别(Recognition) 两个任务。
一个大致的pipeline如下图所示,我们可以用同样的特征抽取过程,借助两个不同的分支输出。
传统的目标检测框架,主要包括三个步骤:
现在主流的深度学习目标检测方法主要分为两类:两阶段(Two Stages)目标检测算法和一阶段(One Stage)目标检测算法。
上述两类方法,基于候选区域(Region Proposal)的方法(两阶段)在检测准确率和定位精度上占优,基于端到端(一阶段)的算法速度占优。相对于R-CNN系列的「两步走」(候选框提取和分类),YOLO等方法只「看一遍」。
我们在本篇中给大家介绍两阶段的目标检测方法,主要是R-CNN系列目标检测方法,在下篇内容目标检测 (SSD,YOLO系列)中给大家介绍一阶段的目标检测方法(YOLO系列,SSD等)。
如何将深度学习分类算法应用到目标检测?
R-CNN核心思想: 对每张图片选取多个区域,然后每个区域作为一个样本进入一个卷积神经网络来抽取特征。
R-CNN算法是较早提出的两阶段目标检测算法,它先找出 Region Proposal,再进行分类和回归。
对于每张输入的图像,R-CNN目标检测主要包括下述步骤:
R-CNN 的效果如下图所示,它有一些不足之处(也是系列算法后续改进的点):
优化方式为:
我们通过前面的 CNN 相关知识学习知道,CNN 的卷积层不需要固定尺寸的图像,而全连接层是需要固定大小的输入。所以当全连接层面对各种尺寸的输入数据时,就需要对输入数据进行 crop(抠图)或者 wrap(图像resize)操作。
在 R-CNN中,因为不同的 proposal 大小不同,所以需要先 resize 成相同大小再输入到 CNN 中。既然卷积层是可以接受任何尺寸的,可以在卷积层后面加上一部分结构使得后面全连接层的输入为固定的,这个「化腐朽为神奇」的结构就是 spatial pyramid pooling layer。
下图是 R-CNN 和 SPP-Net 检测流程的比较:
SPP-Net 和普通 CNN 的对比结构如下,在网络结构上,直接把 pool5 层替换成 SPP 层:
SPP-Net 的具体细节如下,由 features map 上确定的 region proposal 大小不固定,将提取的 region proposal 分别经过三个卷积 4∗44∗44 \ast 4,2∗22∗22 \ast 2,1∗11∗11 \ast 1 ,都将得到一个长度为 21 的向量(21是数据集类别数,可以通过调整卷积核大小来调整),因此不需要对 region proposal 进行尺寸调整:
相比R-CNN,SPP-Net有两大优点。
① 通过「特征金字塔池化」模块,实现了 CNN 的多尺度输入,使得网络的输入图像可以是任意尺寸的,输出则不变,同样是一个固定维数的向量。
② R-CNN 要对每个区域计算卷积,而 SPPNet 只需要计算一次卷积,从而节省了大量的计算时间。
对于 RCNN 速度过慢等问题,提出了基于 RCNN 的改善模型 Fast RCNN。
Fast RCNN 主要改进以下部分:
如下图所示为Fast R-CNN流程与网络结构
Fast R-CNN具体包括的核心环节如下:
跟RCNN一样,Fast-RCNN 采用的也是 Selective Search 的方法来产生 Region Proposal,每张图片生成 2k 张图片。但是不同的是,之后不会对 2k 个候选区域去原图截取,后输入 CNN,而是直接对原图进行一次 CNN,在 CNN 后的 feature map,通过 ROI project 在 feature map 上找到 Region Proposal的位置。
就是对原图输入到 CNN 中去计算,Fast-RCNN 的工具包提供提供了 3 种 CNN 的结构,默认是使用 VGG-16 作为 CNN 的主干结构。根据 VGG-16 的结构,Fast-RCNN 只用了 4 个 MaxPooling 层,最后一个换成了 ROI Pooling,因此,只需要对 Region Proposal 的在原图上的 4 元坐标 (x,y,w,h)(x,y,w,h)(x, y, w, h) 除以 161616,并找到最近的整数,便是 ROI Project 在 feature map 上映射的坐标结果。最终得到 2k2k2k 个 ROI。
对每一个 ROI 在 feature map 上截取后,进行 ROI Pooling,就是将每个 ROI 截取出的块,通过 MaxPooling 池化到相同维度。
ROI Pooling的计算原理是,将每个不同大小的 ROI 平均划分成 7×77×77 \times 7 的 grid,在每个 grid 中取最大值,最后所有 ROI 都会池化成大小为 7×77×77 \times 7 维度。
将每个 ROI Pooling 后的块,通过全连接层生成 ROI 特征向量,最后用一个 Softmax 和一个 bbox regressor 进行分类和回归预测,得到每个 ROI 的类别分数和 bbox 坐标。全连接层为矩阵相乘运算,运行消耗较多,速度较慢,作者在这里提出可以使用 SVD 矩阵分解来加快全连接层的计算。
Fast-RCNN 的两个任务:
Fast R-CNN 效果如上图所示,相比之 R-CNN 它在训练和预测速度上都有了很大的提升,但它依旧有不足之处,大家观察整个流程,会发现在候选区域选择上,依旧使用的 Selective Search 方法,它是整个流程中的时间消耗瓶颈,无法用 GPU 硬件与网络进行加速。
Faster-RCNN 在 Fast-RCNN 的基础上做了两个重大的创新改进:
Faster R-CNN的总体流程结构如下,可分为Backbone、RPN、ROI+分类 / 回归 三个部分。
Anchor 是图像检测领域一个常用的结构,它可以用来表示原图中物体所在的区域,是一个以feature map 上某个点为中心的矩形框。
Faster-RCNN 的 anchor,在 feature map 上每个点,生成 3 种尺度和 3 种比例共 9 个 anchor。
RPN 是一个全卷积的神经网络,它的工作原理可以分成 classification,regression 和 proposal 三个部分
Classification 部分将得到的 feature map 通过一个 3×33×33 \times 3 和 1×11×11 \times 1 的卷积后,输出的维度为 [1×18×38×50][1×18×38×50][1 \times 18 \times 38 \times 50],这18个channel可以分解成 2×92×92\times9,2代表着是否是感兴趣物体备选区域(region proposal)的 0/1 的 score,9 代表着 9 个 anchors。
因此,特征图维度 38×5038×5038\times50 的每一个点都会生成 9 个 anchor,每个 anchor 还会有 0/1 的 score。
Regression 部分原理和 Classification 部分差不多,feature map通过一个 3×33×33 \times 3 和 1×11×11 \times 1 的卷积后,输出的维度为 [1×36×38×50][1×36×38×50][1 \times 36 \times 38 \times 50],其中 36 个channel可以分成 4×94×94 \times 9,9就是跟 cls 部分一样的 9 个anchor,4 是网络根据 anchor 生成的 bbox 的 4 元坐标 target 的 offset。通过 offset 做 bbox regression,再通过公式计算,算出预测 bbox 的 4 元坐标 (x,y,w,h)(x,y,w,h)(x, y, w, h) 来生成 region proposal。
将前两部分的结果综合计算,便可以得出 Region Proposals。
一般来说,前景和背景的 anchor 保留的比例为 1:31:31:3
RPN 网络的训练样本有如下的策略和方式:
RPN 网络是监督学习训练,包含分类和回归两个任务,分类分支和回归分支的预测值和 label 构建方式如下:
RPN 网络的总体 loss 由 2 部分构成,分别是分类 loss 和回归 loss,为其加权求和结构。其中分类 loss 使用常规的交叉熵损失,回归损失函数使用的是 Smooth L1 Loss,本质上就是L1 Loss 和 L2 Loss 的结合。
特别说一下回归部分使用到的 Smooth L1 Loss,对比于 L1 Loss 和 L2 Loss,Smooth L1 Loss 可以从两方面限制梯度:
结合分类和回归结果得出 Region Proposals。若 anchor 的 IoU>0.7IoU>0.7IoU > 0.7,就认为是前景;若 IoU<0.3IoU<0.3IoU < 0.3,就认为是背景,其他的anchor全都忽略。一般来说,前景和背景的anchor保留的比例为 1:31:31:3 。
得到 Region Proposal 后,会先筛选除掉长宽小于 16 的预测框,根据预测框分数进行排序,取前N(例如6000)个送去 NMS,经过 NMS 后再取前 topktopktop_k(例如300)个作为 RPN 的输出结果。
候选框共享特征图特征,并保持输出大小一致。
候选框分为若干子区域,将每个区域对应到输入特征图上,取每个区域内的最大值作为该区域的输出。
在 ROI 映射中,涉及到 region proposal 的坐标映射变换问题,在这过程中难免会产生小数坐标。但是在 feature map 中的点相当于一个个的 pixel,是不存在小数的,因此会将小数坐标量化成向下取整,这就会造成一定的误差。
在 ROI Pooling 中,对每个 ROI 划分 grid 的时候又会有一次坐标量化向下取整。
这样,整个过程像素坐标会经过两次量化,导致 ROI 虽然在 feature map 上有不到 1 pixel 的误差,映射回原图后的误差可能会大于 10 pixel,甚至误差可能会大于整个物体,这对小物体的检测非常不友好。
Faster R-CNN 中通过 ROI Align 消除 RoI Pooling 中产生的误差。
ROI Align 的原理是,先将 ROI Project 和 ROI Pooling 时计算出的 ROI 带小数的坐标存储在内存中,不直接量化成像素坐标。
随后,ROI Align 不取每个 grid 的最大值,而是再将每个 grid 划分成 2×22×22\times2 的小格,在每个小格中找到中心点,将离中心点最近的四个点的值进行双线性差值,求得中心点的值,再取每个 gridgridgrid 中四个中心点的最大值作为 PoolingPoolingPooling 后的值。
下面是分类与回归的 BBox 头部分,它的处理流程展开后如下图所示:
而BBox训练阶段的样本构建方式如下,我们对比RPN阶段的样本构建方式:
BBox头的分类与回归任务的标签构建方式如下,其中分类分支是典型的分类问题,学习每个预测框的类别;回归分支则是学习每个 RoI 到真实框的偏移量。
BBox 头的总体 loss 由分类 loss 和回归 loss 加权组合构成。
Faster R-CNN的效果如下图所示
可以点击 B站 查看视频的【双语字幕】版本