Advertisement

【卷积神经网络】Lesson 2--深层卷积神经网络

阅读量:

课程出处:吴恩达 深度学习专项课程 《卷积神经网络》笔记编写:王小草当前时间为2018年6月6日


outline:

在第1节中,我们将重点讲解5个经典的神经网络模型: LeNet-5(于1998年提出), AlexNet(在2012年的ILSVRC比赛中获得第一名), z-Net(在2013年的ILSVRC比赛中同样夺冠), VGG网络在2014年的ILSVRC比赛中获得亚军,并因其广泛的适用性被应用于多种图像处理任务; GoogleNet于2014年再次问鼎ILSVRC冠军.

接着介绍第2节关于ResNet的内容。

第3节会讲解一个Inception神经网络的实例分析

在深入学习现有的神经网络模型后,你会对如何设计实用的卷积神经网络有更深的理解。

1.经典网络

1.1 CNN的演化

下图展示的是刘昕博士归纳总结的一个CNN演化历史图。该演化过程以早期神经网络模型为起点展开,并在此基础上形成了卷积神经元结构。经典的LeNet网络体系在1998年首次提出。然而随后CNN的表现逐渐被其他技术如SVM等传统手工设计特征的技术所取代。随着ReLU与Dropout技术的成功应用以及GPU加速技术和海量数据的支持,在2012年CNN迎来了具有里程碑意义的历史性突破——AlexNet的成功应用标志着这一阶段的发展达到了一个新的高度

QQ截图20161114113400.png-63.3kB

1.2 Lenet-5

此图为LeNet的结构配置,在当前持续被优化中的CNN架构中也采用了同样的组件布局。

QQ截图20161114113734.png-84kB

Lecun及其合著者在1998年提出了一种基于梯度的方法用于文档识别研究

输入层
输入层是一张黑白图片,大小是32*32(1个颜色通道)。

卷积层1–C1
输入层紧跟其后的一层便是第1个卷积层。该卷积层共有6个滤波器(每个神经元对应一个滤波器),滤波器尺寸为5×5。该过程生成了6张大小均为28×28的特征图,并且每张特征图均捕获了局部空间信息。

该层所包含的可训练参数数量为(5×5+1)×6=156。其中每个卷积核在进行线性运算时会包含一个偏置项bais

如此一来,C1中的链接数共有156*(28*28) = 122304个。

池化层1–S2
池化层亦称下采样模块,在降低网络计算复杂度的同时有效抑制模型过拟合现象。
卷积层C1输出直接连接至卷积层S2输入端,在此过程中减少了网络计算量。
卷积层C1输出直接连接至卷积层S2输入端,在此过程中减少了网络计算量。
卷积层C1输出直接连接至卷积层S2输入端,在此过程中减少了网络计算量.

窗口大小为2*2,步长为2,所以采样之后的S2输出是6 * 14

卷积层2–C3 具有16组滤波器(即16个神经元),同时也可以通过5 \times 5尺寸的滤波器进行计算,从而生成16个大小为10 \times 10的特征图谱。

在C₁层共有六个卷积核,在经过训练后已经增加到了十六个。每个卷积单元负责提取特定区域的特征信息,在此过程中实际反映了该层六种基本特征模式的有效组合。

池化层2–S4
同样,通过对C3的向下采样,输出之后的大小为16 * 5 * 5.

卷积层3–C₅

全连接层 1–F6
该层包含 84 个单元(其数量基于输出层的需求决定),并与前一层 C5 完全连接。该层拥有相当数量的可训练参数(共计 10,164 个)。类似于传统神经网络架构,在 F6 层中将输入向量与权值向量进行点积运算后会加上偏置项;随后将结果传递至 sigmoid 函数以确定单元 i 的最终状态。

输出层–output
输出层由欧氏径向基函数(Euclidean Radial Basis Function)单元构成,并且每个单元都连接84个输入特征。
换句话说,在计算过程中,每个RBF单元评估输入样本与特定参数向量之间的欧氏距离。当输入样本与参数向量的距离越大时,在概率论的角度来看,在F6层中配置空间中定义了一个高斯分布模型后取其负对数似然作为目标函数。给定一个输式样本时,在F6层中配置空间中的高斯分布模型能够反映该样本与其期望分类模式之间的差异程度。因此,在构建损失函数时应确保F6的配置能够充分接近于模式的期望分类位置。

目前实际上很少采用欧式径向基函数作为输出层,在深度学习领域中主要还是依赖于softmax层来进行多分类任务;参考图示说明:

