• 人脸识别智能小程序 | 卷积神经网络基础 | 02


    什么是卷积神经网络

    卷积神经网络:以卷积结构为主(除了conv,还有pooling,dropout等层次结构),搭建起来的深度网络。

    • 将图片作为输入:卷积输入数据的维度((n,h,w,c)),分别表示batch_size,高度,宽度,色彩通道。
    • 自动提取特征:参数优化
    • 图片的变形具有高度不变性:对于图像的形变是不敏感的,是鲁棒的

    特征提取通常是在输出结果前的一层,FC层,经过这个FC层,卷积特征就会变成一个向量,这个向量具体多少维,取决于FC的参数。

    卷积神经网络的重要组成单元

    这里需要重点介绍的有:

    • 卷积层
    • 池化层
    • 激活层
    • BN层
    • LOSS层
    • 全连接层

    卷积:对图像和滤波矩阵(卷积核)做互相关运算(对应元素相乘再求和)的操作。

    卷积操作简单来说就是图像和滤波矩阵进行先乘后加的操作。

    • 滤波器
    • 每一种卷积对应一种特征
    • Im2col实现卷积运算:实现卷积运算不是两重循环,而是先把图片转换成向量,然后进行向量的运算。

    右下图是一个卷积的具体例子,卷积核和对应图片的一个区域,每个元素与对应元素进行相乘,最后在逐个相加,得到结果(一个数)!

    卷积中的重要参数

    卷积核

    • 最常用为2D卷积核((k_w*k_h))
    • 权重和偏置项
    • 常用卷积核:1*1,3*3,5*5,7*7 (一般不会超过7*7)

    为什么卷积核都是奇数的大小?因为有“中间点”,feature map存在“中间点”与原来的图像进行一一对应,可以保留图像的空间信息。

    一般而言,卷积操作后feature map的尺寸会变小,padding可以使得feature map的尺寸与原图像一致。

    卷积——权值共享局部连接(局部感受野/局部感知)

    • 卷积运算作用在局部(这里的filter size应该被认为是卷积后的feature size的大小)
    • Feature map使用同一个卷积核运算后得到一种特征(权值共享)
    • 多种特征采用多个卷积核(channel)

    从层和层之间的连接关系来看,输入层和输出层是局部连接的。也就是当前的一个局部区域,对应到输出的feature map的一个点。

    全连接就是feature map上的点和输入层的每一个点都存在连接关系。

    上面的示例图说的就是权值共享&局部连接。

    • 局部连接:

      对于一个1000 × 1000的输入图像而言,如果下一个隐藏层的神经元数目为10^6个,采用全连接则有1000 × 1000 × 10^6 = 10^12个权值参数,如此数目巨大的参数几乎难以训练;而采用局部连接,隐藏层的每个神经元仅与图像中10 × 10的局部图像相连接,那么此时的权值参数数量为10 × 10 × 10^6 = 10^8,将直接减少4个数量级。

    • 权值共享:

      尽管减少了几个数量级,但参数数量依然较多。能不能再进一步减少呢?能!方法就是权值共享。具体做法是,在局部连接中隐藏层的每一个神经元连接的是一个10 × 10的局部图像,因此有10 × 10个权值参数,将这10 × 10个权值参数共享给剩下的神经元,也就是说隐藏层中10^6个神经元的权值参数相同,那么此时不管隐藏层神经元的数目是多少,需要训练的参数就是这 10 × 10个权值参数(也就是卷积核(也称滤波器)的大小),如下图。

    这大概就是CNN的一个神奇之处,尽管只有这么少的参数,依旧有出色的性能。但是,这样仅提取了图像的一种特征,如果要多提取出一些特征,可以增加多个卷积核,不同的卷积核能够得到图像的不同映射下的特征,称之为Feature Map。如果有100个卷积核,最终的权值参数也仅为100 × 100 = 10^4个而已。另外,偏置参数也是共享的,同一种滤波器共享一个。

    卷积核的大小就对应感受野的区域大小,比如(3*3)d的卷积核,其感受野的大小就是(5*5)

    卷积核越大,意味着感受野越大,感受野越大,意味着感知到这个图像的区域信息就会越多。但是如果用大卷积核,不见得学到的结果就好。例如上图,以2D举例,(3*3)卷积核的参数个数为9,(5*5)卷积核的参数个数为25,(7*7)卷积核的参数个数为49,参数过多容易导致过拟合。

    小卷积核是减少了计算量,但是如何实现大卷积核的效果呢?答案是叠加卷积。

    例如右上图,(3*3)大小的卷积核卷积一次得到的feature map的大小为(3*3),在用(3*3)的卷积核再卷积一次,那么其大小就会变成(1*1),其效果等价于直接使用(5*5)的卷积核进行一次卷积。

    使用小卷积核替代大卷积核的好处:参数量和计算量明显降低!

    通过多个小卷积核来替代一个大卷积核,不仅可以保证感受野的大小不变,而却网络的深度会加深,那么就可以在卷积层和卷积层的其中加入一些非线性层,使得网络的非线性能力更加的强,意味着网络描述一个事物的能力会变强。

    评估卷积的参数量是必须掌握的。

    参数越多,那么对机器的性能就越高,在保证性能的前提下,当然是希望参数越小越好!参数越多,意味着我们的模型越复杂。

    步长(Stride)

    • 下采样的过程
    • 输出Feature Map的大小变化:((N-F)/stride+1)

    stride一般都是设置为1或2。

    Pad

    • 确保Feature Map整数倍变化,对尺度相关的任务尤为重要

    比如(8*8)大小的矩阵,卷积核的大小为(3*3),那么经过pooling得到的Feature Map的大小为(6*6)(8*8)(6*6)相差不是整数倍!

    具体要pad多少呢?和卷积核的大小相关

    • F=3 =》zero pad with 1
    • F=5 =》zero pad with 2
    • F=7 =》zero pad with 3

    卷积的定义和使用

    在tensorflow中定义卷积的话,实际上有很多方法,使用tf.nn原生方法来定义的话,需要自己先定义权值项filter_weight和偏置项biases,

    slim是对tensorflow更加高层的一个封装,也可以方便的定义卷积。

    池化的基本概念

    池化:对输入的特征图进行压缩

    • 使特征图变小,简化网络计算复杂度(stride就是有下采样的作用)
    • 进行特征压缩,提取主要特征
    • 增大感受野

    池化是对Feature Map进行压缩,得到更小的Feature Map!

    压缩Feature Map,一方面是可以减少计算量,还有这也是一个特征提取的过程,另外,对Feature Map压缩可以增大感受野。

    注意: 池化层是没有参数的,所以进行BP的时候是无关池化层的事情!

    激活函数的基本概念

    激活函数:增加网络的非线性,进而提升网络的表达能力

    如何理解线性和非线性?

    从分类器的角度来理解:

    • 线性分类器就是用一个“超平面”将正、负样本隔离开,如:
      (1)二维平面上的正、负样本用一条直线来进行分类;
      (2)三维立体空间内的正、负样本用一个平面来进行分类;
      (3)N维空间内的正负样本用一个超平面来进行分类。
    • 非线性分类器就是用一个“超曲面”或者多个超平(曲)面的组合将正、负样本隔离开(即,不属于线性的分类器),如:
      (1)二维平面上的正、负样本用一条曲线或折线来进行分类;
      (2)三维立体空间内的正、负样本用一个曲面或者折面来进行分类;
      (3)N维空间内的正负样本用一个超曲面来进行分类。

    从函数定义角度来说:

    • 线性:1、变量之间的变化率为恒量,函数关系是直线;2、满足叠加原理,即f(ax + by) = af(x) + bf(y)。
    • 非线性:所有不满足线性条件的关系就是非线性。
    • 可以写成多元一次方程组形式的,就是线性。二次以上就是非线性。

    sigmoid函数将输入的值归一化到0到1中去 (x => [0,1])([0,1])之间有什么特点呢?可以表达概率。因此如果是分类任务,可以使用sigmod函数将结果映射到([0,1])当中,这样就拿到一个关于结果预测的概率分布。

    sigmoid函数很少在网络的中间层,主要原因就是sigmoid容易出现梯度弥散/梯度饱和这样的问题,BP由链式法则进行乘法叠加,那么就会有梯度弥散(就是梯度很小,收敛很慢)。

    指数运算是一个非常耗时的运算!

    sigmoid更多是作为最后的输出层。

    sigmoid和tanh在RNN中应用会更多,在CNN中应用是较少的!

    tanh和sigmoid的问题是类似的,一个就是梯度弥散的问题,一个就是指数运算的问题。

    tanh和sigmoid的区别在于输出是否以零为中心。

    一般在设计CNN的时候都是不会用到tanh和sigmoid的,sigmoid还CNN还会有用到,tanh基本是不会在CNN中出现的

    RuLU激活函数是现在CNN的标配激活函数!

    BatchNorm层/批量归一化层

    (eta,gamma)这两个是在BN层可以被进行学习的参数。

    BatchNorm层:通过一定的规范化手段,把每层神经网络任意神经元这个输入值的分布强行拉回到均值为0,方差为1的标准正态分布。

    为什么需要引入BatchNorm层对数据进行规范化处理呢?

    对于原始的输入数据,如果我们不加规范化的话,输入数据的分布是不可控的,每个层的数据分布都是有差异的。而且这个差异,在训练的过程中,由于经过多轮的BP算法,每一轮的BP算法都会改变相应层的参数,这一层参数的改变,也意味着这一层的输入输出也会发生变化,输入输出发生变化,数据的部分又不可控,这个时候带来的一个现象就是训练过程中,每一层的分布是不停在变化的,这对于网络的收敛是非常不利的,也正是因为这样的一个原因,才会对输入的数据进行约束。

    BatchNorm层使用在激活函数之前,BatchNorm层本质上是一种线性变换,激活函数是非线性变换。

    引入BatchNorm层,对数据进行规范化的约束,会带来很多优点。

    • 可以取消Dropout层和L2正则项
    • BN层可以加速模型收敛,因此学习率可以稍微增大
    • BN可以理解为在每个小批量里加入了噪音,以此来控制模型的复杂度

    上面是TensorFlow中三种使用BN的方式。

    全连接层

    全连接层:连接所有的特征,及那个输出值送给分类器(比如softmax分类器)

    • 将网络的输出变成一个向量: 卷积层输出的结果,一定是一个四维的特征图((n,h,w,c)),需要将这个四维矩阵转化为一维向量进行全连接
    • 可以采用卷积代替全连接层
    • 全连接层是尺度敏感的:全连接层的参数是固定的,如果输入的个数改变,那么运算的式子也会跟着改变。
    • 配合使用dropout层: 因为全连接层的参数量非常大,所以使用dropout层随机丢弃一些节点

    全连接层就是一个线性运算。

    通常而言,一个卷积网的参数量,大部分都是占据在全连接层的,比如VGG,80%的参数都是来自最后的FC层。

    Dropout层/丢弃法

    使用全连接层由于参数量非常大,所以会使用dropout层,来对节点进行杀死。

    dropout:在训练过程中,随机的丢弃一部分输入,此时丢弃部分对应的参数不会更新(置零)。

    防止模型过拟合有两种处理方式:

    • 一种是让模型变得比较小(就是减少参数) =》 丢弃法
    • 一种是让每个参数选择值的范围比较小 =》 权重衰退

    下面是范数知识的补充

    关于权重衰退知识的补充

    损失层

    损失函数:用来评估模型的预测值与真实值的不一致程度。

    • 经验风险最小:得到的结果最优
    • 结构风险最小:防止模型过于复杂(过拟合)

    交叉熵损失、softmax这些都是经验风险最小的损失函数,需要在损失函数中加入一个惩罚项。

    常见的结构风险最小的函数有L0,L1,L2。

    损失层一般都是定义了经验风险最小, 那么结构风险最小需要另外加约束,比如对卷积的核函数参数((w,b)),那么可以对其添加L2正则化。

    交叉熵损失实际上是源于逻辑回归中的似然损失。

    什么是似然?我们在学习概率统计的时候经常会去区分两个概念,就是概率和似然。

    • 概率通常是一个统计上的概念,某一个事件出现的频次
    • 似然是在已知结果的情况下,反推产生这些结果的原因(在深度学习中这些原因就是我们要进行学习的参数)

    非负性:对于损失,都是大于等于0的,因为只有大于等于0,这样才能找到一个最小值。

    上面的公式是以二分类作为例子给出的。

    L1在0点不可导,L2在0点可导,但是L2越靠近0,那么梯度的值就越来越小。

    Smooth L1是综合考虑了L1和L2的特点。在((-1,1))中靠近0点使用L2,其他使用L1加速收敛。

    常见的卷积神经网络结构

    模型是要设计的越复杂还是更加的轻量?

    工业界希望是在保证准确率的情况下,模型设计的越轻量越好。

    学术界则希望模型能够设计的更加的复杂,这样来保证模型的正确率。

    LeNet

    LeNet应用于一个十分类问题(手写数字识别 mnist)。

    从LeNet可以看到分类任务的大概思路。

    图片输入,经过(conv,pooling),在经过全连接层(FC n分类就n维),最后经过softmax,得到一个([0,1])的概率值。

    AlexNet

    2012年显卡的显存还是有限的,网络模型图中给出的两个分支,表示使用两张显卡进行分布式训练。

    • conv-relu-pooling-LRN

    网络图所示,图片经过多轮卷积,(11*11,5*5,3*3,3*3,3*3),AlexNet在设计的时候,每一个卷积之后,都会配有relu,pooling,LRN三个层。

    relu 增加非线性能力

    pooling 下采样,增大图像感受野,对图像进一步提取

    LRN 归一化,将数据约束在一定

    • fc-rule-dropout

    在经过两个fc层,后面跟着rule和dropout,因为fc层的参数量非常大,所以这里要使用dropout层进行一些参数的删除(置零)。

    • fc-softmax

    最终将特征映射到一个1000维的向量上。

    最终训练出来的参数在60M以上,整个模型大小在200M以上。

    • ReLU激活函数

    ReLU激活函数相对于其他的激活函数,能实现一个更快的计算速度,并且在x大于0时,不会出现梯度消失这样的问题。

    ReLU也成了后面我们设计卷积神经网络的一个标配。

    • Dropout层

    FC+Dropout层是标配,dropout可以减少过拟合的风险,因为FC中存在过多的参数,通过dropout能够对FC的参数进行约束。

    • LRN层

    后面研究发现LRN层其实没有多大作用,现在基本已经被弃用了,现在使用的最多的是BN层。

    ZFNet

    ZFNet对于AlexNet并没有多大的改进,只是对AlexNet进行了一些细致的调整。ZFNet的最大贡献是对卷积网络为什么有效进行了分析。

    ZFNet中提出的几点结论,是非常有普适性的。

    ZFNet将特征进行可视化展示,具体是如何实现呢?上图的右边是正常卷积网的一个数据流向,对于我们最终下采样拿到的一个图片,我们该如何还原成最初的图片呢?实际上如果想进行百分百的还原,这是不可能的,因为经过激活层和pooling层的时候,会对图像造成不可逆的破坏,因此这个还原只是对特征高层次的语义分析,具体是通过上采样和反卷积操作来完成的,最终得到与原始图像大小一致的特征图。

    通过观察这些还原出来的特征图,作者总结出下面的结论。

    • 特征分层次体系结构

    对于CNN,特征的层次结构是非常明显的,通过浅层的卷积网络,可以得到纹理、颜色这些低层次的特征,再经过卷积,可以得到更加精细的纹理结构,这些特征图再经过多次深层的卷积,这时候在反卷积可视化,实际上很难在视觉上描述是什么特征,这称为高层次的语义特征。

    下图是训练时的特征演变。

    越浅层的网络提取出来的特征就越低,

    • 深层特征更鲁棒

    这个鲁棒体现在哪里呢?如果输入的图像发生了轻微的扰动,那么浅层的特征会发生明显的变化,但是对于深层的特征,产生的变化会越来越小。

    也就说,深层次的特征对输入的图像变得越来越不敏感,越来越鲁棒。

    • 深层特征更有区分度

    利用这些深层特征,可以更好的完成图像的分类。

    • 深层特征收敛更慢

    网络加深之后很难收敛,也就是越来越难训练,但是加深网络确实效果会更好。

    ResNet解决了网络加深后收敛变慢的这个问题。

    VGG

    VGG

    • 为了研究网络深度对模型准确度的影响,并采用小卷积堆叠的方式,来搭建整个网络结构

    都是采用了(3*3)的小卷积。

    • 参数量:138M;模型大小>500M

    VGG的网络更大,对比参数量的大小和模型大小就可以知道。

    上面的VGG示例图只列出了卷积的结构,实际上在卷积当中还会插入激活层和池化层。

    上面列出了11层、13层、16层、19层(卷积层、FC层是需要进行参数训练的,池化层不需要训练)。

    这里输入图像的大小是(224*224),这个尺寸是对应ImageNet挑战赛图像分类任务的图像尺寸,这也是为什么我们在设计分类识别任务的时候采用(224*224)来设计和训练网络。我们想要使用ImageNet挑战赛上表现优秀的模型来进行模型迁移,那么就需要保证和训练的模型数据的一致性,所以在设计网络的时候会尽量保证尺寸为(224*224)

    • 更深的网络结构,结构更加规整、简答

    • 全部使用(3*3)的小型卷积核核(2*2)的最大池化层

    不难发现一点,VGG的网络非常深,相比AlexNet,它的卷积是非常多的,另外可以发现这里的卷积核都是(3*3)的卷积核,没有大于(3*3)的卷积核。

    小卷积核可以实现大卷积核的感受野范围,同时计算量会更小。

    • 每次池化后Feature Map宽高降低一半,通道数量增加一倍

    每次经过一个pooling层,channel的数量会乘2,保证提取的数量。

    • 网络层数更多,结构更深,模型参数更大

    • 证明了更深的网络,能够提取更好的特征

    • 成为后续很多网络的backbone

    利用VGG来进行特征的提取,虽然VGG只在ImageNet挑战赛获得第二名,但是使用VGG提取出来的图像特征往往更有效。

    这也是为什么VGG也成为后续很多网络的主干网络。

    • 规范化了后续网络设计的思路

    VGG也规范了后面网络的设计思路,后续的网络设计基本都是非常的规整。

    基本都有一个最小的结构单元,然后在这个单元上进行堆叠。

    还有就是一个默认:每次下采样过后,channel的数量也会相应的增加。

    Inception

    Inception结构,在设计网络结构时,不仅强调网络的深度,也会考虑网络的宽度

    网中网的结构,也就是Inception结构。

    Inception结构在后面设计网络结构的时候也是经常会被用到的一个网络结构。

    Inception提出后,Google也进行了一系列的改进,提出v2、v3..

    更多的卷积:网络的宽度(channel数量)

    更深的层次:网络的深度

    为什么GoogleNet的网路深度很深,宽度也很宽,可最终的参数量却很小呢?主要就是有效的利用了(1*1)的卷积核。

    Inception结构是GooLeNet的最小结构单元,当然GoogLeNet中包含多个Inception结构, 每个Inception结构都有一些细微的差别。

    不同于VGG的”串“结构,GoogLeNet表现为一个”网中网“的结构,输入的中间的这样一个层,它的每个结点同样也是一个卷积。

    值得学习的一个点就是在经过(3*3)(5*5)的卷积核之前,会使用(1*1)的卷积核来减少channel的数量。

    GoogLeNet为了保证网络变深之后能够收敛的更好,利用了2个loss来进行训练。

    GoogoLeNet最大的启示就是教会我们如何巧妙的利用(1*1)的卷积核。

    理解为什么什么(1*1)的卷积核可以实现降维?

    这个就是卷积运算本身的内容,卷积核的channel是多少,那么最后的结果是把每个channel进行相加。

    也就是如果输入(28*28*192)经过一个(1*1*64)的卷积核后,尺寸会变成(28*28*3)

    上图的左右和右边分别表示在图片输入之前有没有加入(1*1)的卷积核。

    • 更深的网络结构,同时考虑了网络的宽度

    GoogLeNet在设计的时候不仅考虑网络的深度,也考虑的网络的宽度。

    • 两个LOSS层,降低过拟合风险
    • 巧妙地利用(1*1)的卷积核来进行通道降维,减小计算量

    这里的更新是 利用两个(3*3)替换(5*5),利用(n*1)(1*n)替换了(n*n)

    使用小卷积核替换大卷积核的好处:

    • 参数量减少,计算量减少
    • 网络变深,那么可以插入更多的激活函数,增加网络的非线性能力。

    实验表明,对于卷积的这种拆分,最好是在网络的中间使用,不要再输入的开始就进行这样的卷积拆分。

    ResNet

    ResNet引入跳连结构来防止梯度消失问题,可以进一步加大网络的深度。

    ResNet也是后面许多网络结构作为主干网络进行特征提取的首选。

    VGG最多有19层,ResNet可以达到上百层。为什么ResNet的网络结构可以这么深呢?因为引入了跳连的结构。

    这种跳连结构直接将输入层的特征传递到输出层,然后和卷积之后的结果进行相加,最后可以得到一个结合了原始输入特征的输出特征。

    在网络加入这样跳连的线,实际上并没有增加参数量,虽然网络结构发生了变化,但是网络的参数量是没有发生变化的,这也是跳连结构的一个优点。

    ResNet在设计的时候同样采用卷积堆叠的方式,但是不再是串联,而是这种带有跳连的结构来作为核心单元。然后网络使用这样的单元来进行堆叠。

    输入使用(7*7)的卷积核,由于初始channel为3,问题不大。可以发现后面深层一点的卷积核都是(1*1)(3*3)的。

    ResNet在最后分类的时候,采用的不是FC,而是average pool。VGG的80%的参数集中在FC层,使用一个池化层来替换掉FC层,会减少很多的参数量,因为池化层本身是没有参数的。

    对于像50、101、152层的ResNet,其中还采用了(1*1)的卷积核来减少计算量,整个还是可以接受的。

    上图有给出网络需要的计算量FLOPs。

    还有就是ResNet对缓存有要求,如下图,从A->C不是直接串联下来的,而是需要把A先进行缓存,如果feature map比较大或channel比较多,对机器的缓存就有要求。

    例如上图,网络当然不是越深越好,这是一定的,比如F3的网络可能最优解比F6找到的要更好,这种虽然网络更深,但是并没有表现得更好,这就是模型偏移。

    ResNet的思想就是可以保证模型不会变差。

    如下图,输入的特征为x,输出特征为(H(x)=f(x)+x)

    也就是,即使没有(f(x)),那么(H(x))也有x作为保底。

    从卷积的角度思考,如何减小网络中的计算量

    从GoogleNet中,可以总结出下面几个结论,来减少卷积网络中的计算量。

    • 小卷积核来对大卷积核进行拆分

    对于(5*5)(7*7)这样的大卷积核(不可能比7更大),最多只会使用再输入层,因为原始图片输入channel为3,那么channel为3的计算量还是很小的,但是后续的channel的可能是32、64、128,这就是非常大一个channel数量。

    后面一般都是采用(3*3)(1*1)的卷积核,不太会采用其他的大小的卷积核。像类似(1*3)(3*1)也很少使用,只用在Inception中使用了。

    • stride=2代替pooling层

    stride=2可以直接降低当前卷积层的计算量。

    • 巧妙地利用(1*1)的卷积核来进行降维

    (1*1)卷积核可以帮助减少channel的数量。

    我们在设计卷积的时候,要压缩网络的时候,就可以从上面的点来进行考虑。

    卷积神经网络结构对比

    AlexNet:开启了卷积神经网络的风暴

    VGG:加深了卷积神经网络

    GoogLeNet:加深、加宽了网络

    ResNet:更加加深了网络

    卷积神经网络中的Attention机制

    注意力机制可能大家在循环神经网中大家了解会比较多一点,实际上在卷积神经网络中也存在attention机制。

    attention是模仿人脑在观察图片的时候,会像关注重要的信息。

    引入attention机制,使得网络有更好的可解释性。

    attention就是对图像相应位置进行不同程度的加权

    Hard-Attention:0/1这样的mask

    Soft-Attention:0~1这样的mask

    attention就是一种加权的思路,这种加权的思路不仅可以用在特征图,还可以用在原始图、空间尺度...

    上部分是一个标准的ResNet结构,下部分就是在计算特征图上每个点的权值,通过卷积和反卷积,得到和feature map大小一致的结果,然后对这个输出结果进行激活,然后和特征结果进行点乘,再进行相加,这就完成了对特征图的加权。

    上图是将特征图作用在通道上的一种加权的方法。

    模型压缩

    想要让模型跑在嵌入设备中

    • 一种方法就是设计一些轻量型的卷积神经网络
    • 还有就是对大的模型进行模型压缩

    模型压缩也是在精度和速度之间的一种平衡。

    学院派希望精度越高越好,工程派希望在精度一定时候,能够让模型尽可能的轻量,减少计算量。

    模型剪枝

    小结

    什么是卷积神经网络

    卷积神经网络:以卷积结构为主(除了conv,还有pooling,dropout等层次结构),搭建起来的深度网络。
    *   将图片作为输入:卷积输入数据的维度$(n,h,w,c)$,分别表示batch_size,高度,宽度,色彩通道。
    *   自动提取特征:参数优化
    *   图片的变形具有高度不变性:对于图像的形变是不敏感的,是鲁棒的
    
    特征提取通常是在输出结果前的一层,FC层,经过这个FC层,卷积特征就会变成一个向量,这个向量具体多少维,取决于FC的参数。
    

    卷积的基本定义

    卷积:对图像和滤波矩阵(卷积核)做互相关运算(对应元素相乘再求和)的操作。
    
    卷积操作简单来说就是图像和滤波矩阵进行先乘后加的操作。
    
    *   滤波器
    *   每一种卷积对应一种特征
    *   Im2col实现卷积运算:实现卷积运算不是两重循环,而是先把图片转换成向量,然后进行向量的运算。
    

    卷积核,以及卷积核的大小为什么都是奇数?

    卷积核
    
    *   最常用为2D卷积核$(k_w*k_h)$
    *   权重和偏置项
    *   常用卷积核:1*1,3*3,5*5,7*7 (一般不会超过7*7)
    
    
    
    为什么卷积核都是奇数的大小?因为有“中间点”,feature map存在“中间点”与原来的图像进行一一对应,可以保留图像的空间信息。
    
    一般而言,卷积操作后feature map的尺寸会变小,padding可以使得feature map的尺寸与原图像一致。
    

    卷积中的局部连接和权值共享

    局部连接:图片中只有局部与输出的feature map的点有关
    全连接:feature map的店与图像中的全部点都有关
    
    权值共享:没有必要每一个局部都训练出一个卷积核的参数,一个就行了(提取同一种特征,而且与位置无关)
    
    局部连接&权值共享大大减小了图片的网络参数数量!
    

    卷积核与感受野

    **使用小卷积核替代大卷积核的好处:参数量和计算量明显降低!**
    
    通过多个小卷积核来替代一个大卷积核,不仅可以保证感受野的大小不变,而却网络的深度会加深,那么就可以在卷积层和卷积层的其中加入一些非线性层,使得网络的非线性能力更加的强,意味着网络描述一个事物的能力会变强。
    
    

    如何估算卷积的参数量?

    32*32*3image
    filter size:5*5
    filter num:100
    
    那么参数的个数为
    5*5*3*1*100
    
    如果没有权值共享,那么为 (5*5*3)*(28*28)*100
    

    步长

    步长(Stride)
    
    *   下采样的过程(把高维矩阵通过一个隐层映射为一个维数较低的矩阵)
    *   输出Feature Map的大小变化:$(N-F)/stride+1$
    
    stride一般都是设置为1或2。
    

    pad

    Pad
    
    *   确保Feature Map整数倍变化,对尺度相关的任务尤为重要
    
    比如$8*8$大小的矩阵,卷积核的大小为$3*3$,那么经过pooling得到的Feature Map的大小为$6*6$,$8*8$和$6*6$相差不是整数倍!
    
    具体要pad多少呢?和卷积核的大小相关
    
    *   F=3 =》zero pad with 1
    *   F=3 =》zero pad with 2
    *   F=3 =》zero pad with 3
    

    池化层

    池化:对输入的特征图进行压缩
    
    *   使特征图变小,简化网络计算复杂度(stride就是有下采样的作用)
    *   进行特征压缩,提取主要特征
    *   增大感受野
    
    
    
    池化是对Feature Map进行压缩,得到更小的Feature Map!
    压缩Feature Map,一方面是可以减少计算量,还有这也是一个特征提取的过程,另外,对Feature Map压缩可以增大感受野。
    
    注意: 池化层是没有参数的,所以进行BP的时候是无关池化层的事情!
    

    什么是线性?什么是非线性?

    从分类器的角度来理解:
    
    *   线性分类器就是用一个“超平面”将正、负样本隔离开,如:
        (1)二维平面上的正、负样本用一条直线来进行分类;
        (2)三维立体空间内的正、负样本用一个平面来进行分类;
        (3)N维空间内的正负样本用一个超平面来进行分类。
    *   非线性分类器就是用一个“超曲面”或者多个超平(曲)面的组合将正、负样本隔离开(即,不属于线性的分类器),如:
        (1)二维平面上的正、负样本用一条曲线或折线来进行分类;
        (2)三维立体空间内的正、负样本用一个曲面或者折面来进行分类;
        (3)N维空间内的正负样本用一个超曲面来进行分类。
    
    
    
    从函数定义角度来说:
    
    *   线性:1、变量之间的变化率为恒量,函数关系是直线;2、满足叠加原理,即f(ax + by) = af(x) + bf(y)。
    *   非线性:所有不满足线性条件的关系就是非线性。
    *   可以写成多元一次方程组形式的,就是线性。二次以上就是非线性。
    

    激活函数,sigmoid,tanh,ReLU

    激活函数:增加网络的非线性,进而提升网络的表达能力
    
    sigmoid:
    sigmoid函数将输入的值归一化到0到1中去 $x => [0,1]$,$[0,1]$之间有什么特点呢?可以表达概率。因此如果是分类任务,可以使用sigmod函数将结果映射到$[0,1]$当中,这样就拿到一个关于结果预测的概率分布。
    
    sigmoid函数很少在网络的中间层,主要原因就是sigmoid容易出现梯度弥散/梯度饱和这样的问题,BP由链式法则进行乘法叠加,那么就会有梯度弥散(就是梯度很小,收敛很慢)。
    
    指数运算是一个非常耗时的运算!
    sigmoid更多是作为最后的输出层。
    **sigmoid和tanh在RNN中应用会更多,在CNN中应用是较少的!**
    
    tanh:
    tanh和sigmoid的问题是类似的,一个就是梯度弥散的问题,一个就是指数运算的问题。
    tanh和sigmoid的区别在于输出是否以零为中心。
    **一般在设计CNN的时候都是不会用到tanh和sigmoid的,sigmoid还CNN还会有用到,tanh基本是不会在CNN中出现的**
    
    ReLU:
    **RuLU激活函数是现在CNN的标配激活函数!**
    

    BatchNorm层/批量归一化层

    BatchNorm层:通过一定的规范化手段,把每层神经网络任意神经元这个输入值的分布强行拉回到均值为0,方差为1的标准正态分布。
    
    效果:非常的work!现在基本是深层卷积网络的标配。(典型的工程走在理论前面!)
    作用:可能就是通过在每个小批量里加入噪音来控制模型的复杂度(防止过拟合),还有就是BN层可以加速收敛速度,但是对精度不会影响太多(所以一般大家都乐意加上BN层,能加速何乐而不为呢)
    
    
    引入BatchNorm层,对数据进行规范化的约束,会带来很多优点。
    *   可以取消Dropout层(丢弃法)和L2正则项
    *   BN层可以加速模型收敛,因此学习率可以稍微增大
    *   BN可以理解为在每个小批量里加入了噪音,以此来控制模型的复杂度
    
    
    为什么需要引入BatchNorm层对数据进行规范化处理呢?
    
    对于原始的输入数据,如果我们不加规范化的话,输入数据的分布是不可控的,每个层的数据分布都是有差异的。而且这个差异,在训练的过程中,由于经过多轮的BP算法,每一轮的BP算法都会改变相应层的参数,这一层参数的改变,也意味着这一层的输入输出也会发生变化,输入输出发生变化,数据的部分又不可控,这个时候带来的一个现象就是训练过程中,每一层的分布是不停在变化的,这对于网络的收敛是非常不利的,也正是因为这样的一个原因,才会对输入的数据进行约束。
    

    特征缩放方法

    归一化: MinMaxScaler
    标准化: StandardScaler
    

    全连接层

    全连接层:连接所有的特征,及那个输出值送给分类器(比如softmax分类器)
    
    *   将网络的输出变成一个向量: 卷积层输出的结果,一定是一个四维的特征图$(n,h,w,c)$,需要将这个四维矩阵转化为一维向量进行全连接
    *   可以采用卷积代替全连接层
    *   全连接层是尺度敏感的:全连接层的参数是固定的,如果输入的个数改变,那么运算的式子也会跟着改变。
    *   配合使用dropout层: 因为全连接层的参数量非常大,所以使用dropout层随机丢弃一些节点
    
    
    全连接层就是一个线性运算。
    
    通常而言,一个卷积网的参数量,大部分都是占据在全连接层的,比如VGG,80%的参数都是来自最后的FC层。
    

    权重衰退&丢弃法(dropout)

    如何防止模型过拟合?
    * 让模型变得简单:丢弃法
    * 让权重不要太大:权重衰退(权重不要那么大,就不会学习的那么激烈)
    
    权重衰退和dropout都是防止过拟合的手段,能够一定程度上提升模型的表现效果。
    
    

    什么是范数?

    非正式地说,一个向量的范数告诉我们一个向量有多大。
    在线性代数中,向量范数是将向量映射到标量的函数f。
    
    常用的范数有 L1,L2(默认 欧氏距离就是L2范数)
    
    L1范数:它表示为向量元素的绝对值之和。
    L2范数:假设n维向量x中的元素是x1,…,xn,其L2范数是向量元素平方和的平方根。
    

    损失函数(目标函数)

    损失函数:用来评估模型的预测值和真实值的不一致程度。
    目标函数 = 损失函数(经验风险最小) + 正则化(结构风险最小)
    
    

    L0,L1,L2正则化(范数约束/正则项/惩罚项)

    L0:参数中取值为0的个数(参数的0越多,表示模型越简单)
    L1:所有数的绝对值相加
    L2:所有数平方相加开根号(距离)
    
    L0是没有办法求导的,所以有了L1,L1是对L0的线性逼近。
    L2是对L1的凸优化
    
    L0、L1可以实现参数稀疏,模型稀疏的话泛化能力会更好
    

    什么是似然?

    什么是似然?我们在学习概率统计的时候经常会去区分两个概念,就是概率和似然。
    
    *   概率通常是一个统计上的概念,某一个事件出现的频次
    *   似然是在已知结果的情况下,反推产生这些结果的原因(在深度学习中这些原因就是我们要进行学习的参数)
    

    损失函数

    分类任务:交叉熵损失函数
    回归任务:L1、L2、smooth L1(一般都是选择smooth L1作为回归任务的损失函数)
    
    

    卷积神经网络中的设计标配

    激活函数:ReLU
    FC+d
    

    LeNet

    LeNet应用于一个十分类问题(手写数字识别 mnist)。
    
    从LeNet可以看到分类任务的大概思路。
    
    图片输入,经过(conv,pooling),在经过全连接层(FC n分类就n维),最后经过softmax,得到一个$[0,1]$的概率值。
    

    AlexNet

    2012年显卡的显存还是有限的,网络模型图中给出的两个分支,表示使用两张显卡进行分布式训练。
    
    *   conv-relu-pooling-LRN
    
    网络图所示,图片经过多轮卷积,$11*11,5*5,3*3,3*3,3*3$,AlexNet在设计的时候,每一个卷积之后,都会配有relu,pooling,LRN三个层。
    
    relu 增加非线性能力
    pooling 下采样,增大图像感受野,对图像进一步提取
    LRN 归一化,将数据约束在一定
    
    
    *   fc-rule-dropout
    
    在经过两个fc层,后面跟着rule和dropout,因为fc层的参数量非常大,所以这里要使用dropout层进行一些参数的删除(置零)。
    
    *   fc-softmax
    
    最终将特征映射到一个1000维的向量上。
    最终训练出来的参数在60M以上,整个模型大小在200M以上。
    
    *   ReLU激活函数
    ReLU激活函数相对于其他的激活函数,能实现一个更快的计算速度,并且在x大于0时,不会出现梯度消失这样的问题。
    
    ReLU也成了后面我们设计卷积神经网络的一个标配。
    
    *   Dropout层
    FC+Dropout层是标配,dropout可以减少过拟合的风险,因为FC中存在过多的参数,通过dropout能够对FC的参数进行约束。
    
    *   LRN层
    后面研究发现LRN层其实没有多大作用,现在基本已经被弃用了,现在使用的最多的是BN层。
    

    ZFNet

    ZFNet对于AlexNet并没有多大的改进,只是对AlexNet进行了一些细致的调整。ZFNet的最大贡献是对卷积网络为什么有效进行了分析。
    
    ZFNet中提出的几点结论,是非常有普适性的。
    
    ZFNet将特征进行可视化展示,具体是如何实现呢?上图的右边是正常卷积网的一个数据流向,对于我们最终下采样拿到的一个图片,我们该如何还原成最初的图片呢?实际上如果想进行百分百的还原,这是不可能的,因为经过激活层和pooling层的时候,会对图像造成不可逆的破坏,因此这个还原只是对特征高层次的语义分析,具体是通过上采样和反卷积操作来完成的,最终得到与原始图像大小一致的特征图。
    
    通过观察这些还原出来的特征图,作者总结出下面的结论
    * 特征分层次体系结构
    * 深层特征更鲁棒
    * 深层特征更有区分度
    * 深层特征收敛更慢
    

    VGG

    VGG
    
    *   为了研究**网络深度**对模型准确度的影响,并采用小卷积堆叠的方式,来搭建整个网络结构
    都是采用了$3*3$的小卷积。
    
    *   参数量:138M;模型大小>500M
    VGG的网络更大,对比参数量的大小和模型大小就可以知道。
    
    
    
    上面的VGG示例图只列出了卷积的结构,实际上在卷积当中还会插入激活层和池化层。
    
    上面列出了11层、13层、16层、19层(卷积层、FC层是需要进行参数训练的,池化层不需要训练)。
    
    这里输入图像的大小是$224*224$,这个尺寸是对应ImageNet挑战赛图像分类任务的图像尺寸,这也是为什么我们在设计分类识别任务的时候采用$224*224$来设计和训练网络。我们想要使用ImageNet挑战赛上表现优秀的模型来进行模型迁移,那么就需要保证和训练的模型数据的一致性,所以在设计网络的时候会尽量保证尺寸为$224*224$。
    

    VGG的特点

    *   更深的网络结构,结构更加规整、简答
    *   全部使用$3*3$的小型卷积核核$2*2$的最大池化层
    不难发现一点,VGG的网络非常深,相比AlexNet,它的卷积是非常多的,另外可以发现这里的卷积核都是$3*3$的卷积核,没有大于$3*3$的卷积核。
    小卷积核可以实现大卷积核的感受野范围,同时计算量会更小。
    *   每次池化后Feature Map宽高降低一半,通道数量增加一倍
    每次经过一个pooling层,channel的数量会乘2,保证提取的数量。
    *   网络层数更多,结构更深,模型参数更大
    

    VGG的意义

    *   证明了更深的网络,能够提取更好的特征
    *   成为后续很多网络的backbone
    利用VGG来进行特征的提取,虽然VGG只在ImageNet挑战赛获得第二名,但是使用VGG提取出来的图像特征往往更有效。
    这也是为什么VGG也成为后续很多网络的主干网络。
    
    *   规范化了后续网络设计的思路
    VGG也规范了后面网络的设计思路,后续的网络设计基本都是非常的规整。
    基本都有一个最小的结构单元,然后在这个单元上进行堆叠。
    还有就是一个默认:每次下采样过后,channel的数量也会相应的增加。
    
    

    GoogLeNet/Inception

    Inception结构,**在设计网络结构时,不仅强调网络的深度,也会考虑网络的宽度**。
    网中网的结构,也就是Inception结构。
    Inception结构在后面设计网络结构的时候也是经常会被用到的一个网络结构。
    Inception提出后,Google也进行了一系列的改进,提出v2、v3..
    
    更多的卷积:网络的宽度(channel数量)
    更深的层次:网络的深度
    
    为什么GoogleNet的网路深度很深,宽度也很宽,可最终的参数量却很小呢?主要就是有效的利用了$1*1$的卷积核。
    
    
    GoogoLeNet最大的启示就是教会我们如何巧妙的利用$1*1$的卷积核。
    理解为什么什么$1*1$的卷积核可以实现降维?
    
    这个就是卷积运算本身的内容,卷积核的channel是多少,那么最后的结果是把每个channel进行相加。
    也就是如果输入$28*28*192$经过一个$1*1*64$的卷积核后,尺寸会变成$28*28*3$。
    
    

    GoogLeNet的特点

    *   更深的网络结构,同时考虑了网络的宽度
    GoogLeNet在设计的时候不仅考虑网络的深度,也考虑的网络的宽度。
    *   两个LOSS层,降低过拟合风险
    *   巧妙地利用$1*1$的卷积核来进行通道降维,减小计算量
    
    

    关于(1*1)卷积和stride=2

    1*1卷积可以减少channel的数量,也可以理解成“全连接”,因为减少channel实际上就是让channel进行了线性堆叠
    
    stride=2不仅可以减少当前卷积层的计算量,而且可以替换了池化层,因为池化层丢弃的参数会更多。 但是每层卷积都是有参数的,这样计算量会增大不少。
    

    从卷积角度思考,如何减少网络中的计算量?

    从GoogleNet中,可以总结出下面几个结论,来减少卷积网络中的计算量。
    
    *   小卷积核来对大卷积核进行拆分
    对于$5*5$和$7*7$这样的大卷积核(不可能比7更大),最多只会使用再输入层,因为原始图片输入channel为3,那么channel为3的计算量还是很小的,但是后续的channel的可能是32、64、128,这就是非常大一个channel数量。
    
    后面一般都是采用$3*3$或$1*1$的卷积核,不太会采用其他的大小的卷积核。像类似$1*3$和$3*1$也很少使用,只用在Inception中使用了。
    
    *   stride=2代替pooling层
    stride=2可以直接降低当前卷积层的计算量。
    
    *   巧妙地利用$1*1$的卷积核来进行降维
    $1*1$卷积核可以帮助减少channel的数量。
    
    
    
    我们在设计卷积的时候,要压缩网络的时候,就可以从上面的点来进行考虑。
    

    关于深层网络梯度爆炸和梯度消失的理解

    BP算法求梯度,是一个一个导数相乘的 x*x*x*...  这里可以抽象为 x^n
    如果 x>1 n->∞, 那么 x->∞  梯度爆炸
    如果 x<1 n->∞, 那么 x->0  梯度消失
    

    ResNet

    ResNet引入跳连结构来防止梯度消失问题,可以进一步加大网络的深度。
    
    ResNet也是后面许多网络结构作为主干网络进行特征提取的首选。
    
    VGG最多有19层,ResNet可以达到上百层。为什么ResNet的网络结构可以这么深呢?因为引入了跳连的结构。
    
    这种跳连结构直接将输入层的特征传递到输出层,然后和卷积之后的结果进行相加,最后可以得到一个结合了原始输入特征的输出特征。
    
    在网络加入这样跳连的线,实际上并没有增加参数量,虽然网络结构发生了变化,但是网络的参数量是没有发生变化的,这也是跳连结构的一个优点。
    
    ResNet在设计的时候同样采用卷积堆叠的方式,但是不再是串联,而是这种带有跳连的结构来作为核心单元。然后网络使用这样的单元来进行堆叠。
    
    输入使用$7*7$的卷积核,由于初始channel为3,问题不大。可以发现后面深层一点的卷积核都是$1*1$和$3*3$的。
    
    ResNet在最后分类的时候,采用的不是FC,而是average pool。VGG的80%的参数集中在FC层,使用一个池化层来替换掉FC层,会减少很多的参数量,因为池化层本身是没有参数的。
    
    对于像50、101、152层的ResNet,其中还采用了$1*1$的卷积核来减少计算量,整个还是可以接受的。
    
    上图有给出网络需要的计算量FLOPs。
    
    
    
    还有就是ResNet对缓存有要求,如下图,从A->C不是直接串联下来的,而是需要把A先进行缓存,如果feature map比较大或channel比较多,对机器的缓存就有要求。
    

    ResNet的设计点

    如下图,输入的特征为x,输出特征为$H(x)=f(x)+x$
    也就是,即使没有$f(x)$,那么$H(x)$也有x作为保底。
    
    
    * 核心单元简单堆叠
    * 跳连结构解决网络梯度消失问题
    * average pooling层代替FC层
    * BN层加快网络训练速度和收敛时的稳定性
    * 加大网络深度,提高模型特征提取能力
    

    卷积中的attention

    attention实际上就是一种加权的思想。
    
  • 相关阅读:
    Symfony2 学习笔记之报错
    Symfony2学习笔记之数据校验
    Symfony2学习笔记之HTTP Cache
    Symfony2学习笔记之表单
    Symfony2 学习笔记之插件格式
    Symfony2学习笔记之数据库操作
    Symfony2 学习笔记之内部构件
    Symfony2 学习笔记之模板使用
    让VIEWSTATE从页面中完全消失(小技巧)
    打包bat等文件成exe,双击运行不显示dos窗口,exe不报毒
  • 原文地址:https://www.cnblogs.com/Rowry/p/15076804.html
Copyright © 2020-2023  润新知