0%

卷积神经网络-实例探究

卷积神经网络-实例探究

为什么要进行实例分析?

之前已经了解过了卷积神经网络的一些基本知识-卷积层、池化层、全连接层等,人们花费许多时间在探究如何将这些不同的层进行连接形成有更有效的神经网络,而找到这种方法(或感觉)的最好方法之一就是看一些实例。

经典网络

LeNet-5

LeNet-5是针对灰度图像训练的,所以输入通道只有1,结构如图

image-20201226211935913
image-20201226211935913

包含约6万个参数

参考文献:Gradient-Based Learning Applied to Document Recognition

AlexNet

image-20201226212903842
image-20201226212903842

AlexNet和LeNet类似,但更大,包含约6000万个参数

使用了ReLU激活函数

多GPU

LRN层:局部响应归一化层(Local Response Normalization)

参考文献:ImageNet Classification with Deep Convolutional Neural Networks

VGGNet(VGG-16)

image-20201226214414518
image-20201226214414518

VGG-16中的16指在网络中包含16个卷积层和全连接层

总共包含约1.38亿个参数

参考文献:Very Deep Convolutional Networks for Large-Scale Image Recognition

残差网络(Residual Networks(ResNets))

残差块(Residual block)

ResNets是由残差块构建的

如图是一个两层神经网络,在L层进行激活,得到\(a^{[l+1]}\)再次进行激活,两层之后,得到\(a^{[l+2]}\) \[ a^{[l]} \xrightarrow[z^{[l+1]}=W^{[l+1]}a^{[l]}+b^{[l+1]}]{} Linear \rightarrow ReLU \xrightarrow[a^{[l+1]}=g(z^{[l+1]})]{a^{[l+1]}}Linear \xrightarrow[z^{[l+2]}=W^{[l+2]}a^{[l+1]}+b^{[l+2]}]{} \\ ReLU \xrightarrow[a^{[l+2]}=g(z^{[l+2]})]{} a^{[l+2]} \] 换句话说,从\(a^{[l]}\)\(a^{[l+2]}\),需要经过以上所有步骤,即这些网络的主路径

在残差网络中有一点变化,将\(a^{[l]}\)直接迅速向后拷贝到神经网络的深层,在ReLU非线性激活前加上\(a^{[l]}\),构成一条捷径"short cut"(远跳连接"skip connection"),意味着最后的\(a^{[l+2]}=g(z^{[l+2]})\)去掉了,取而代之的是\(a^{[l+2]}=g(z^{[l+2]}+a^{[l]})\)

通过这种残差块的方式,能够训练更深的神经网络,所以构建一个ResNet网络,就是通过将很多这样的残差块堆积在一起,形成一个深度神经网络

image-20201226221805757
image-20201226221805757

残差网络(Residual Network)

如图是一个"Plain Network",将它变成"ResNet"的方法是,加上所有的"skip connections"/"shortcut connections",和前面一样,第两层增加一个捷径,构成一个残差块,5个残差块连接在一起,构成一个残差网络

image-20201226222440538
image-20201226222440538

如图下面部分,在"Plain Network"中,虽然理论上应该神经网络层数越深,错误率越低,但实际上却往往会先下降再上升,而ResNet中则几乎会一起下降

参考文献

残差网络会什么有用?

如图,假设有一个大型神经网络,输入为X,输出激活值\(a^{[l]}\),如果想增加这个神经网络的深度,方便起见,假设使用的激活函数都是ReLU,且激活值a大于等于0,

如果增加两层,将这两层看作一个残差块,则\(a^{[l+2]}=g(z^{[l+2]}+a^{[l]})=g(W^{l+2]}a^{[l+1]}+b^{[l+2]}+a^{[l]})\)

如果\(W^{[l+2]}=0,b^{[l+1]}=0\),则\(a^{[l+2]}=g(a^{[l]})\),则\(a^{[l+2]}=a^{[l]}\)