image_1cf5jokvl15q94es1vh61otb1mr49.png-89.1kB

相较于现代版本而言,这个神经网络规模较小仅包含大约60万个参数;现在普遍采用的是拥有1千万到1亿个参数的神经网络。

2.3 Alexnet

AlexNet 被认为是人工智能发展史上的一个重要里程碑,在其之前深度学习领域相对沉寂 long periods. 技术界普遍认为 2012 年是人工智能的重要转折之年,在这一年 AlexNet 在 ImageNet 图像分类挑战赛中实现了显著的技术突破. 这一创新性地实现了与上一年冠军相比 reduce 错误率 by a remarkable margin, 并且远远超出了 runner-up 的水平.

该网络在学术界取得了显著成就,并推动了深度学习技术的重获学术地位。主要原因在于:
(1)激活函数类型采用了ReLU。
(2)防止过拟合的技术包括Dropout和数据增强方法。
(3)基于海量的ImageNet图像数据进行训练。
(4)其他辅助技术包括利用GPU加速运算以及LRN层的引入。
(5)相较于LeNet-5网络结构更为复杂,在参数规模上达到了600万个量级。
使用了local response normalization(此处不详细讨论该层的作用)。

原论文:[Krizhevsky et al.,2012.ImageNet classification with deep convolutional neaural networks]

2.3.1 结构

Alexnet的结构如下:

QQ截图20161114132145.png-47.4kB

还有一张图可能更直观:

image_1cf6in08r1l35b7gacfefr309.png-192.9kB

alexnet一共设置有8个层级结构,在设计上将这些层级划分为两部分:前面的前五部分均为卷积层(其中包括池化模块),而后三部分则为全连接层。根据文章内容可知,在减少任何一个卷积操作的结果都会显著降低模型性能的情况下,在具体实现时应当细致考虑各层次之间的参数配置关系。

conv1:
第一卷积层 输入的图像尺寸为227×227×3像素(论文中可能存在笔误写作224×224×3),配置了96组11×11大小的卷积核(参数配置为[96, 11, 11, 3]),采用每隔4个像素进行滑动或垂直滑动的方式(步长设定为4),从而能够输出96个大小均为55×55的矩形区域响应值。

pool2: 该网络结构中经过响应归一化处理后执行池化操作,在完成池化操作后对输出进行响应归一化处理(实际上是局部响应归一化操作)。这一层与caffe中的alexnet以及论文中提到过caffe网络中使用了两个GPU来加速训练的内容有所不同,在卷积神经网络的第一阶段中采用了不同配置。因此,在卷积神经网络的第一阶段中采用了不同配置。该网络结构中经过响应归一化处理后执行池化操作,在完成池化操作后对输出进行响应归一化处理(实际上是局部响应归一化的实现)。该网络结构中采用了不同于caffe alexnet中的配置设置,在完成池化的过程中设置了一个大小为(3, 3)的窗口并采用步长为2 pixels的方式滑动遍历输入区域,并最终输出了96个大小均为(55 - 3 + 1) = 53 pixels的特征图?等一下这个计算好像有问题,请再核对一下尺寸计算是否正确?

conv3:
该卷积层配置了数量为256的参数设置,在两个GPU上进行了部署,并将每块子核包含128个内核(由大小为5x5x48的空间权重矩阵定义)。该层采用pad_size(2, 2)进行填充处理,并以单像素为间隔滑动窗口操作。经过上述处理后,能够生成大小为[batch_size, 256, 27×27]的空间特征图。

pool4: 实现了LRN过程,并进行了池化操作。使用了大小为3\times 3的矩形框作为池化窗口,并设置每两个像素作为取样间隔。最终提取了256组13\times 13大小的特征向量。

conv5:
使用384个kernels(33384,pad_size=(1,1),得到3841515,kernel_size为(3,3),以1个pixel为步长,得到3841313)

conv6:
使用384个kernels(pad_size(1,1)得到3841515,核大小为(3,3)步长为1个pixel,得到3841313)

conv7:
使用256个kernels(pad_size(1,1)得到3841515,核大小为(3,3)步长为1个pixel,得到2561313)

pool7:
经过一个池化层,pool_size=(3,3),步长为2,得到66256

full8:

full9:
该层神经元个数仍然是4096个

softmax10:
上一层的输出结果会被传递到softmax层进行处理。基于1,000个分类类别,在该网络架构中将会有1,000个神经元分别计算并输出各类的概率值。需要注意的是,在全连接层中包含relu激活函数用于引入非线性特性;随后应用dropout技术以防止过拟合;最后使用innerProduct操作实现线性组合。

