吴恩达老师深度学习视频课笔记:深度卷积网络

        Why look at case studies?:过去几年,计算机视觉研究中的大量研究都集中在如何把卷积层、池化层以及全连接层这些基本构件组合起来形成有效的卷积神经网络。找感觉最好的方法之一就是去看一些案例,就像很多人通过看别人的代码来学习编程一样。实际上,在计算机视觉中表现良好的神经网络框架往往也适用于其它任务。也就是说,如果有人已经训练或者计算出擅长识别猫、狗、人的神经网络或者神经网络框架,而你的计算机视觉任务是构建一个自动驾驶汽车,你完全可以借鉴别人的神经网络框架来解决自己的问题。经典网络(classic networks)包括:LeNet-5、AlexNet、VGG。ResNet又称残差网络是一个152层的神经网络。Inception。

        经典网络:LeNet-5、AlexNet、VGGNet.

        LeNet-5:假设有一张32*32*1的图像,如下图所示,LeNet-5可以识别图像中的手写数字。LeNet-5是针对灰度图训练的。第一层使用6个5*5的过滤器,步幅为1,padding为0,输出结果为28*28*6,然后进行平均池化操作,过滤器的宽度为2,步幅为2,输出是一个14*14*6的矩阵。接下来是卷积层,用一组16个5*5的过滤器,步幅为1,padding为0,输出为10*10*16的矩阵,然后又是池化层,过滤器的宽度为2,步幅为2,输出为5*5*16的矩阵。下一层是全连接层,在全连接层中有400(5*5*16)个节点,每个节点有120个神经元,接下来又是一个全连接层,有84个神经元,然后得到最后的输出预测y’的值,y’有10个可能的值,对应识别0--9这10个数字。在现在的版本中,使用softmax函数输出10种分类结果。


        AlexNet:首先用一张227*227*3的图像作为输入,如下图所示,第一层使用96个11*11的过滤器,步幅为4,输出为55*55*96,然后用一个3*3的过滤器构建最大池化层,步幅为2,输出为27*27*96;接着再执行5*5的卷积,采用same padding,输出为27*27*256,然后在进行最大池化,过滤器为3*3,步幅为2,输出为13*13*256;再执行一次与上一步相同的卷积,相同的padding,输出为13*13*384,再作一次3*3相同卷积,输出为13*13*384,再作一次同样的操作,输出为13*13*256,最后再进行一次最大池化,输出为6*6*256即9216个单元;然后是两个全连接层,神经元数分别为4096,4096;最后使用softmax函数输出识别的结果,看它究竟是1000个可能对象中的哪一个。


        VGG-16:VGG也叫VGG-16网络,它没有那么多超参数,卷积层过滤器为3*3,步幅为1,采用same padding,池化层采用最大池化,f为2*2,步幅为2*2,VGG-16简化了神经网络结构。假设224*224*3作为输入,如下图所示,在最开始的2个卷积层,用64个3*3的过滤器进行卷积,输出为224*224*64,接下来池化层,输出为112*112*64;然后又是2次卷积层,使用128个过滤器,输出为112*112*128,然后进行池化,输出为56*56*128;然后又是3个卷积层,使用256个过滤器,输出为56*56*256,然后进行池化,输出为28*28*256;然后再进行3次卷积,在池化;在进行3次卷积,在池化,将最后得到的7*7*512的特征图进行全连接操作,得到4096个单元,然后进行softmax激活,输出从1000个对象中识别的结果。VGG-16的这个数字16,是指在这个网络中包含16个有权值的层。


        残差网络(Residual Networks, ResNets):非常非常深的网络是很难训练的,因为存在梯度消失和梯度爆炸问题。跳远连接(skip connections),它可从某一网络层获取激活,然后迅速反馈给另外一层,甚至是神经网络的更深层。我们可以利用跳远连接构建ResNets,它使我们可以训练非常深的网络,有时深度能够超过100层。ResNets是由残差块(residual block)构建的。所谓残差块,如下图所示,这是一个两层神经网络,在L层进行激活,得到a[l+1],再次进行激活得到a[l+2]。计算过程从a[l]开始,首先进行线性激活得到z[l+1],然后通过ReLU非线性激活得到a[l+1];接着再次进行线性激活得到z[l+2],最后通过ReLU非线性激活得到a[l+2]。换句话说,信息流从a[l]到a[l+2],需要经过以上所有步骤。在残差网络中有一点变化,我们将a[l]直接快进拷贝到神经网络的深层,在应用ReLU非线性激活前加上a[l],这是一条捷径(shortcut),a[l]的信息直接到达神经网络的深层,不再沿着主路径传递,等式a[l+2]=g(z[l+2])变为a[l+2]=g(z[l+2]+a[l]),也就是加上的这个a[l]产生了一个残差块。a[l]插入的时机是在线性激活之后ReLU激活之前。有时候,除了shartcut,还有另一个术语”跳远连接(skip connection)”,就是指a[l]跳过一层或者好几层,从而将信息传递到神经网络的更深层。使用残差块能够训练更深的神经网络。所以构建一个ResNet网络就是通过将很多这样的残差块堆积在一起形成一个深度神经网络。


        Residual Network:如下图,原始是一个普通网络(plain network),把它变成ResNet的方法是加上所有跳远连接,每两层增加一个捷径,构成一个残差块。5个残差块连接在一起,构成一个残差网络。如果我们使用标准优化算法训练一个普通网络,比如梯度下降等其它热门优化算法,如果没有多余的残差,凭经验,你会发现随着网络深度的加深,训练误差会先减少然后增多;而理论上,随着网络深度的加深,应该训练得越来越好才对,也就是说,理论上网络深度越深越好,但实际上,如果没有残差网络,对于一个普通网络来说,深度越深意味着用优化算法越难训练。而实际上,随着网络深度的加深,训练误差会越来越多。但是有了ResNets就不一样了,即使网络再深,训练误差也会减少,就算训练深达100层的网络也不例外。


        Why ResNets work:一个网络深度越深,它在训练集上训练网络的能力会有所减弱,这也是有时候我们不希望加深网络的原因。而事实并非如此,至少在训练ResNet网络时并不完全如此。假设有一个大型神经网络,如下图所示,其输入为X,输出激活值a[l]。如果你想增加这个神经网络的深度,再给这个网络额外添加两层,最后输出为a[l+2],可以把这两层看作一个ResNet块,即残差块。假设在整个网络中使用ReLU激活函数,所以激活值都大于等于0.a[l+2]=g(z[l+2]+a[l])=g(w[l+2]*a[l+1]+b[l+2]+a[l])=g(a[l])=a[l],(如果假设w[l+2]=0,b[l+2]=0,g(a[l])是应用于非负数的ReLU函数)。结果表明,残差块学习这个恒等式函数(identity function)残差块并不难。因为跳远连接(skip connection)使我们很容易得出a[l+2]=a[l]。这意味着,即使给神经网络增加了这两层,它的效率也并不逊色于更简单的神经网络,因为学习恒等式函数对它来说很简单。尽管它多了两层,也只是把a[l]的值赋给a[l+2].所以,给大型神经网络增加两层,不论是把残差块添加到神经网络的中间还是末端位置都不会影响网络的表现。当然,我们的目标不仅仅是保持网络效率,还要提升它的效率,想象一下,如果这些隐层单元学到一些有用信息,那么它可能比学习恒等式函数表现的更好,而这些不含有残差块或跳远连接的深度普通网络情况就不一样了,当网络不断加深时,就算是选择用来学习恒等式函数的参数都很困难,所以很多层最后的表现不但没有好反而更糟。残差网络起作用的主要原因就是这些残差块学习恒等式函数非常容易。


        将ResNet用于图像识别:如下图,这是一个普通网络,输入是一张图像,它有很多卷积层,最后输出一个Softmax;如果把它转换成ResNet,只需要添加跳远连接。这个网络有很多层3*3卷积,而且它们大多都是相同的,这就是添加等维特征向量的原因,所有这些都是卷积层而不是全连接层,因为它们是相等的卷积,维度得以保留。ResNet类似于其它很多网络,也会有很多卷积层,其中偶尔会有池化层或类似于池化层的层。


        Network in Network and 1*1 convolutions:如下图,filter为1*1*1,值为2,输入是一张6*6*1的图像,然后做卷积,结果相当于把这个图像中的值乘以2;如果是一张6*6*32的图像,使用的filter为1*1*32,然后应用ReLU,输出结果为6*6*1,如果有n个filter,则输出结果为6*6*n。因此,在这里,1*1卷积可以理解为这32个神经元都应用了一个全连接神经网络,全连接层的作用是输入32个数字和filter数量,标记为nc[l+1],在36个positions上重复此过程,输出结果为6*6*filter数量。1*1卷积有时也被称为network in network。


        谷歌Inception网络简介:Inception网络的作用就是用来确定在构建卷积层时该如何决定filter的大小及要不要添加pooling层。如下图,输入层为28*28*192,而Inception网络或Inception层的作用就是代替人工确定卷积层中的filtersize,或确定是否需要创建卷积层或池化层。如果使用1*1filter做卷积,假设输出为28*28*64;如果使用3*3的filter,输出是28*28*128;然后把第二个输出值堆积到第一个输出值上;如果使用5*5的filter,输出是28*28*32;如果使用池化操作,这里池化后输出是28*28*32;依次把上面这些输出堆积起来。有了这样的Inception模块,你就可以输入某个量,作为输出,它累加了所有数字,这里的最终输出为32+32+128+64=256。Inception模块的输入为28*28*129,输出为28*28*256.这就是Inception网络的核心内容。基本思想是Inception网络不需要人为决定使用哪个filter,或者是否需要pooling,而是由网络自行确定这些参数,你可以给网络添加这些参数的所有可能值,然后把这些输出连起来,让网络自己学习它需要什么样的参数,采用哪些filter组合。


        Inception模块中计算成本问题:如下图,已上图中的5*5 filter为例,输入为28*28*192,输出为28*28*32,它有32个filter,因为输出有32个channels,每个filter的size为5*5*192,那么总的乘法运算次数为(28*28*32)*(5*5*192)结果等于1.2亿次,即使用现代计算机乘以1.2亿次乘法运算,成本也是相当高的。假设使用1*1的filter,为了降低计算成本,我们用计算成本除以因子10,结果它从1.2亿减少到原来的十分之一。


        还有另外一种架构,如下图,其输入为28*28*192,输出为28*28*32,先使用16个1*1*192的filter,输出中间结果为28*28*16,然后在使用32个5*5*16的filter,最终输出结果为28*28*32。最终的输入和输出和之前相同。但我们要做的就是把左边的大的输入层,压缩成这个较小的中间层,有时被称为瓶颈层(bottleneck layer),这个计算成本为(28*28*16)*(1*1*192)约为240万,第二个卷积层的计算成本为(28*28*32)*(5*5*16)约为1000万,这两层的计算成本之和是1240万。与之前的值做比较,计算成本从1.2亿降到了1240万,原来的十分之一。所进行的加法运算次数与乘法的运算的次数近似相等,所以只统计了乘法运算的次数。可以通过使用1*1的filter来构建瓶颈层从而大大降低计算成本。事实证明,只要合理构建瓶颈层,你既可以显著缩小表示层规模,又不会降低网络性能,从而大量节省了计算。


        总结,如果你在构建神经网络层的时候,不想决定pooling层使用1*1,3*3还是5*5的filter,那Inception模块就是最好的选择。我们可以应用各种类型的filter,只需把输出连接起来。可以使用1*1的filter来降低计算成本。

        Inception网络:如下图,这就是一个Inception模块。而Inception网络所要做的就是将这些模块都组合到一起。


    下图是一个Inception网络,图中每一个红框其实都是一个Inception模块,绿色框的最后一层为softmax用来作预测。这个特别的网络叫做GoogLeNet。Inception网络无非是很多Inception模块一环接一环,最后组成了网络。


        使用开源的实现方案:事实证明很多神经网络难以复制,因为一些参数调整的细节问题。如果你看到一篇研究论文,想应用它的成果,你应该考虑做一件事,在网络上寻找一个开源的实现。因为你如果想得到作者的实现,通常要比你从头开始实现快的多。

        迁移学习:如果你要做一个计算机视觉的应用,相比于从头训练权重,或者说从随机初始化权重开始,不如你下载别人已训练好的网络结构的权重,你通常能够进展的相当快。用这个作为预训练,然后转换到你感兴趣的任务上。计算机视觉的研究社区,非常喜欢把许多数据集上传到网上,比如ImageNet,MS COCO或者Pascal类型的数据集。你可以下载花费了别人几周甚至几个月而做出来的开源的权重参数,把它当作一个很好的初始化用在自己的神经网络上。用迁移学习把公共的数据集的知识迁移到你自己的问题上。如下图,假如说你要建立一个猫的检测器用来检测你自己的宠物猫,Tigger,Misty或者Neither,忽略两只猫同时出现在一种图的情况。你现在可能没有Tigger和Misty的大量图像,所以你的训练集会很小。此时可以从网上下载一些神经网络的开源实现,不仅把代码下载下来也要把权重(weights)下载下来。有许多训练好的网络你都可以下载,例如ImageNet,它有1000个不同的类别,因此这个网络会有一个Softmax单元,它可以输出1000个可能类别之一。你可以去掉这个Softmax层,创建你自己的Softmax单元用来输出Tigger,Misty,Neither三个类别。就网络而言,建议你把所有的层都看作是冻结的(frozen)。你冻结的网络中包含所有层的参数,你只需要训练和你的Softmax层有关的参数。这个Softmax层有三个可能的输出。通过使用其他人预训练的权重,你很可能得到很好的性能,即使只有一个小的数据集。幸运的是,大多数深度学习框架都支持这种操作,事实上,取决于用的框架。如果你的数据越多,你可以冻结越少的层,训练越多的层。这个理念就是,如果你有一个更大的训练集,也许有足够多的数据,那么不要单单训练一个Softmax单元,而是考虑训练中等大小的网络,包含你最终要用的网络的后面几层。最后,如果你有大量数据,你应该做的就是用开源的网络和它的权重把整个当作初始化然后训练整个网络。


        数据增强(data augmentation):大部分的计算机视觉任务使用很多的数据,数据增强是经常使用的一种技巧来提高计算机视觉系统的表现。在当下,计算机视觉的主要问题是没有办法得到充足的数据。计算机视觉中常见的数据增强方法,如下图:(1)、垂直镜像对称(mirroring on the vertical axis);(2)、随机裁剪(random cropping)。理论上,你还可以使用旋转(rotation)、剪切(shearing)、局部扭曲(local warping)。


        第二种经常使用的方法是色彩转换(color shifting),如下图,给R、G、B三通道加上不同的失真值(different distorition)。对R、G、B有不同的采样方式,其中一种影响颜色扭曲的算法叫PCA即主成分分析,有时候被称作PCA颜色增强。


        计算机视觉现状:深度学习已经成功地应用于计算机视觉、自然语言处理、语言识别、在线广告、物流还有许多其它问题。

        GitHubhttps://github.com/fengbingchun/NN_Test  

猜你喜欢

转载自blog.csdn.net/fengbingchun/article/details/80786455