内容来源:2018 年 04 月 21 日,AI教育求职平台景略集智创始人王文凯在“百度深度学习公开课·北京站:AI工程师的快速进阶之路”进行《目标检测面面观》演讲分享。IT 大咖说(微信id:itdakashuo)做为独家视频合做方,经主办方和讲者审阅受权发布。python
阅读字数:4339 | 11分钟阅读bash
本次演讲主要介绍视觉识别领域中目标检测的相关技术,对其中各类不一样的检测方法进行解析和对比。微信
最简单的视觉识别是根据图片中的物体对图片进行分类,典型的就是判断一张照片是猫仍是狗。再进一步不只要识别图片中物体,还要对它进行定位。网络
实际工程中,图片通常会同时存在多个物体,面对这种复杂场景须要应用目标检测,同时包含分类和定位。比目标检测更深刻的是语义分割,从上图能够看到目标检测只是简单的框出了物体,而语义分析会挖掘出图像中更深层次的信息。框架
对分类领域稍有熟悉的朋友可能都知道MNIST(手写数字)数据集,它被称为DeepLearning中的hello world,主流的深度学习框架都会提供该数据集的相应的接口。ide
上图左边是人眼所看到的图像,在计算机中被转化成了右方这样的矩阵,0表示的是0像素,中间的数字表示颜色由浅到深的过渡。函数
对于上面图片的分类,首先会将图片以像素为单位拆解成特征向量输入到神经网络中,而后输出猜想——长度为10的向量。这种方法是将二维矩阵展开为一维向量,过程当中必然会损失必定的信息。因此在深度学习领域更常见的作法是使用卷积神经网络。性能
这里输入的一样是数字图片,输出为10维度向量。不过中间部分有些不一样,它是由convolution、subsampling、Pooling构成,核心在于convolution(卷积)。学习
任意的图片均可以被转换为矩阵,图中中间部分的3*3的小矩阵被称为卷积核。咱们会将卷积核放到图片矩阵中滑动,重叠部分一样也是一个3*3的矩阵,对他们进行计算后会获得一个结果,计算公式为对应像素位置的值相乘而后求和。ui
不一样的卷积核对应不一样的特征,如图中动物图片的卷积核取值,中间是8,周围是-1,这表示一个边缘检测。在通过滑动计算后展示的就是右边的feature map(特征映射),能够看到原图中的边缘区域都被高亮了,总体图片虽然变成了黑白的,可是信息对比更增强烈。
Pooling是在获得特征映射后进一步对信息进行简约化处理,如上图对某个特征映射作2*2的切分,每4个点取一个最大值,减少网络中的计算量只保留最主要的特征信息。ReLu叫作整流线性单元,它是一个激活函数,小于0的时候值一直为0,大于0的时候恢复正常。
卷积神经网络衍生出过不少不一样的版本,VGG16就是其中之一 ,它被不少的目标检测方案用做特征提取。VGG16接收的输入图片尺寸是224*224。图中黑色方块为一个卷积层,后面接着激活函数,红色块是石化层。卷积核获得的特征映射会逐渐缩小,越日后特征映射的点对应的原图区域越大。
VGG16一共有16个带有权重的层,其中13个卷积层和3个全连接层,咱们能够将卷积核、激活函数、石化层视为一个block模块。VGG16的整个网络有138M个参数。
import paddle.v2 as pal
pdl.networks.vgg_16_network(input_image, num_channels,num_classes=1000)复制代码
这样庞大的网络,使用上图的方法是最简单的。这是一段python代码,经过导入pdI模块使用VGG16网络,仅用输入3个参数,输入的图片、通道数、分类数。不过仅用这种方式确定是没法知足大多数状况。
import paddle.v2 as pal
def vgg16(input):
def conv_block(ipc, num_filter, groups, dropouts, num_channels=None):
return pdl.networks.img_conv_group(input=ipt, num_channels=num_channels,
pool_type=pdl.pooling.Max(), pool_size=2, pool_stride=2,
conv_num_filter=[num_filter]*groups, conv_filter_size=3,
conv_act=pdl.activation.Rolu(), conv_with_batchnorm=True,
conv_batchnorm_drop_rate=dropouts)
conv1 = conv_block(input, 64, 2, [0.3, 0], 3)
conv2 = conv_block(input, 128, 2, [0.4, 0])
conv3 = conv_block(input, 256, 3, [0.4, 0])
conv4 = conv_block(input, 512, 3, [0.4, 0.4, 0])
conv5 = conv_block(input, 512, 3, [0.4, 0.4, 0])
fc1 = pdl.layer.fc(input=conv5, size=4096, act=pdl.activation.Linear())
fc2 = pdl.layer.fc(input=fc1, size=4096, act=pdl.activation.Linear())
fc3 = pdl.layer.fc(input=fc2, size=1000, act=pdl.activation.Linear())复制代码
这是另外一种稍显复杂的写法,下方定义了5个卷积层和3个全连接层。它的好处在于整个模块都是咱们自定义的,能够随时进行修改。
前面提到过VGG16网络有138M个参数,若是每一个视觉分类的任务都须要从新训练,整个任务规模仍是很是大的。因此经常使用的作法是基于ImageNet数据集,它有1000类,共1400万张图片。通常咱们会使用数据集中那些已经被训练好参数来作。
Object Detection目标检测须要用到PASCAL VOC数据集,它只有20个类别,虽然相对ImageNet要少不少,可是每张图片的信息更为丰富。
实现目标检测最简单暴力的方法是使用滑动窗口,如上图让绿色窗口在图片上不断滑动。不过因为没法肯定窗口的大小是否匹配要检测的物体,因此要不断的缩放图片来进行匹配,同时线框的形状也要进行调整,这无疑增大了复杂度。
Region Proposal会帮咱们限制图像搜索的空间。它首先假设图上的每一个点为独立集团,而后根据颜色、纹理、尺寸、包含关系等进行合并。
好比这张图,最初有很是多的点,以后随着不断合并造成了几个大的集团,下方的线框也就仅剩几个了,最后再进行分类。这样的话计算性能有了很大的提高。
在经过提名方式大体猜想出图片中物体种类后,接下来要作的就是对这些块进行分类。这要用到卷积神经网络,更具体的是Region based CNN。输入图片后提取出region proposals,而后将这些region proposals图片缩放成统一大小的正方形输入到CNN中,最后CNN会给出分类结果。
R-CNN训练过程当中,首先会在ImageNet上训练卷积部分提取物体特征的能力,在嫁接到PASCAL以前还要对网络进行改造,让它只输入21类,多出的1类为背景。这种对神经网络的改造,用到就是前面展现的相对复杂的代码。
R-CNN针对每张图片可能会提取出2000多个region proposals,而对这些region proposals都须要作一遍卷积操做,计算量无形中增大了2000倍,显然会拖慢运行效率。
为此如今又提出了Fast R-CNN。咱们知道图片通过卷积以后获得的特征映射,虽然信息量下降了,可是保留下了分类相关的信息。所以region proposals就彻底能够不在原图上进行,而在特征映射上完成。原先要将图片切成多份,每份单独进行一次卷积提取特征。如今只须要先总体进行一次提取,而后在特征映射上作若干个区域提名。
Fast RCNN相对普通的RCNN速度虽有所提高,不过还能够进一步提升。咱们能够将生成Proposal的过程也经过神经网络完成,至关于神经网络中又嵌套着一层神经网络,使整个过程所有经过GPU加速,这种方式被称为Faster RCNN。
Faster RCNN整个流程分为两个分支,一部分是区域提名,另外一部分是特征提取以及位置分类的计算,一次任务要走两步。所以虽然在静态图片识别上Faster RCNN能很好的完成任务,可是还不知足在视频领域实时图像的识别。
因此又出现了一种新的方法——You Only Look Once。它先对图片作固定数量切分,在此基础上进行各类猜想,而后对这些猜想框进行分类以及四个角的回归,使回归和分类就融合到同一个神经网络中,实现端到端的训练。
这类将区域提名以及位置和分类合并到一块儿的方法被称为single shot,上图是Single Shot的另外一种方式multi-box detector的结构图。multi-box detector也用到了VGG16,不过仅有前三个conv_block,剔除了全连接层,原先的FC六、FC7又添加了新的卷积。能够看到其中有若干个卷积块链接到了最后的detections,也就是在不一样尺度的特征映射上都进行一次物体猜想,这样精度会稍有提升,对于尺度变化较大的物体也能起到较好的效果。
前面提到的这些方法其本质都是在效率和功率上寻找折中,上图是对一些经典方法的总结,横轴是速度,纵轴是MVP。能够看到single shot类的方法明显要更快一些,不过它的实时性是基于牺牲必定的精度。