作者:黄星源、樊亮、陈桦、斯国一
深度学习的发展不仅突破了许多视觉难题,也加速了计算机视觉领域相关技术的进步。本文主要从CV数据处理、CV模型(CNN)、CV模型训练流程以及CV模型集成对计算机视觉的基础知识和基本环节进行了讲解。
https://tianchi.aliyun.com/competition/entrance/531795/information(阿里天池-零基础入门CV赛事)
五种数据读取方法
目前较为主流的Python图像库的基本使用方法:
1. matplotlib
matplotlib是Python的绘图库,在科学绘图领域被广泛使用。使用plt.imread()读取图片将其储存为一个RGB像素值矩阵,再进行处理。故其可以与opencv或pillow结合使用,只需要传入像素值矩阵,matplotlib便可以接手处理接下来想要完成的操作。
2. PIL(pillow)
PIL即Python Imaging Library,而pillow是PIL的一个分支。pillow提供了常见的图像读取和处理的操作,它比opencv更为轻巧,且可以与ipython notebook无缝集成。使用Image.open()读取图片储存为一个对象,并非是numpy矩阵。
3. OpenCV
OpenCV是一个跨平台的计算机视觉库,是今天介绍的所有图像库中最全面也最强大的库。使用cv2.imread()读取图片将其储存为一个BGR像素值矩阵,故若要结合使用matplotlib则要先进行转化。
4. skimage
skimage包是scikit-image SciKit (toolkit for SciPy) 的简称,它对scipy.ndimage进行了扩展,提供了更多的图片处理功能。skimage包由许多的子模块组成,各个子模块功能不同。使用io.imread()读取图片将其储存为一个RGB像素值矩阵。
Imageio是一个Python库,提供了一个简单的接口用于读取和写入各种图像数据,包括动画图像,视频,体积数据和科学格式。使用imageio.imread()读取图片将其储存为一个RGB像素值矩阵。
五种数据扩增技巧
在深度学习模型的训练过程中,数据扩增是必不可少的环节。现有深度学习的参数非常多,一般的模型可训练的参数量基本上都是万到百万级别,而训练集样本的数量很难有这么多,数据扩增可以扩展样本空间。
扩增一般不会改变标签;对于物体检测,数据扩增会改变物体坐标位置;对于图像分割,数数据扩增方法有很多:从颜色空间、尺度空间到样本空间,同时根据不同任务数据扩增都有相应的区别。对于图像分类,数据据扩增会改变像素标签。以torchvision.transforms为例,首先整体了解数据扩增的方法,包括:
1. 裁剪
2. 翻转和旋转
3. 随机遮挡
4. 图像变换
5. 对transforms操作,使数据增强更灵活
1. torchvision
pytorch官方提供的数据扩增库,提供了基本的数据扩增方法,可以无缝与torch进行集成;但数据扩增方法种类较少,且速度中等;
链接:https://github.com/pytorch/vision
2. imgaug
imgaug是常用的第三方数据扩增库,提供了多样的数据扩增方法,且组合起来非常方便,速度较快;
链接:https://github.com/aleju/imgaug
3. albumentations
是常用的第三方数据扩增库,提供了多样的数据扩增方法,对图像分类、语义分割、物体检测和关键点检测都支持,速度较快。
链接:https://albumentations.readthedocs.io
CNN原理
卷积神经网络(Convolutional Neural Network, CNN)是一类特殊的人工神经网络,是深度学习中重要的一个分支。CNN在很多领域都表现优异,精度和速度比传统计算学习算法高很多。特别是在计算机视觉领域,CNN是解决图像分类、图像检索、物体检测和语义分割的主流模型。
CNN每一层由众多的卷积核组成,每个卷积核对输入的像素进行卷积操作,得到下一次的输入。随着网络层的增加卷积核会逐渐扩大感受野,并缩减图像的尺寸。
卷积神经网络与普通神经网络非常相似,它们都由具有可学习的权重和偏置常量的神经元组成。每个神经元都接收一些输入,并做一些点积计算,输出是每个分类的分数,普通神经网络里的一些计算技巧到这里依旧适用。
两者的不同点在于,卷积神经网络默认输入是图像,可以让我们把特定的性质编码入网络结构,使我们的前馈函数更加有效率,并减少了大量参数。
1. 具有三维体积的神经元(3D volumes of neurons)
卷积神经网络利用输入图片的特点,把神经元设计成三个维度 :width, height, depth。比如输入的图片大小是 32 × 32 × 3 (rgb),那么输入神经元就也具有 32×32×3 的维度。下面是传统神经网络的示意图:
一个卷积神经网络由很多层组成,它们的输入是三维的,输出也是三维的,有的层有参数,有的层不需要参数。卷积神经网络的示意图如下:
2. 卷积神经网络结构
2.1 卷积层(Convolutional layer)
卷积神经网路中每层卷积层由若干卷积单元组成,每个卷积单元的参数都是通过反向传播算法优化得到的。卷积运算的目的是提取输入的不同特征,第一层卷积层可能只能提取一些低级的特征如边缘、线条和角等层级,更多层的网络能从低级特征中迭代提取更复杂的特征。
2.2 池化层(Pooling layer)
通常在卷积层之后会得到维度很大的特征,将特征切成几个区域,取其最大值或平均值,得到新的、维度较小的特征。
池化即下采样,目的是为了减少特征图。池化操作对每个深度切片独立,规模一般为 2*2,相对于卷积层进行卷积运算,池化层进行的运算一般有以下几种:
最常见的池化层是规模为2*2, 步幅为2,对输入的每个深度切片进行下采样。每个MAX操作对四个数进行,如下图所示:
池化操作将保存深度大小不变。如果池化层的输入单元大小不是二的整数倍,一般采取边缘补零(zero-padding)的方式补成2的倍数,然后再池化。
2.3 非线性激活函数
神经的非线性激活化函数,用于增加网络的非线性分割能力,一般用Relu函数。
2.4 全连接层( Fully-Connected layer)
完全连接层是一个传统的多层感知器,它在输出层使用 softmax 激活函数。把所有局部特征结合变成全局特征,用来计算最后每一类的得分。一个卷积神经网络各层应用实例:
CNN常见模型
1. 卷积神经网络基础:LeNet5
手写字体识别模型LeNet5诞生于1994年,是最早的卷积神经网络之一。LeNet5通过巧妙的设计,利用卷积、参数共享、池化等操作提取特征,避免了大量的计算成本,最后再使用全连接神经网络进行分类识别,这个网络也是最近大量神经网络架构的起点。
如下图所示为LeNet网络结构,总共有7层网络(不含输入层),2个卷积层、2个池化层、3个全连接层。
2. 卷积神经网络进阶
随着网络结构的发展,研究人员最初发现网络模型结构越深、网络参数越多模型的精度更优。比较典型的是AlexNet、VGG、InceptionV3和ResNet的发展脉络。
2012年,AlexNet横空出世。这个模型的名字来源于论文第一作者的姓名Alex Krizhevsky。AlexNet使用了8层卷积神经网络,并以很大的优势赢得了ImageNet 2012图像识别挑战赛。它首次证明了学习到的特征可以超越手工设计的特征,从而一举打破计算机视觉研究的现状。
与相对较小的LeNet相比,AlexNet包含8层变换,其中有5层卷积和2层全连接隐藏层,以及1个全连接输出层。AlexNet在LeNet的基础上增加了3个卷积层。但AlexNet作者对它们的卷积窗口、输出通道数和构造顺序均做了大量的调整。虽然AlexNet指明了深度卷积神经网络可以取得出色的结果,但并没有提供简单的规则以指导后来的研究者如何设计新的网络。
VGG,它的名字来源于论文作者所在的实验室Visual Geometry Group。VGG提出了可以通过重复使用简单的基础块来构建深度模型的思路。VGG16相比AlexNet的一个改进是采用连续的几个3x3的卷积核代替AlexNet中的较大卷积核(11x11,7x7,5x5) 。VGG16包含了16个隐藏层(13个卷积层和3个全连接层)。VGG的结构图如下:
在2014年的ImageNet图像识别挑战赛中,一个名叫GoogLeNet的网络结构大放异彩。它虽然在名字上向LeNet致敬,但在网络结构上已经很难看到LeNet的影子。GoogLeNet吸收了NiN中网络串联网络的思想,并在此基础上做了很大改进。在随后的几年里,研究人员对GoogLeNet进行了数次改进,本节将介绍这个模型系列的第一个版本。
Inception块GoogLeNet中的基础卷积块叫作Inception块,得名于同名电影《盗梦空间》(Inception)。与上一节的NiN块相比,这个基础块在结构上更加复杂。
深度学习的问题:深度CNN网络达到一定深度后再一味地增加层数并不能带来进一步地分类性能提高,反而会招致网络收敛变得更慢,准确率也变得更差。- - -残差块(Residual Block)恒等映射:
ResNet的前两层跟之前介绍的GoogLeNet中的一样:在输出通道数为64、步幅为2的7*7卷积层后接步幅为2的3*3的最大池化层。不同之处在于ResNet每个卷积层后增加的批量归一化层。ResNet-50网络结构如下:
在机器学习模型(特别是深度学习模型)的训练过程中,模型是非常容易过拟合的。深度学习模型在不断的训练过程中训练误差会逐渐降低,但测试误差的走势则不一定。
在模型的训练过程中,模型只能利用训练数据来进行训练,并不能接触到测试集上的样本,故需要构建验证数据集对模型进行验证。
过拟合与欠拟合
拟合(Fitting):就是说这个曲线能不能很好的描述某些样本,并且有比较好的泛化能力。
过拟合(Overfitting):模型把数据学习的太彻底,以至于把噪声数据的特征也学习到了,这样就会导致在后期测试的时候不能够很好地识别数据,即不能正确的分类,模型泛化能力太差。
欠拟合(UnderFitting):模型没有很好地捕捉到数据特征,不能够很好地拟合数据,或者是模型过于简单无法拟合或区分样本。
防止过拟合方法
左侧为全连接网络,右侧的网络以 0.5 的概率丢弃神经元。输出层并没有应用 Dropout
防止欠拟合方法
数据集划分
因为训练集和验证集是分开的,所以模型在验证集上面的精度在一定程度上可以反映模型的泛化能力。在划分验证集的时候,需要注意验证集的分布应该与测试集尽量保持一致,不然模型在验证集上的精度就失去了指导意义。
既然验证集这么重要,那么如何划分本地验证集呢。在一些比赛中,赛题方会给定验证集;如果赛题方没有给定验证集,那么参赛选手就需要从训练集中拆分一部分得到验证集。验证集的划分有如下几种方式:
这些划分方法是从数据划分方式的角度来讲的,在现有的数据比赛中一般采用留出法和交叉验证法。如果数据量比较大,留出法还是比较合适的。
训练神经网络的流程
1. 好好检查数据
训练神经网络的第一步是完全不接触任何神经网络代码,而是从彻底检查数据开始。此步骤至关重要。花时间去检查数据是一件比较重要的工作。因为数据中往往可能存在异常值,而且了解它们的分布可以有利于我们找到一个更好的模型。
2. 评估框架并得到一个并不完美的baseline
此阶段的提示和技巧:
3. 过度拟合
找到一个好的模型的方法有两个阶段:首先获得一个足够大的模型以使其可以过度拟合(即专注于训练损失),然后适当地对其进行正则化(放弃一些训练损失以提高验证损失)。
此阶段的一些提示和技巧:
4. 正则化
此阶段的一些提示和技巧:
5. 微调
此阶段的一些提示和技巧:
6. 进一步提高精确率
分类器(Classifier)
分类器是数据挖掘中对样本进行分类的方法的统称,包含决策树、逻辑回归、朴素贝叶斯、神经网络等算法。
分类器的构造和实施大体会经过以下几个步骤:
1. 决策树分类器
构造这个分类器不需要任何领域的知识,也不需要任何的参数设置。因此它特别适合于探测式的知识发现。此外,这个分类器还可以处理高维数据,而且采用的是类似于树这种形式,也特别直观和便于理解。因此,决策树是许多商业规则归纳系统的基础。
2. 朴素贝叶斯分类器
素贝叶斯分类器是假设数据样本特征完全独立,以贝叶斯定理为基础的简单概率分类器。
3. AdaBoost算法
AdaBoost算法的自适应在于前一个分类器产生的错误分类样本会被用来训练下一个分类器,从而提升分类准确率,但是对于噪声样本和异常样本比较敏感。
4. 支持向量机
支持向量机是用过构建一个或者多个高维的超平面来将样本数据进行划分,超平面即为样本之间的分类边界。
5. K近邻算法
基于k近邻的K个样本作为分析从而简化计算提升效率,K近邻算法分类器是基于距离计算的分类器。
集成学习方法
集成学习有许多集成模型,例如自助法、自助聚合(Bagging)、随机森林、提升法(Boosting)、 堆叠法(stacking) 以及许多其它的基础集成学习模型。
集成方法的思想是通过将这些个体学习器(个体学习器称为“基学习器”,基学习器也被称为弱学习器。)的偏置和/或方差结合起来,从而创建一个 强学习器(或 集成模型),从而获得更好的性能。
我们可以用三种主要的旨在组合弱学习器的元算法:
非常粗略地说,我们可以说Bagging的重点在于获得一个方差比其组成部分更小的集成模型,而Boosting和Stacking则将主要生成偏置比其组成部分更低的强模型(即使方差也可以被减小)。
十折交叉验证
由于深度学习模型一般需要较长的训练周期,如果硬件设备不允许建议选取留出法,如果需要追求精度可以使用交叉验证的方法。
十折交叉验证用来测试算法准确性。将数据集分成十份,轮流将其中九份作为训练数据,一份作为测试数据,进行试验。每次试验都会得出相应的正确率(或差错率)。十次的结果的正确率(或差错率)的平均值作为对算法精度的估计,一般还需要进行多次十折交叉验证(例如十次十折交叉验证),再求其均值,作为对算法准确性的估计。
下面假设构建了十折交叉验证,训练得到十个CNN模型。
那么在十个CNN模型可以使用如下方式进行集成:
在深度学习中本身还有一些集成学习思路的做法,值得借鉴学习:
【1】数据读取:https://mp.weixin.qq.com/s/IOlHIEIQhuIaubTeP4o39【2】CNN模型:https://mp.weixin.qq.com/s/JhFun5I_8Kjkbz6S4613Xw【3】模型训练:
https://mp.weixin.qq.com/s/ZwfrIkHQMsHl_16xvCSejQ【4】模型集成:
https://mp.weixin.qq.com/s/I41c-i-6y-pPdZOeiMM_0Q【5】理论实践:https://tianchi.aliyun.com/competition/entrance/531795/information