结果表明,残差块学习这个恒等函数并不难,"skip connection"帮助我们很容易得到\(a^{[l+2]}=a^{[l]}\),这也就意味着,即使给这个网络增加了这两层,它的效率也并不逊色于更简单的神经网络

当然,如果这些新增的隐藏层单元可以学到一些有用的信息,那么它可能会比恒等函数表现的更好

image-20201226224639302
image-20201226224639302

网络中的网络(Network in Network)和1×1卷积

为什么1×1卷积?

如图,将一个6×6×1的图片,与一个1×1×1的过滤器作卷积,相当于把这个图片中每个数字乘以2,这对单通道图片而言,看上去并没有什么效果;

但如果是一张6×6×32的图片,与一个1×1×32的过滤器作卷积,

具体来说,1×1卷积所实现的功能是:遍历这36个单元格,计算左图中32个数字和过滤器中32个数字的元素智能乘积(Element wise product),然后应用ReLU非线性函数,得到一个实数,作为输出中的一个元素

image-20201226230148608
image-20201226230148608

1×1卷积可以从根本上理解为:这32个单元都应用了一个全连接神经网络,全连接层的作用是输入32个数字,和过滤器数量,在6×6=36个单元上重复进行,输出结果是6×6×过滤器数量,以便在输入层上实施一个"pretty non-trivial computation",这种方法通常被称为1×1卷积,有时也称为Network in Network

参考文献:Network In Network)

1×1卷积的一个应用

如图,有一个28×28×129的输入层,可以使用池化层压缩它的高度和宽度,但是,如果通道数量很大,该如何压缩呢?

可以使用32个大小为1×1的过滤器,严格地说是1×1×192,输出层为28×28×32,这就是压缩\(n_c\)的方法,然而池化层,则只是压缩了这些层的高度和宽度

image-20201226232038321
image-20201226232038321

Inception Network

Motivation for Inception Network

Inception Network的作用就是你替你决定过滤器的大小究竟是多少或要不要添加池化层等,但它会让网络架构变得更加复杂,但网络表现却很好

如图,是一个28×28×192的输入层,Inception Network或Inception Layer的作用是代替人工决定卷积层中的过滤器类型或确定是否需要创建卷积层或池化层

image-20201227112249498
image-20201227112249498

基本思想是Inception Network不需要选择使用哪个过滤器或是池化,而是由网络自行确定这些参数,然后将这些输出连接起来,让网络自己学习它需要什么样的参数,采用哪些过滤器组合

参考文献:Going deeper with convolutions

计算成本的问题

将重点放在上述图中的5×5过滤器,则如下图

image-20201227113212477
image-20201227113212477

计算这个28×28×32输出的计算成本:

它有32个过滤器,因为输出有32个通道,每个过滤器大小为5×5×192,输出大小是20×20×32,所以要计算(28×28×32)个数字, 对于输出中的每个数字而言,都要执行(5×5×192)次乘法运算,所以乘法运算的总次数为每个输出值所需的乘法运算次数乘以输出值的个数((28×28×32)×(5×5×192))=1.2亿

使用1×1卷积

如图,和上述计算有相同的输入和输出

image-20201227113723554
image-20201227113723554

事实证明,只要合理构建瓶颈层,既可以显著缩小表示层规模,又不会降低网络性能,从而大量节省了计算。

Inception 模块

Inception模块会将之前层的激活或输出作为它的输入

image-20201227172240582
image-20201227172240582

Inception Network

如图,可以发现图中有许多重复的模块,如果只取其中一部分,会发现它就是之前的Inception模块,有的还会有一些额外的最大池化层,Inception Network其实只是许多之前据说的Inception Module在不同位置重复组成的网络。

此外,网络中其实还有一些分支,在网络的最后几层,通常称为全连接层,之后是一个Softmax层来做预测,而这些分支所做的就是通过隐藏层来做出预测,所以其实是一个softmax输出,它确保了即便是隐藏单元和中间层也参与了特征计算,也能预测图片的分类,在Inception Network中直到一种调整的效果,并能防止过拟合