Alexnet总共有5个卷积层,具体的数据流如下:

QQ截图20161114132850.png-185.7kB

以下展示了更为系统化的知识架构(源自<>)

QQ截图20161114133243.png-78.5kB
QQ截图20161114133111.png-80.1kB
QQ截图20161114133123.png-91.8kB
QQ截图20161114133137.png-115kB
QQ截图20161114133149.png-82.9kB
2.3.2 优点

平移变换,crop

反射变换,flip

光照、彩色变换,color jittering

根据作者的研究表明

ReLU 激活函数
Sigmoid 是常用的非线性的激活函数, 它能够将输入的连续实值压缩至0至1之间. 特别地, 在输入为非常大的负数时输出为0;而当输入为非常大的正数时输出接近1.
然而它存在几个致命缺陷:
其主要缺陷在于当输入数值过大或过小时会出现饱和现象, 并导致梯度消失. 具体而言, 在数据进入神经元时若均为正值(例如在f=wTx+b中x>0 elementwise), 则权重w所计算出的梯度也会保持正值.
然而通过批处理训练的方法可以一定程度缓解这一问题. 尽管如此, 在提高收敛速度和训练效率方面与前一种方法相比还是略逊一筹.

Alex采用ReLU替代了Sigmoid,并经过实验发现使用ReLU获得的SGD收敛速度显著快于sigmoid/tanh。主要原因是其具有线性特性(因为ReLU的导数始终为1),相较于sigmoid/tanh仅需通过一个阈值即可获得激活值而无需计算大量复杂的运算步骤

Dropout是一种集成多个预先训练好的不同模型用于预测的方法(Ensemble),因其大受欢迎而非常成功地降低了测试集误差。然而由于每个模型都需要大量时间进行训练因此对于大型神经网络而言这种方法过于昂贵。AlexNet团队开发出了一个非常有效的基于集成的方法其所需时间为单一模型的两倍该技术被称为Dropout机制它通过随机移除神经元来防止过拟合具体而言每个隐层神经元有50%的概率被设置为零值从而在正向传播时A层会跳过这一过程同样也不会参与反向传播这一特性使得每次输入样本相当于尝试了不同的网络结构尽管这些结构共享相同的权重参数但能够更好地泛化这些随机子集带来的独特特征正是由于这种特性网络被迫学习更加鲁棒和通用的能力从而在综合这些不同子集特征时表现出色在测试阶段我们采用将所有输出乘以0.5的方法这是一种合理且有效的折中方案用于近似计算指数级Dropout网络产生的预测分布几何平均值

多GPU训练
单个NVIDIA GTX 580显卡仅提供3GB显存资源,在实际应用中会限制可训练网络的最大规模。因此为了提高训练效率通常会将网络模型划分为多个部分分别部署在不同的显卡上进行处理。
现代高性能图形处理器(GPUs)都具备强大的跨显卡并行计算能力这是因为它们可以直接在彼此的显存中进行数据读取和写入操作无需依赖主机内存作为中间介质。
该方法的具体实现策略是在每个显卡内分配一半数量的神经核(或计算单元),并且通过优化设计实现了不同显卡之间的高效通信机制以减少不必要的通信开销。

QQ截图20161114133650.png-47.8kB

比如,在第3层中各通道的权重参数需要从前一层的所有通道输出特征图上进行提取。而在第4层中各通道权重参数仅限于本层位于同一GPU上的各通道输出特征图提取。

2.3.3 AlexNet On Tensorflow

代码位置:
http://www.cs.toronto.edu/~guerzhoy/tf_alexnet/

在tflearn中包含一个alexnet用于分类oxford的例子感到非常兴奋因为基于tflearn对一些常用层进行了封装代码量仅不到50行深入查看了内部layer的具体实现觉得非常不错建议在写代码时可以参考一下这个例子相关的代码地址可以在github上找到具体实现链接为https://github.com/tflearn/tflearn/blob/master/examples/images/alexnet.py

