go语言深度学习目标检测,go语言自动化测试
Halcon deep learning之目标检测笔记(二)
在上一步,完成了网络的创建和数据的预处理。接下来准备对这个网络进行训练,通过训练得到一个可以用于目标检测的深度学习网络模型。这里首先要确定上一步输出的模型和数据集的存放路径是可用的,否则训练环节会因为缺少输入而报错。
创新互联专业成都做网站、成都网站建设、成都外贸网站建设,集网站策划、网站设计、网站制作于一体,网站seo、网站优化、网站营销、软文推广等专业人才根据搜索规律编程设计,让网站在运行后,在搜索中有好的表现,专业设计制作为您带来效益的网站!让网站建设为您创造效益。
Halcon的参考样例detect_pills_deep_learning_2_train.hdev详述了这一过程,这里做一些学习记录。
设置输入路径,主要是两个,一是上一步的预训练的以.hdl结尾的模型,另一个是数据集和样本数据字典的存放路径。
输出路径也是两个,一是存放最佳评估模型的路径,一个是最终训练完成的模型路径。
首先用check_files_availability验证预处理模型和数据集路径是否正确。没有问题的话可以开始读取。
使用read_dl_model读取前一步初始化后的网络模型,得到模型的句柄DLModelHandle。
接着用read_dict读取预处理后的数据集,得到数据字典句柄DLDataset。
设置模型参数主要通过set_dl_model_param算子,以修改属性值的方式改变关键参数的值。该算子原型如下:
set_dl_model_param( : : DLModelHandle, GenParamName, GenParamValue : )
输入三个参数:
注意,如果将'runtime'的值改为了’gpu’,则要确定cuDNN和cuBLAS已经成功安装了。
通过set_dl_model_param算子,可以将本文开头提到的设置的模型的基本参数传递给模型句柄DLModelHandle。如将'batch_size'设为之前的batch_size的值等等。
1)创建训练参数。
这里使用create_dl_train_param算子创建一个训练参数的字典,用于存放训练参数和训练效果可视化的参数。这些参数可以做个说明:
2)训练网络
接下来是最耗时的部分,即使用train_dl_model算子进行深度学习网络模型的训练。算子如下:
train_dl_model( : : DLDataset, DLModelHandle, TrainParam, StartEpoch : TrainResults, TrainInfos,EvaluationInfos)
前四个参数是输入参数,后三个是输出参数。
接着到了第三步,即验证模型的部分。
目标检测算法(R-CNN,fast R-CNN,faster R-CNN,yolo,SSD,yoloV2,yoloV3)
深度学习目前已经应用到了各个领域,应用场景大体分为三类:物体识别,目标检测,自然语言处理。 目标检测可以理解为是物体识别和物体定位的综合 ,不仅仅要识别出物体属于哪个分类,更重要的是得到物体在图片中的具体位置。
2014年R-CNN算法被提出,基本奠定了two-stage方式在目标检测领域的应用。它的算法结构如下图
算法步骤如下:
R-CNN较传统的目标检测算法获得了50%的性能提升,在使用VGG-16模型作为物体识别模型情况下,在voc2007数据集上可以取得66%的准确率,已经算还不错的一个成绩了。其最大的问题是速度很慢,内存占用量很大,主要原因有两个
针对R-CNN的部分问题,2015年微软提出了Fast R-CNN算法,它主要优化了两个问题。
R-CNN和fast R-CNN均存在一个问题,那就是 由选择性搜索来生成候选框,这个算法很慢 。而且R-CNN中生成的2000个左右的候选框全部需要经过一次卷积神经网络,也就是需要经过2000次左右的CNN网络,这个是十分耗时的(fast R-CNN已经做了改进,只需要对整图经过一次CNN网络)。这也是导致这两个算法检测速度较慢的最主要原因。
faster R-CNN 针对这个问题, 提出了RPN网络来进行候选框的获取,从而摆脱了选择性搜索算法,也只需要一次卷积层操作,从而大大提高了识别速度 。这个算法十分复杂,我们会详细分析。它的基本结构如下图
主要分为四个步骤:
使用VGG-16卷积模型的网络结构:
卷积层采用的VGG-16模型,先将PxQ的原始图片,缩放裁剪为MxN的图片,然后经过13个conv-relu层,其中会穿插4个max-pooling层。所有的卷积的kernel都是3x3的,padding为1,stride为1。pooling层kernel为2x2, padding为0,stride为2。
MxN的图片,经过卷积层后,变为了(M/16) x (N/16)的feature map了。
faster R-CNN抛弃了R-CNN中的选择性搜索(selective search)方法,使用RPN层来生成候选框,能极大的提升候选框的生成速度。RPN层先经过3x3的卷积运算,然后分为两路。一路用来判断候选框是前景还是背景,它先reshape成一维向量,然后softmax来判断是前景还是背景,然后reshape恢复为二维feature map。另一路用来确定候选框的位置,通过bounding box regression实现,后面再详细讲。两路计算结束后,挑选出前景候选框(因为物体在前景中),并利用计算得到的候选框位置,得到我们感兴趣的特征子图proposal。
卷积层提取原始图像信息,得到了256个feature map,经过RPN层的3x3卷积后,仍然为256个feature map。但是每个点融合了周围3x3的空间信息。对每个feature map上的一个点,生成k个anchor(k默认为9)。anchor分为前景和背景两类(我们先不去管它具体是飞机还是汽车,只用区分它是前景还是背景即可)。anchor有[x,y,w,h]四个坐标偏移量,x,y表示中心点坐标,w和h表示宽度和高度。这样,对于feature map上的每个点,就得到了k个大小形状各不相同的选区region。
对于生成的anchors,我们首先要判断它是前景还是背景。由于感兴趣的物体位于前景中,故经过这一步之后,我们就可以舍弃背景anchors了。大部分的anchors都是属于背景,故这一步可以筛选掉很多无用的anchor,从而减少全连接层的计算量。
对于经过了3x3的卷积后得到的256个feature map,先经过1x1的卷积,变换为18个feature map。然后reshape为一维向量,经过softmax判断是前景还是背景。此处reshape的唯一作用就是让数据可以进行softmax计算。然后输出识别得到的前景anchors。
另一路用来确定候选框的位置,也就是anchors的[x,y,w,h]坐标值。如下图所示,红色代表我们当前的选区,绿色代表真实的选区。虽然我们当前的选取能够大概框选出飞机,但离绿色的真实位置和形状还是有很大差别,故需要对生成的anchors进行调整。这个过程我们称为bounding box regression。
假设红色框的坐标为[x,y,w,h], 绿色框,也就是目标框的坐标为[Gx, Gy,Gw,Gh], 我们要建立一个变换,使得[x,y,w,h]能够变为[Gx, Gy,Gw,Gh]。最简单的思路是,先做平移,使得中心点接近,然后进行缩放,使得w和h接近。如下:
我们要学习的就是dx dy dw dh这四个变换。由于是线性变换,我们可以用线性回归来建模。设定loss和优化方法后,就可以利用深度学习进行训练,并得到模型了。对于空间位置loss,我们一般采用均方差算法,而不是交叉熵(交叉熵使用在分类预测中)。优化方法可以采用自适应梯度下降算法Adam。
得到了前景anchors,并确定了他们的位置和形状后,我们就可以输出前景的特征子图proposal了。步骤如下:
1,得到前景anchors和他们的[x y w h]坐标。
2,按照anchors为前景的不同概率,从大到小排序,选取前pre_nms_topN个anchors,比如前6000个
3,剔除非常小的anchors。
4,通过NMS非极大值抑制,从anchors中找出置信度较高的。这个主要是为了解决选取交叠问题。首先计算每一个选区面积,然后根据他们在softmax中的score(也就是是否为前景的概率)进行排序,将score最大的选区放入队列中。接下来,计算其余选区与当前最大score选区的IOU(IOU为两box交集面积除以两box并集面积,它衡量了两个box之间重叠程度)。去除IOU大于设定阈值的选区。这样就解决了选区重叠问题。
5,选取前post_nms_topN个结果作为最终选区proposal进行输出,比如300个。
经过这一步之后,物体定位应该就基本结束了,剩下的就是物体识别了。
和fast R-CNN中类似,这一层主要解决之前得到的proposal大小形状各不相同,导致没法做全连接。全连接计算只能对确定的shape进行运算,故必须使proposal大小形状变为相同。通过裁剪和缩放的手段,可以解决这个问题,但会带来信息丢失和图片形变问题。我们使用ROI pooling可以有效的解决这个问题。
ROI pooling中,如果目标输出为MxN,则在水平和竖直方向上,将输入proposal划分为MxN份,每一份取最大值,从而得到MxN的输出特征图。
ROI Pooling层后的特征图,通过全连接层与softmax,就可以计算属于哪个具体类别,比如人,狗,飞机,并可以得到cls_prob概率向量。同时再次利用bounding box regression精细调整proposal位置,得到bbox_pred,用于回归更加精确的目标检测框。
这样就完成了faster R-CNN的整个过程了。算法还是相当复杂的,对于每个细节需要反复理解。faster R-CNN使用resNet101模型作为卷积层,在voc2012数据集上可以达到83.8%的准确率,超过yolo ssd和yoloV2。其最大的问题是速度偏慢,每秒只能处理5帧,达不到实时性要求。
针对于two-stage目标检测算法普遍存在的运算速度慢的缺点, yolo创造性的提出了one-stage。也就是将物体分类和物体定位在一个步骤中完成。 yolo直接在输出层回归bounding box的位置和bounding box所属类别,从而实现one-stage。通过这种方式, yolo可实现45帧每秒的运算速度,完全能满足实时性要求 (达到24帧每秒,人眼就认为是连续的)。它的网络结构如下图:
主要分为三个部分:卷积层,目标检测层,NMS筛选层。
采用Google inceptionV1网络,对应到上图中的第一个阶段,共20层。这一层主要是进行特征提取,从而提高模型泛化能力。但作者对inceptionV1进行了改造,他没有使用inception module结构,而是用一个1x1的卷积,并联一个3x3的卷积来替代。(可以认为只使用了inception module中的一个分支,应该是为了简化网络结构)
先经过4个卷积层和2个全连接层,最后生成7x7x30的输出。先经过4个卷积层的目的是为了提高模型泛化能力。yolo将一副448x448的原图分割成了7x7个网格,每个网格要预测两个bounding box的坐标(x,y,w,h)和box内包含物体的置信度confidence,以及物体属于20类别中每一类的概率(yolo的训练数据为voc2012,它是一个20分类的数据集)。所以一个网格对应的参数为(4x2+2+20) = 30。如下图
其中前一项表示有无人工标记的物体落入了网格内,如果有则为1,否则为0。第二项代表bounding box和真实标记的box之间的重合度。它等于两个box面积交集,除以面积并集。值越大则box越接近真实位置。
分类信息: yolo的目标训练集为voc2012,它是一个20分类的目标检测数据集 。常用目标检测数据集如下表:
| Name | # Images (trainval) | # Classes | Last updated |
| --------------- | ------------------- | --------- | ------------ |
| ImageNet | 450k | 200 | 2015 |
| COCO | 120K | 90 | 2014 |
| Pascal VOC | 12k | 20 | 2012 |
| Oxford-IIIT Pet | 7K | 37 | 2012 |
| KITTI Vision | 7K | 3 | |
每个网格还需要预测它属于20分类中每一个类别的概率。分类信息是针对每个网格的,而不是bounding box。故只需要20个,而不是40个。而confidence则是针对bounding box的,它只表示box内是否有物体,而不需要预测物体是20分类中的哪一个,故只需要2个参数。虽然分类信息和confidence都是概率,但表达含义完全不同。
筛选层是为了在多个结果中(多个bounding box)筛选出最合适的几个,这个方法和faster R-CNN 中基本相同。都是先过滤掉score低于阈值的box,对剩下的box进行NMS非极大值抑制,去除掉重叠度比较高的box(NMS具体算法可以回顾上面faster R-CNN小节)。这样就得到了最终的最合适的几个box和他们的类别。
yolo的损失函数包含三部分,位置误差,confidence误差,分类误差。具体公式如下:
误差均采用了均方差算法,其实我认为,位置误差应该采用均方差算法,而分类误差应该采用交叉熵。由于物体位置只有4个参数,而类别有20个参数,他们的累加和不同。如果赋予相同的权重,显然不合理。故yolo中位置误差权重为5,类别误差权重为1。由于我们不是特别关心不包含物体的bounding box,故赋予不包含物体的box的置信度confidence误差的权重为0.5,包含物体的权重则为1。
Faster R-CNN准确率mAP较高,漏检率recall较低,但速度较慢。而yolo则相反,速度快,但准确率和漏检率不尽人意。SSD综合了他们的优缺点,对输入300x300的图像,在voc2007数据集上test,能够达到58 帧每秒( Titan X 的 GPU ),72.1%的mAP。
SSD网络结构如下图:
和yolo一样,也分为三部分:卷积层,目标检测层和NMS筛选层
SSD论文采用了VGG16的基础网络,其实这也是几乎所有目标检测神经网络的惯用方法。先用一个CNN网络来提取特征,然后再进行后续的目标定位和目标分类识别。
这一层由5个卷积层和一个平均池化层组成。去掉了最后的全连接层。SSD认为目标检测中的物体,只与周围信息相关,它的感受野不是全局的,故没必要也不应该做全连接。SSD的特点如下。
每一个卷积层,都会输出不同大小感受野的feature map。在这些不同尺度的feature map上,进行目标位置和类别的训练和预测,从而达到 多尺度检测 的目的,可以克服yolo对于宽高比不常见的物体,识别准确率较低的问题。而yolo中,只在最后一个卷积层上做目标位置和类别的训练和预测。这是SSD相对于yolo能提高准确率的一个关键所在。
如上所示,在每个卷积层上都会进行目标检测和分类,最后由NMS进行筛选,输出最终的结果。多尺度feature map上做目标检测,就相当于多了很多宽高比例的bounding box,可以大大提高泛化能力。
和faster R-CNN相似,SSD也提出了anchor的概念。卷积输出的feature map,每个点对应为原图的一个区域的中心点。以这个点为中心,构造出6个宽高比例不同,大小不同的anchor(SSD中称为default box)。每个anchor对应4个位置参数(x,y,w,h)和21个类别概率(voc训练集为20分类问题,在加上anchor是否为背景,共21分类)。如下图所示:
另外,在训练阶段,SSD将正负样本比例定位1:3。训练集给定了输入图像以及每个物体的真实区域(ground true box),将default box和真实box最接近的选为正样本。然后在剩下的default box中选择任意一个与真实box IOU大于0.5的,作为正样本。而其他的则作为负样本。由于绝大部分的box为负样本,会导致正负失衡,故根据每个box类别概率排序,使正负比例保持在1:3。SSD认为这个策略提高了4%的准确率
另外,SSD采用了数据增强。生成与目标物体真实box间IOU为0.1 0.3 0.5 0.7 0.9的patch,随机选取这些patch参与训练,并对他们进行随机水平翻转等操作。SSD认为这个策略提高了8.8%的准确率。
和yolo的筛选层基本一致,同样先过滤掉类别概率低于阈值的default box,再采用NMS非极大值抑制,筛掉重叠度较高的。只不过SSD综合了各个不同feature map上的目标检测输出的default box。
SSD基本已经可以满足我们手机端上实时物体检测需求了,TensorFlow在Android上的目标检测官方模型ssd_mobilenet_v1_android_export.pb,就是通过SSD算法实现的。它的基础卷积网络采用的是mobileNet,适合在终端上部署和运行。
针对yolo准确率不高,容易漏检,对长宽比不常见物体效果差等问题,结合SSD的特点,提出了yoloV2。它主要还是采用了yolo的网络结构,在其基础上做了一些优化和改进,如下
网络采用DarkNet-19:19层,里面包含了大量3x3卷积,同时借鉴inceptionV1,加入1x1卷积核全局平均池化层。结构如下
yolo和yoloV2只能识别20类物体,为了优化这个问题,提出了yolo9000,可以识别9000类物体。它在yoloV2基础上,进行了imageNet和coco的联合训练。这种方式充分利用imageNet可以识别1000类物体和coco可以进行目标位置检测的优点。当使用imageNet训练时,只更新物体分类相关的参数。而使用coco时,则更新全部所有参数。
YOLOv3可以说出来直接吊打一切图像检测算法。比同期的DSSD(反卷积SSD), FPN(feature pyramid networks)准确率更高或相仿,速度是其1/3.。
YOLOv3的改动主要有如下几点:
不过如果要求更精准的预测边框,采用COCO AP做评估标准的话,YOLO3在精确率上的表现就弱了一些。如下图所示。
当前目标检测模型算法也是层出不穷。在two-stage领域, 2017年Facebook提出了mask R-CNN 。CMU也提出了A-Fast-RCNN 算法,将对抗学习引入到目标检测领域。Face++也提出了Light-Head R-CNN,主要探讨了 R-CNN 如何在物体检测中平衡精确度和速度。
one-stage领域也是百花齐放,2017年首尔大学提出 R-SSD 算法,主要解决小尺寸物体检测效果差的问题。清华大学提出了 RON 算法,结合 two stage 名的方法和 one stage 方法的优势,更加关注多尺度对象定位和负空间样本挖掘问题。
目标检测领域的深度学习算法,需要进行目标定位和物体识别,算法相对来说还是很复杂的。当前各种新算法也是层不出穷,但模型之间有很强的延续性,大部分模型算法都是借鉴了前人的思想,站在巨人的肩膀上。我们需要知道经典模型的特点,这些tricks是为了解决什么问题,以及为什么解决了这些问题。这样才能举一反三,万变不离其宗。综合下来,目标检测领域主要的难点如下:
一文读懂目标检测AI算法:R-CNN,faster R-CNN,yolo,SSD,yoloV2
从YOLOv1到v3的进化之路
SSD-Tensorflow超详细解析【一】:加载模型对图片进行测试
YOLO
C#项目参考:
项目实践贴个图。
目标检测算法的分步介绍(第 1 部分)
英文原文:
对原文的表达有部分改动
在本文中,我们将更深入地研究可用于目标检测的各种算法。我们将从 RCNN 家族的算法开始,即 RCNN、Fast RCNN 和 Faster RCNN。在本系列即将发布的文章中,我们将介绍更高级的算法,如 YOLO、SSD 等。
下图是说明目标检测算法如何工作的一个流行示例。图像中的每个物体,从一个人到一只风筝,都以一定的精度被定位和识别。
让我们从最简单的深度学习方法开始,也是一种广泛使用的方法,用于检测图像中的目标——卷积神经网络( CNN)。CNN 的内部工作原理如下:
我们将图像传递给网络,然后通过各种卷积和池化层处理,发送给全连接层。最后,我们以目标类别的形式获得输出。这相当简单,不是吗?对于每个输入图像,我们得到一个相应的类作为输出。我们可以使用这种技术来检测图像中的各种目标吗?让我们看看如何使用 CNN 解决一般的目标检测问题。
使用这种方法的问题在于图像中的目标可能具有不同的纵横比和空间位置。例如,在某些情况下,目标可能覆盖图像的大部分,而在某些情况下,目标可能仅覆盖图像的一小部分。目标的形状也可能不同(在现实生活中经常发生)。由于这些因素,我们将需要大量的区域,从而导致大量的计算时间。因此,为了解决这个问题并减少区域数量,我们可以使用基于区域的 CNN,它使用提案法选择区域。让我们了解这个基于区域的 CNN 可以为我们做什么。
与在大量区域上工作不同的是,RCNN 算法是在图像中选取一堆框并检查这些框中是否有任何一个包含任何目标。 RCNN 使用 selective search 从图像中提取这些框(这些框称为 regions)。
让我们首先了解什么是 selective search 以及它如何识别不同的 regions。基本上四个模式可以构成一个物体:不同的尺度、颜色、纹理和外壳。selective search 识别图像中的这些模式,并在此基础上提出各种regions。以下是selective search 工作原理的简要概述:
举个例子:
到目前为止,我们已经看到了 RCNN 如何实现目标检测。但是这种技术有其自身的局限性。由于以下步骤,训练 RCNN 模型既昂贵又缓慢:
所有这些过程结合起来使 RCNN 非常慢。对每张新图像进行预测大约需要 40-50 秒,这实质上使得模型在面对庞大的数据集时变得笨重且几乎无法构建。
好消息是——我们有另一种目标检测技术,它修复了我们在 RCNN 中看到的大部分问题。
我们还能做些什么来减少 RCNN 算法通常需要的计算时间?我们是否可以每张图像只运行一次并获取所有感兴趣的区域(包含某个目标的区域)。
RCNN 的作者 Ross Girshick 提出了这个想法,即每张图像只运行一次 CNN,然后找到一种方法在 2,000 个区域之间共享该计算。在 Fast RCNN 中,我们将输入图像提供给 CNN,后者反过来生成卷积特征图。使用这些地图,提取提议的区域。然后我们使用 RoI 池化层将所有提议的区域重塑为固定大小,以便可以将其馈入全连接网络。
让我们将其分解为简化概念的步骤:
因此,Fast RCNN 不是使用三个不同的模型(如 RCNN),而是使用单个模型从区域中提取特征,将它们分成不同的类,并同时返回识别类的边界框。
为了进一步分解,我将对每个步骤进行可视化。
这就是 Fast RCNN 如何解决 RCNN 的两个主要问题,1. 将每个图像的一个而不是 2,000 个区域传递给 ConvNet。2. 使用一个而不是三个不同的模型来提取特征、分类和生成边界框。
但即使是 Fast RCNN 也存在某些问题。它还使用 selective search 作为寻找感兴趣区域的建议方法,这是一个缓慢且耗时的过程。每张图像检测目标大约需要 2 秒,这与 RCNN 相比要好得多。但是当我们考虑大型现实生活数据集时,即使是 Fast RCNN 看起来也不那么快了。
Faster RCNN 是 Fast RCNN 的修改版本。它们之间的主要区别在于 Fast RCNN 使用 selective search 来生成感兴趣的区域,而 Faster RCNN 使用 Region Proposal Network ,又名 RPN。 RPN 将图像特征图作为输入并生成一组目标提议,每个提议的目标以分数作为输出。
Faster RCNN 方法通常遵循以下步骤:
让我简要解释一下这个区域提议网络(RPN)实际上是如何工作的。
首先,Faster RCNN 从 CNN 获取特征图并将它们传递给区域提议网络。 RPN 在这些特征图上使用一个滑动窗口,在每个窗口,它生成 k 个不同形状和大小的 Anchor 框:
Anchor 框是固定大小的边界框,它们放置在整个图像中,具有不同的形状和大小。对于每个 Anchor,RPN 预测两件事:
我们现在有不同形状和大小的边界框,它们被传递到 RoI 池化层。在 RPN 步骤之后,有可能存在没有分配给它们的类别提议。我们可以获取每个建议并对其进行裁剪,以便每个建议都包含一个目标。这就是 RoI 池化层所做的。它为每个锚点提取固定大小的特征图:
然后将这些特征图传递到具有 softmax 和线性回归层的全连接层。它最终对目标进行分类并预测已识别目标的边界框。
到目前为止,我们讨论的所有目标检测算法都使用区域来识别目标。网络不会一次性查看完整图像,而是依次关注图像的各个部分。这会造成两个并发症:
计算机视觉——典型的目标检测算法(OverFeat算法)(二)
【嵌牛导读】目标检测在现实中的应用很广泛,我们需要检测数字图像中的物体位置以及类别,它需要我们构建一个模型,模型的输入一张图片,模型的输出需要圈出图片中所有物体的位置以及物体所属的类别。在深度学习浪潮到来之前,目标检测精度的进步十分缓慢,靠传统依靠手工特征的方法来提高精度已是相当困难的事。而ImageNet分类大赛出现的卷积神经网络(CNN)——AlexNet所展现的强大性能,吸引着学者们将CNN迁移到了其他的任务,这也包括着目标检测任务,近年来,出现了很多目标检测算法。
【嵌牛鼻子】计算机视觉
【嵌牛提问】如何理解目标检测算法——OverFeat
【嵌牛正文】
一、深度学习的典型目标检测算法
深度学习目标检测算法主要分为 双阶段检测算法 和 单阶段检测算法 ,如图1所示。
双阶段目标检测算法先对图像提取候选框,然后基于候选区域做二次修正得到检测结果,检测精度较高,但检测速度较慢;单阶段目标验测算法直接对图像进行计算生成检测结果,检测速度快,但检测精度低。
1、双阶段目标检测算法
双阶段目标检测方法主要通过选择性搜索(Selective Search)或者Edge Boxes等算法对输入图像选取可能包含检测目标的候选区域(Region Proposal),再对候选区域进行分类和位置回归以得到检测结果。
1.1 OverFeat 算法
《OverFeat: Integrated Recognition, Localization and Detection using Convolutional Networks》
Sermanet 等改进AlexNet 提出 OverFeat 算法。该算法结合AlexNet通过多尺度滑动窗口实现特征提取功能,并且共享特征提取层,应用于图像分类、定位和目标检测等任务。
关键技术:
1、FCN( 全卷积神经网络 )
对于一个各层参数结构都设计好的网络模型,要求输入图片的尺寸是固定的(例如,Alexnet要求输入图片的尺寸为227px*227px)。如果输入一张500*500的图片,希望模型仍然可以一直前向传导,即一个已经设计完毕的网络,可以输入任意大小的图片,这就是FCN。
FCN的思想在于:
1、从卷积层到全连接层,看成是对一整张图片的卷积层运算。
2、从全连接层到全连接层,看成是采用1*1大小的卷积核,进行卷积层运算。
如上图所示,绿色部分代表卷积核大小。假设一个CNN模型,其输入图片大小是14*14,通过第一层卷积后得到10*10大小的图片,然后接着通过池化得到了5*5大小的图片。像但是对于像素值为5*5的图片到像素值为1*1的图片的过程中:
(1)传统的CNN:如果从以前的角度进行理解的话,那么这个过程就是全连接层,我们会把这个5*5大小的图片,展平成为一维向量进行计算。
(2)FCN:FCN并不是把5*5的图片展平成一维向量再进行计算,而是直接采用5*5的卷积核,对一整张图片进行卷积运算。
二者本质上是相同的,只是角度不同,FCN把这个过程当成了对一整张特征图进行卷积,同样,后面的全连接层也是把它当做是以1*1大小的卷积核进行卷积运算。
当输入一张任意大小的图片,就需要利用以上所述的网络,例如输入一张像素为16*16的图片:
根据上图,该网络最后的输出是一张2*2的图片。可见采用FCN网络可以输入任意大小的图片。同时需要注意的是网络最后输出的图片大小不在是一个1*1大小的图片,而是一个与输入图片大小息息相关的一张图片。
Overfeat就是把采用FCN的思想把全连接层看成了卷积层,在网络测试阶段可以输入任意大小的图片。
2、offset max-pooling
简单起见,不用二维的图像作为例子,而是采用一维作为示例:
如上图所示,在X轴上有20个神经元,并且选择池化size=3的非重叠池化,那么根据之前所学的方法应该是:对上面的20个神经元,从1位置开始进行分组,每3个连续的神经元为一组,然后计算每组的最大值(最大池化),19、20号神经元将被丢弃,如下图所示:
或者可以在20号神经元后面,添加一个数值为0的神经元编号21,与19、20成为一组,这样可以分成7组:[1,2,3],[4,5,6]……,
[16,17,18],[19,20,21],最后计算每组的最大值。
如果只分6组,除了以1作为初始位置进行连续组合之外,也可以从位置2或者3开始进行组合。也就是说其实有3种池化组合方法:
A、△=0分组:[1,2,3],[4,5,6]……,[16,17,18];
B、△=1分组:[2,3,4],[5,6,7]……,[17,18,19];
C、△=2分组:[3,4,5],[6,7,8]……,[18,19,20];
对应图片如下:
以往的CNN中,一般只用△=0的情况,得到池化结果后,就送入了下一层。但是该文献的方法是,把上面的△=0、△=1、△=2的三种组合方式的池化结果,分别送入网络的下一层。这样的话,网络在最后输出的时候,就会出现3种预测结果了。
前面所述是一维的情况,如果是2维图片的话,那么(△x,△y)就会有9种取值情况(3*3);如果我们在做图片分类的时候,在网络的某一个池化层加入了这种offset 池化方法,然后把这9种池化结果,分别送入后面的网络层,最后的图片分类输出结果就可以得到9个预测结果(每个类别都可以得到9种概率值,然后我们对每个类别的9种概率,取其最大值,做为此类别的预测概率值)。
算法原理:
文献中的算法,就是把这两种思想结合起来,形成了文献最后测试阶段的算法。
1、论文的网络架构与训练阶段
(1)网络架构
对于网络的结构,文献给出了两个版本——快速版、精确版,一个精度比较高但速度慢;另外一个精度虽然低但是速度快。下面是高精度版本的网络结构表相关参数:
表格参数说明:
网络输入:图片大小为221px*221px;
网络结构方面基本上和AlexNet相同,使用了ReLU激活,最大池化。不同之处在于:(a)作者没有使用局部响应归一化层;(b)然后也没有采用重叠池化的方法;(c)在第一层卷积层,stride作者是选择了2,这个与AlexNet不同(AlexNet选择的跨步是4,在网络中,如果stride选择比较大得话,虽然可以减少网络层数,提高速度,但是却会降低精度)。
需要注意的是把f7这一层,看成是卷积核大小为5*5的卷积层,总之就是需要把网络看成前面所述的FCN模型,去除了全连接层的概念,因为在测试阶段可不是仅仅输入221*221这样大小的图片,在测试阶段要输入各种大小的图片,具体请看后面测试阶段的讲解。
(2)网络训练
训练输入:对于每张原图片为256*256,然后进行随机裁剪为221*221的大小作为CNN输入,进行训练。
优化求解参数设置:训练的min-batchs选择128,权重初始化选择高斯分布的随机初始化:
然后采用随机梯度下降法,进行优化更新,动量项参数大小选择0.6,L2权重衰减系数大小选择10-5次方。学习率初始化值为0.05,根据迭代次数的增加,每隔几十次的迭代后,就把学习率的大小减小一半。
然后就是DropOut,这个只有在最后的两个全连接层,才采用dropout,dropout比率选择0.5。
2、网络测试阶段
在Alexnet的文献中,预测方法是输入一张图片256*256,然后进行multi-view裁剪,也就是从图片的四个角进行裁剪,还有就是一图片的中心进行裁剪,这样可以裁剪到5张224*224的图片。然后把原图片水平翻转一下,再用同样的方式进行裁剪,又可以裁剪到5张图片。把这10张图片作为输入,分别进行预测分类,在后在softmax的最后一层,求取个各类的总概率,求取平均值。
然而Alexnet这种预测方法存在两个问题:
一方面这样的裁剪方式,把图片的很多区域都给忽略了,这样的裁剪方式,刚好把图片物体的一部分给裁剪掉了;
另一方面,裁剪窗口重叠存在很多冗余的计算,像上面要分别把10张图片送入网络,可见测试阶段的计算量还是较大的。
Overfeat算法:
训练完上面所说的网络之后,在测试阶段不再是用一张221*221大小的图片了作为网络的输入,而是用了6张大小都不相同的图片,也就是所谓的多尺度输入预测,如下表格所示:
当网络前向传导到layer 5的时候,就利用了前面所述的FCN、offset pooling这两种思想的相结合。现以输入一张图片为例(6张图片的计算方法都相同),讲解layer 5后面的整体过程,具体流程示意图如下:
步骤一:
对于某个尺度的图片,经过前五层的卷积后得到特征图。上图中特征图的分辨率是20x23,256个通道。
步骤二:
对于该特征图,重复多次使用非重叠的池化,每次池化的偏置不同,有行偏置和列偏置。上图中偏置池化3次,偏置分别为为(0,1,2)。这就是offset pooling,也被称为fine stride。offset pooling得到的特征图的维度为6x7x3x3xD,其中6x7是特征图的分辨率,3x3是偏置池化的次数,D是通道数。上图中是以1维显示的。
步骤三:
池化后得到的特征图将被送入分类器。
步骤四:
分类器的输入是的5x5xD,输出是C(类别数)维向量。但是offset pooling后得到的特征图并不是5x5xD,比如上图中的特征图大小为6x7xD,因此分类器以滑动窗口的方式应用在特征图上,每个滑动窗口经过分类器输出一个C维向量。比如上图中输入的6x7xD的特征图最终得到2x3xC的输出,其中2x3是滑动窗口的个数。
步骤五:
而2x3xC只是一组偏置池化的输出,总的输出为2x3x3x3xC,将输出的张量reshape,得到6x9xC输出张量。最终输出分类张量为3d张量,即两个分辨率维度 x C维。
然后需要在后面把它们拉成一维向量,这样在一个尺度上,可以得到一个C*N个预测值矩阵,每一列就表示图片属于某一类别的概率值,并且求取每一列的最大值,作为本尺度的每个类别的概率值。
最后一共用了6种不同尺度(文献使用了12张,另外6张是水平翻转的图片)进行做预测,然后把这六种尺度结果再做一个平均,作为最最后的结果。
从上面过程可以看到整个网络分成两部分:layer 1~5这五层称之为特征提取层;layer 6~output称之为分类层。
六、定位任务
用于定位任务的时候,就把分类层(上面的layer 6~output)给重新设计一下,把分类改成回归问题,然后在各种不同尺度上训练预测物体的bounding box。
目标检测-YOLOv3
传统的目标检测算法适用的场景有限,而且维护成本很大。深度学习方法应用于目标检测,不仅算法适应性好,还可以进行迁移学习,降低成本。
深度学习目标检测算法中,基于锚框(Anchor)的方法主要分为 一阶段 方法和 两阶段 方法。
两阶段 方法先对感兴趣的区域进行选择,然后进一步对候选框内做分类和回归,最终输出选择的框以及对应的分类。两阶段的模型有R-CNN系列,比如 R-CNN,Fast-RCNN,Faster-RCNN 等。两阶段模型的优点是精度高,但是速度及较慢。
一阶段 方法直接对anchor进行回归和分类,得到最终目标框和类别,算法有 YOLOv2,v3,SSD,RetinaNet 等。一阶段模型的推理速度较快,但是相对的精度会下降一些。
此外还有一些 anchor-free 的方法,包括基于关键点的检测算法以及基于中心检测算法等。
下面是一些基础概念和缩写:
BBox :Bounding Box 边界框
Anchor :锚框
RoI : Region of Interest 特定的感兴趣区域
Region Proposal : 候选区域
RPN : Region proposal network 提取候选区域的网络
IoU : Intersaction over Union (Area of Overlap/ Area of Union) 交并比,预测框的质量
mAP :mean average precision
NMS :non-maximum suppression 非极大值抑制
YOLO系列的模型在保有一定精度的基础上拥有很快的推理速度,在下面图中YOLOv3的推理速度远超其他模型,因此在实时监测领域中有很好的应用。
YOLO的名字来源于you only look once,从名字上就道出了YOLO的精髓。
YOLOv1将图像划分为S*S个网络,物体真实框的中心落在哪个网格上,哪个网格对应的锚框就负责检测物体。
每个网格会预测一个边界框以及对应的置信度,这里的置信度反映的是模型认为这个框里包含着物体的把握以及它预测到这个物体的精确程度。所以置信度就等于 。如果物体不存在,那么置信度应该等于零。
每个边界框会预测5个值 。(x,y)坐标表示框相对于网格单元边界的中心。 w,y是相对于整个图像预测宽度和高度。 最后,置信度预测表示预测框与任何真实框之间的IOU。
YOLOv2在v1的基础上进行了优化,骨干网络使用了DarkNet19,并且将输入图片给尺寸从224增大到448,并且将网络结构设为全卷积网络结构加上Batch Norm,使用了Kmeans聚类方法来计算anchor,引入了多尺度训练,使网络在训练过程中学习不同尺度的图像。不过待改进的地方有在小目标上召回率不高,靠近的群体目标检测效果不好,检测精度还有优化空间。
YOLOv3使用了更加深的骨干网络DarkNet53,同时加入了多尺度预测,在COCO数据集上聚类; 9中不同尺度的anchor,在分类上使用sigmoid激活函数,支持了目标的多分类。YOLOv3的优点是推理速度快,性价比高,通用性强;缺点是召回率较低,定位精度较差,对于靠近或者遮挡的群体、小物体的检测能力相对较弱。
YOLOv3在v1的基础上做了很多改动。
边界框预测
YOLOv3使用聚类预测到的边界框作为锚框。网络为边界框预测4个坐标值 ,如果单元格从图像的左上角偏移了 ,并且先验边界框的宽度和高度为 ,则预测如下图:
YOLOv3给每个边界框用逻辑回归预测一个objectness score,如果某个边界框和真实框重合度比其他都高,那么它的objectness score应该是1。而其他框虽然也与真实框有重叠,会被忽略掉。
类别预测
使用的是sigmoid函数,没有用softmax因为没必要。
不同尺度的预测
YOLOv3使用k-means聚类来确定bounding box priors,选择了9个clusters和3个scales,然后在整个scales上均匀分割clusters。在COCO数据集上,9个cluster分别为(10×13),(16×30),(33×23),(30×61),(62×45),(59×119),(116×90) ,(156×198),(373×326)。
特征提取
YOLOv3使用了Darknet-53,特点是加入了残差,比之前的网络更深了(有53层卷积层所以叫Darknet-53)。
借一张图看一下YOLOv3的整个流程:
每个输出分支上对应着三个尺寸的先验框(总共3 3=9种尺度)。经过32倍下采样的网格,每一个网格对应着输入图像上32 32的区域,适合检测尺寸较大的目标,而8倍下采样的网格适合检测尺寸小的目标。
输出特征的高度H和宽度W,相当于将图像划分为H*W个网格,而不是直接在图像上画网格。也就是说32倍下采样之后得到的 ,相当于在输入图像上划一个 的网格,每一个网格对应着输出特征图上的一个点。
特征图的C通道上表示预测框的信息,包括坐标信息 ,目标置信度,分类。
C=B*(1+4+class_num),B为特征图上分配的锚框个数。
损失函数有三个,分类损失,定位损失和objectness损失。分类使用sigmoid激活函数,loss是sigmoid cross entropy。定位损失在x,y上使用sigmoid函数和sigmoid cross entropy损失,在w,h上使用L1损失。objectness损失用的是sigmoid激活函数和sigmoid cross entropy损失。
对于与真实框重叠的框,三种损失都要计算
对于没有真实框重叠的框,只计算objectness(0);对于与真实框重叠但不是最匹配的框,忽略它们。
名称栏目:go语言深度学习目标检测,go语言自动化测试
新闻来源:http://scyanting.com/article/dseoccj.html