image-20201227173532543
image-20201227173532543

迁移学习

Eg:假设需要建立一个猫的检测器,需要检测图片中的是A类猫还是B类猫还是都不是,忽略两种猫同时出现在一张图片里的情况

现在,对于这个任务,可能没有大量的相关图片,所以训练集会很小,可以从网上下载一些神经网络开源的实现,除了代码外,权重也需要下载,如ImageNet数据集对应的,它有1000个不同的类别,因此有一个Softmax单元,可以去掉这个softmax单元,然后创建用于这个任务的softmax单元来输出A、B、N三个类别,就网络而言,可以将前面所有层都看作是冻结的,网络中所有层的参数都是被冻结的,只需要训练和softmax有关的参数,通过使用其它人预训练的权重,可能可以得到很好的性能,即使只有一个小的数据集。

并且,对于大多数神经网络,都支持这种迁移操作,事实上,取决于使用的框架,也许有trainableParameter=0这样的参数,对于冻结的层,可以设置这个参数来让网络不训练这些权重,有时也是freeze=1等

image-20201227175302682
image-20201227175302682

加速训练的一个技巧:

将冻结部分最后层的计算的特征或激活值,然后存到硬盘中,进而对于每个输入x,可以直接映射到冻结部分的最后输出,相当于在训练时缩短了神经网络的层数。

而如果训练集的大小更大一些,则可以冻结更少的层

image-20201227180138230
image-20201227180138230

而如果训练集足够大,则应该将下载的权重当做初始化,然后训练网络

数据增强(Data Augmentation)

大部分的计算机视觉任务使用很多的数据,数据增强是一种经常用来提高计算机视觉系统表现的技巧

普通增强方法

垂直镜像对称方法(Mirroring):

image-20201227180944240
image-20201227180944240

随机裁剪(Random Cropping):

image-20201227181212935
image-20201227181212935

以上两种是经常被使用的,但理论上,也可以使用旋转(rotation)、剪切(shearing)、局部弯曲(local warping)等

颜色转换

如图,给图片RGB三通道上加减不同的失真值,进行颜色转换

image-20201227181730903
image-20201227181730903

在训练期间实现变形(Implementing distortions during training)

通常将图片数据从硬盘上读取后,可以使用CPU多线性对图片进行变形处理如镜像、变色等,然后将构成的批数据或mini batch传输给其它线程(可以是CPU也可以是GPU)进行训练

image-20201227182327667
image-20201227182327667

将数据加载、增强和训练分开在不同的线程或进程,可以让两个部分并行进行,加快速度

计算机视觉现状

数据和手工工程(Data vs. hand-engineering)

机器学习问题可以看成映射在在数据相对较少和大量数据之间的范围

image-20201227215302872
image-20201227215302872

通常认为学习算法有两种知识来源:

  1. 被标记的数据(x,y)
  2. 手工工程特征或网络体系结构或系统的其它组件

因此,当没有太多的标签数据时,只需要更多地考虑手工工程,因此,计算机视觉在试图学习一个非常复杂的功能时,经常会感觉到没有足够的数据,这可能就是为什么计算机视觉从历史到现在都更多地依赖于手工工程,这也是计算机视觉邻域发展比较复杂网络架构的原因,正是由于缺乏较多的数据,因此,想要更好的表现就需要花更多的时间进行架构设计

做好基准测试或赢得比赛的技巧(Tips for doing well on benchmarks/winning competitions)

  1. 集成(Ensembling)
    • 独立训练一些网络,然后将它们的结果平均后输出
  2. 在测试时使用Multi-crop(Multi-crop at test time)
    • 在多个版本测试图片和平均结果上运行分类器

使用开源代码

  • 使用发布了文献的网络框架
  • 如果可能的话使用已经开源的实现
  • 使用预训练模型并在数据集上微调(fine tune)