复制代码
    from __future__ import division, print_function, absolute_import
    
    import tflearn
    from tflearn.layers.core import input_data, dropout, fully_connected
    from tflearn.layers.conv import conv_2d, max_pool_2d
    from tflearn.layers.normalization import local_response_normalization
    from tflearn.layers.estimator import regression
    
    import tflearn.datasets.oxflower17 as oxflower17
    X, Y = oxflower17.load_data(one_hot=True, resize_pics=(227, 227))
    
    # Building 'AlexNet'
    network = input_data(shape=[None, 227, 227, 3])
    network = conv_2d(network, 96, 11, strides=4, activation='relu')
    network = max_pool_2d(network, 3, strides=2)
    network = local_response_normalization(network)
    network = conv_2d(network, 256, 5, activation='relu')
    network = max_pool_2d(network, 3, strides=2)
    network = local_response_normalization(network)
    network = conv_2d(network, 384, 3, activation='relu')
    network = conv_2d(network, 384, 3, activation='relu')
    network = conv_2d(network, 256, 3, activation='relu')
    network = max_pool_2d(network, 3, strides=2)
    network = local_response_normalization(network)
    network = fully_connected(network, 4096, activation='tanh')
    network = dropout(network, 0.5)
    network = fully_connected(network, 4096, activation='tanh')
    network = dropout(network, 0.5)
    network = fully_connected(network, 17, activation='softmax')
    network = regression(network, optimizer='momentum',
                     loss='categorical_crossentropy',
                     learning_rate=0.001)
    
    # Training
    model = tflearn.DNN(network, checkpoint_path='model_alexnet',
                    max_checkpoints=1, tensorboard_verbose=2)
    model.fit(X, Y, n_epoch=1000, validation_set=0.1, shuffle=True,
          show_metric=True, batch_size=64, snapshot_step=200,
          snapshot_epoch=False, run_id='alexnet_oxflowers17')

2.4 ZFNet

首先来简单地介绍一下ZFNet这个CNN模型。让我们简单介绍一下这个名为ZFNet的卷积神经网络模型。
ILSVRC比赛于2013年被该模型夺冠。
它是基于Alexnet做出的小幅度优化与调整。
结构如下:

QQ截图20161114141203.png-142kB

ZFNet相较于Alexnet存在两个主要区别:
第一,在卷积层1的设计上,VGG采用了较大的卷积核尺寸(即11×11),并设置了较大的步长(即步长为4);而ZFNet则采用了较小尺寸的卷积核(即7×7)以及较短步长(即步长设置为2)。
第二,在后续多个卷积层中(具体为第3、4、5层),神经元数量相应地从VGG的配置(即384、384、256)进行了升级至ZFNet所采用的新数值(即分别为512、1024、512)。

其余结构与AlexNet完全一致。

ZFNet将top5的错误率从15.4%下降到了14.8%,提升并没有特别惊人。

2.5 VGG

该研究提出了一种深度卷积神经网络模型,在大规模图像识别任务中表现出色。该研究发表于2015年Simonyan&Zisserman的文章中详细描述了该模型的设计与实现

2.5.1 结构

Oxford Visual Geometry Group的研究团队开发了VGGnet,在ILSVRC 2014年的研究中取得了显著成果。该方法的核心贡献在于展示了网络深度增加如何在一定程度上影响网络性能。如图所示,文章通过逐步提升网络深度以改善性能。虽然看似采用了一些直接的方法,并未采取特别巧妙的设计手段,但这种策略确实表现出良好的效果。许多预训练模型采用了VGG架构(主要版本包括第16和第19层),与之相比,VGG架构拥有相当大的参数空间。最终模型具有约500 million个参数,并非所有情况都适用这一规模;而Alnext仅包含约200 million个参数,并非所有情况都适用这一规模;Googlenet则拥有更少的数量级。

QQ截图20161114141739.png-315.7kB
QQ截图20161114141706.png-36.7kB

论文的作者探索了不同类型的CNN模型,在第十六层实现了最佳性能。因此我们通常会采用VGG系列中的模型架构。

以下是VGG每一层的数据维度

QQ截图20161114142056.png-85.6kB

为了估算每层所需的显存资源, 可以通过对其参数数量进行分析来推断. 在使用VGG模型时, 输入一张图片所需的空间约为93 million parameters, 这仅用于前向传播. 如果还需要执行反向传播则需额外增加, 因此在完成反向传播时所需显存将翻倍至186 million parameters.

QQ截图20161114142128.png-516kB
2.5.2 VGG on tensorflow
复制代码
    import tflearn
    from tflearn.layers.core import input_data, dropout, fully_connected
    from tflearn.layers.conv import conv_2d, max_pool_2d
    from tflearn.layers.estimator import regression
    
    # Data loading and preprocessing
    import tflearn.datasets.oxflower17 as oxflower17
    X, Y = oxflower17.load_data(one_hot=True)
    
    # Building 'VGG Network'
    network = input_data(shape=[None, 224, 224, 3])
    
    network = conv_2d(network, 64, 3, activation='relu')
    network = conv_2d(network, 64, 3, activation='relu')
    network = max_pool_2d(network, 2, strides=2)
    
    network = conv_2d(network, 128, 3, activation='relu')
    network = conv_2d(network, 128, 3, activation='relu')
    network = max_pool_2d(network, 2, strides=2)
    
    network = conv_2d(network, 256, 3, activation='relu')
    network = conv_2d(network, 256, 3, activation='relu')
    network = conv_2d(network, 256, 3, activation='relu')
    network = max_pool_2d(network, 2, strides=2)
    
    network = conv_2d(network, 512, 3, activation='relu')
    network = conv_2d(network, 512, 3, activation='relu')
    network = conv_2d(network, 512, 3, activation='relu')
    network = max_pool_2d(network, 2, strides=2)
    
    network = conv_2d(network, 512, 3, activation='relu')
    network = conv_2d(network, 512, 3, activation='relu')
    network = conv_2d(network, 512, 3, activation='relu')
    network = max_pool_2d(network, 2, strides=2)
    
    network = fully_connected(network, 4096, activation='relu')
    network = dropout(network, 0.5)
    network = fully_connected(network, 4096, activation='relu')
    network = dropout(network, 0.5)
    network = fully_connected(network, 17, activation='softmax')
    
    network = regression(network, optimizer='rmsprop',
                     loss='categorical_crossentropy',
                     learning_rate=0.001)
    
    # Training
    model = tflearn.DNN(network, checkpoint_path='model_vgg',
                    max_checkpoints=1, tensorboard_verbose=0)
    model.fit(X, Y, n_epoch=500, shuffle=True,
          show_metric=True, batch_size=32, snapshot_step=500,
          snapshot_epoch=False, run_id='vgg_oxflowers17')

2.残差网络

2.1 残差网络介绍

原论文链接:https://arxiv.org/abs/1512.03385

当神经网络达到相当深度的时候,在反向传播过程中对残差进行求导运算时所得的结果会变得极其微小;因此训练过程会面临巨大的挑战。然而,在实践中发现,随着网络深度的增加其表现往往能够得到显著提升。

为了使神经网络既具有深度又易于训练优化而设法设计出更高效的架构。微软亚洲研究院通过其提出的ResNet模型,在2015年的ILSVRC比赛中实现了突破性胜利;该模型的深度是VGG网络的8倍(总计152层)。这使得ResNet成为当时最深也是最有效的深度学习架构之一。

深层的Convolutional Neural Networks(CNNs)在训练过程中面临梯度衰减的问题。即使采用批归一化技术(Batch Normalization),深度网络依然难以收敛训练。

于是ResNet设计了这样一个结构:residual block

QQ截图20161114151147.png-40kB

F(x)是一个残差的映射,在其基础上叠加从根部传下来的原始信息x,并通过激励函数relu继续往下传递。

从而,原来的每层计算如下:

image_1cf6kva141bl9nb7v2e7d31dlam.png-28.1kB

现在a[l+2]中增添了a[l]的信息:

image_1cf6l0o47rvnksjvt1r9a1g3r13.png-18.2kB

这个传残差的的过程叫做“shot cut”,有时也叫做“skip connection”

整个ResNet的结构可以如下图:

QQ截图20161114152005.png-74.7kB

使用resNet的效果对比:

image_1cf6l698lh9ril01oub1fhf1k6s1g.png-25kB

普通神经网络,在深度递增的情况下(随着深度逐步提升),其训练误差随之增大;而采用残差网络,则无论深度如何提升(不论是逐步增加还是大幅提高),其训练误差均呈现逐渐下降趋势。

2.2 Deep Residual Network tflearn实现

复制代码
    from __future__ import division, print_function, absolute_import
    
    import tflearn
    
    # Residual blocks
    # 32 layers: n=5, 56 layers: n=9, 110 layers: n=18
    n = 5
    
    # Data loading
    from tflearn.datasets import cifar10
    (X, Y), (testX, testY) = cifar10.load_data()
    Y = tflearn.data_utils.to_categorical(Y, 10)
    testY = tflearn.data_utils.to_categorical(testY, 10)
    
    # Real-time data preprocessing
    img_prep = tflearn.ImagePreprocessing()
    img_prep.add_featurewise_zero_center(per_channel=True)
    
    # Real-time data augmentation
    img_aug = tflearn.ImageAugmentation()
    img_aug.add_random_flip_leftright()
    img_aug.add_random_crop([32, 32], padding=4)
    
    # Building Residual Network
    net = tflearn.input_data(shape=[None, 32, 32, 3],
                         data_preprocessing=img_prep,
                         data_augmentation=img_aug)
    net = tflearn.conv_2d(net, 16, 3, regularizer='L2', weight_decay=0.0001)
    net = tflearn.residual_block(net, n, 16)
    net = tflearn.residual_block(net, 1, 32, downsample=True)
    net = tflearn.residual_block(net, n-1, 32)
    net = tflearn.residual_block(net, 1, 64, downsample=True)
    net = tflearn.residual_block(net, n-1, 64)
    net = tflearn.batch_normalization(net)
    net = tflearn.activation(net, 'relu')
    net = tflearn.global_avg_pool(net)
    # Regression
    net = tflearn.fully_connected(net, 10, activation='softmax')
    mom = tflearn.Momentum(0.1, lr_decay=0.1, decay_step=32000, staircase=True)
    net = tflearn.regression(net, optimizer=mom,
                         loss='categorical_crossentropy')
    # Training
    model = tflearn.DNN(net, checkpoint_path='model_resnet_cifar10',
                    max_checkpoints=10, tensorboard_verbose=0,
                    clip_gradients=0.)
    
    model.fit(X, Y, n_epoch=200, validation_set=(testX, testY),
          snapshot_epoch=False, snapshot_step=500,
          show_metric=True, batch_size=128, shuffle=True,
          run_id='resnet_cifar10')

3.3 1*1卷积

那么1×1卷积的作用是什么?听起来有点滑稽哦。实际上它的应用非常广泛。
在该网络架构中,在输入层接收到了一张大小为6×6、通道数为32的图像,在经过一层使用标准卷积核(尺寸为1×1、深度为32)进行操作后会生成新的特征图矩阵...

image_1cf884qkl1f8n1uitv39rvv1uubm.png-70.2kB

这个过程称为1*1卷积,或者网络中的网络

通常在通道数量非常大的情况下(即当通道数目极大时),我们才会考虑采用1×1卷积的操作。然而池化层无法缩减hight和width的空间尺寸(即高度与宽度),但池化层无法缩减通道的数量(即height与width)。然而通过应用1×1卷积操作则能够有效缓解这一问题(即能够有效减少通道的数量)。通过应用这些操作可以使模型在不显著增加计算量的情况下显著提升性能。

来个例子:

image_1cf88v757d8l1e2t1untvusncl13.png-68.3kB

输入尺寸为28×28×192。其中通道数量高达196(即使用具有相同高度、宽度和原始深度但不同 learnable parameters 的),这种设计使得计算量大幅降低的同时还能保持足够的表示能力。这样处理后输出尺寸将变为3^{*} 3^{*} 3^{*} 3^{*} 3^{*}。同样地,在需要扩展通道数量时可以通过类似方法实现。
(例如,在Inception网络中)

4. 谷歌Inception网络

在构建神经网络的过程中,我们需要规划多少个滤波器数量呀?滤波器尺寸又是多大呢?每层应该设置多少个卷积块与池化层呢?这些问题都是需要考虑的。而Inception网络尤其能提供指导,在于它能够系统地帮助我们确定这些参数设置。然而这使得网络架构变得更加复杂了。不过这并没有影响到其优异的性能表现。

4.1 Inception结构

假设有一个2828192的输入

image_1cf93b625hk11jfl1lopur6qrf1g.png-19.9kB

不知道要用多少大小的卷积核去卷积,因此先用64个11卷积核,得到2828*64的输出

image_1cf93dchb1meftjhj781726nps1t.png-40.7kB

接着在用128个33的卷积核,得到2828*128的输出,将这个输出叠加在已有的输出上

image_1cf93g5gg1mev1h221olpvf9l7b2a.png-55.6kB

再接着用32个55的卷积核,得到2828*32的输出,再叠加到已有输出上

image_1cf93k3tn675nvv3b12j212572n.png-74.1kB

再增加一个池化层,并使用32个1×1尺寸的卷积核(kernel),步长设为1,则这样处理后会得到大小为28\times 28\times 32的结果特征图(feature map)。接着将这一结果叠加到现有的特征图上

image_1cf93n0b69jkjn513np1o8v18ok34.png-88.6kB

通过将所有输出进行叠加操作后可获得通道数达到28×28×256的特征图,并且这一过程也即Inception网络体系结构的基础来源:Szegedy et al. 2014. Going Deeper with Convolutions

基于之前的分析可知, 我们包括了三类卷积操作, 单独一类池化操作. 为了简化设计流程, 我们不需要让模型去手动选择究竟采用哪一种卷积层或是否需要池化与卷积操作, 而是让网络在训练过程中自动生成参数, 并根据性能动态选择相应的卷积类型. 这种设计虽然简化了人工决策过程, 但也带来了计算开销的增加

4.2 Inception的问题-计算量大

以5*5的卷积核为例来看看它的计算量。

image_1cf949snu1pq51d3113ds10371gtd3h.png-51.3kB

输入是2828192,卷积核大小是55,有32个,因此总的计算量是28283255192 = 1.2亿。吓人。

解决方案是上一节介绍的一种基于深度可分离卷积的方法。通过采用3\times3深度可分离卷积模块,在输入为B_0的情况下(即B_0=3×3×M_{in}×N_{in}),输出特征图的空间尺寸将从H×W×C_{in}减少到H×W×C_{out}。在该基础上再进行一次5x5标准卷积操作,则整个网络计算量得到显著降低。具体而言,在第一部分中计算得到总运算量为:\sum\limits_H \sum\limits_W 3\times 3\times C_in = B_0^{\text{step} 1};而在第二部分中则有:\sum\limits_H \sum\limits_W 5\times 5\times C_out = B_0^{\text{step} 2}。与之前相比总运算量下降了约97%

image_1cf94h98e1gck2th18afcsn18a33u.png-63.8kB

中间的这个282816的输出层,有时我们称之为瓶颈层(bottleneck layer)

4.3 构建完整的Inception网络

回顾一下Inception模块

image_1cf95aoqaeh18vu1up1fk21b7i4o.png-216.1kB

输入时前一层的激活函数的输出,大小有2828192

中间过程做4个类型的堆叠:
(1)直接进行11卷积,输出282864
(2)进行3
3卷积,但是为了减小计算量,前面先放了一个11卷积,使channel层数目由192下降到了96,最终输出2828128
(3)进行5
5卷积,同样为了减小计算量,前面先放了一个11卷积,使channel层数目由192下降到了16,最终输出282832
(4)池化,输出28
28192,然后用11卷积将192下降到了32

最终左右结果堆叠在一起输出2828256

完整的Inception网络结构图:

image_1cf9598vkf4rubp17on3drd0v4b.png-106.2kB

实际上密集恐惧症并非如看上去那样令人害怕,而是由多个Inception模块构成,在其中穿插了一些max pool层来减小height和width.

论文中完整的网络架构中包含了一些细节部分,在这些隐藏层通常会连接到全连接层和Softmax层用于分类任务的同时,能够有效防止模型过拟合。

image_1cf95td3c1me27vv1dbr19d62df55.png-180.2kB

为什么要取名为Inception呢?看过电影《Inception(盗梦空间)》的不解释。

4.4 GoogLeNet

参考博客“http://hacker.duanshishi.com/?p=1678

Google在ILSVRC 2014竞赛中夺冠,其设计灵感源自经典算法LeNet-5的基础,由Google研究团队开发。参考文献可查阅Going Deeper with Convolutions一文。在相关领域的工作主要集中在提升传统卷积神经网络(CNN)的表现上,其中包括了AlexNet网络之前的诸多创新技术,其中最引人注目的是 Network-in-Network 模型通过简洁的参数架构显著超越了当时的性能水平。该模型仅包含约29 million parameters,就实现了超越AlexNet的目标。该研究 borrow and improve upon the fundamental ideas of Network-in-Network架构

QQ截图20161114144415.png-170.6kB

总体结构:

1.包括Inception模块的所有卷积,都用了修正线性单元(ReLU);

2.网络的感受野大小是224x224,采用RGB彩色通道,且减去均值;

分别表示使用1×1卷积核的缩减层中参数数量;池化投影层经过max-pooling后的投影层中1×1卷积核的数量;这些缩减层和投影层都需要应用ReLU激活函数。

该网络拥有22个具有可学习参数的模块(若计入池化层则共计为27个);其中大部分以独立构成模块的形式存在,并且这些独立构成模块的数量约为100个左右。

  1. 网络中间各层提取出的特征具有较强的区分度,在此基础上设计了一种引入辅助分类器的方法。具体而言,在Inception模块4a及4b输出端引入了一些小尺寸卷积神经网络作为辅助分类器。通过这种设计,在训练阶段中,在计算总损失时会将每层经过折扣处理后的权重(其中折扣系数设定为0.3)进行累加。

辅助分类器的具体细节:

1.均值pooling层滤波器大小为5x5,步长为3,(4a)的输出为4x4x512,(4d)的输出为4x4x528;

2.1x1的卷积有用于降维的128个滤波器和修正线性激活;

3.全连接层有1024个单元和修正线性激活;

4.dropout层的dropped的输出比率为70%;

全连接层负责将softmax损失函数作为分类器(与主分类器相同,在识别1000个类别时起作用),但在推理阶段移除该功能。

5.使用开源的实现方案

我们在先前的内容中探讨了若干经典的神经网络架构。今天我们将重点讲解这些模型的具体应用方法。深入阅读论文后,在全面理解其理论架构的基础上,请注意以下几点:第一,在动手实现这些算法之前,请确保您已充分理解相关背景知识;第二,请尽量利用现有的工具包来缩短实现时间;第三,在复现过程中切勿简单模仿现有方案;第四,在复现过程中请尽量保留创新思维。虽然动手实现这些算法确实耗时费力,并且难以完全复制作者的研究成果。由于构建神经网络所涉及的技术细节实在过于繁多,并非所有关键点都能够在论文中一一罗列清楚。因此我们需要通过其他途径获取更多关于该模型的信息(如果可能的话)。

获取开源代码库。通过Github平台搜索与之相关的关键词。筛选出相关项目后即可完成本地环境搭建。(建议您参考Github官方文档或网络资源了解详细步骤)

6.迁移学习(transfer learning)

从零开始搭建神经网络模型,并对其中的参数进行初始化及后续的系统性训练工作往往耗时耗力且效率低下。相反地,则可以直接利用现成的经过良好训练的模型来进行预训练工作以达到事半功倍的效果

详细说明迁移学习的方法论

而基于数据集A训练得到的神经网络模型,在实际应用中我们通常会采用一些主流开源框架(特别提醒:在GitHub上下载源码时,请确保同步同步模型权重)。

迁移学习为何被采用?在源领域训练获得的关键属性能够帮助目标领域数据集中的算法性能得到提升(例如拓扑关系和几何特性等其中某些特性可能具有参考价值)。

什么时候进行迁移学习?
(1)任务A和B要求两者的输入类型需一致。
(2)在面对目标问题时若其数据量有限,则建议首先利用大量通用数据进行预训练后再转入目标任务进行微调。
(3)当A的数据能够提供有助于提取B相关特征的信息时

7.数据增强(data augmentation)

训练神经网络通常依赖大量的数据;然而,在现实世界中获得这些数据仍然非常困难;因此为了扩大现有数据集的数量而采用data augmentation技术。

对于图像有以下几种数据增强的方式:

常用的方式
(1)Mirroring镜像翻转

image_1cf98f8rh1tsc6mu10rugfm1fv09.png-129.3kB

(2)Random Cropping随机裁剪

image_1cf98gtve13cd199l18dn1d0kis3m.png-159.4kB

这种方法并非完美无缺的数据增强手段。它可能导致模型未能准确识别特定物体进而影响学习效果。然而,在海量数据情况下这种轻微的干扰也不会显著影响整体效果。

(3)Rotation旋转
(4)Shearing扭曲
(5)local warping局部弯曲

color shifting

image_1cf98r493cjt1rnp1kn0p3c1q3b1j.png-266kB

RGB的采样方式:PCA(主成分分析法/PCA颜色增强)

8.论文与比赛中表现好的小技巧

如果在基准数据集上的表现优异,则通常容易发表论文。因此研究者们通常会专注于提升模型在基准数据集上的性能,并致力于构建高效的预测系统;然而,在实际应用场景中这些策略有时效果有限。具体来说以下是一些实用建议:

image_1cf9a057813873dj1utmdj5128k2g.png-99.5kB

要做的是, 让分类器对这10张图片进行预测, 并取其平均值(同时也会增加计算负担)。 (3)采用开源框架: (i)已有研究提出的神经网络架构设计;(ii)现成的开源实现方案;(iii)在其数据集基础上进行微调训练以适应自身需求。

要做的是, 让分类器对这10张图片进行预测, 并取其平均值(同时也会增加计算负担)。 (3)采用开源框架: (i)已有研究提出的神经网络架构设计;(ii)现成的开源实现方案;(iii)在其数据集基础上进行微调训练以适应自身需求。

全部评论 (0)

还没有任何评论哟~