一文带你了解CNN(卷积神经网络)

⼀⽂带你了解CNN(卷积神经⽹络)
⽬录
前⾔
⼀、CNN解决了什么问题?
⼆、CNN⽹络的结构
2.1 卷积层 - 提取特征
卷积运算
权重共享
稀疏连接
总结:标准的卷积操作
卷积的意义
1x1卷积的重⼤意义
2.2 激活函数
高强钢2.3 池化层(下采样) - 数据降维,避免过拟合
2.4 全连接层 - 分类,输出结果
三、Pytorch实现LeNet⽹络
the sartorialist3.1 模型定义
3.2 模型训练(使⽤GPU训练)
3.3 训练和评估模型
前⾔
  在学计算机视觉的这段时间⾥整理了不少的笔记,想着就把这些笔记再重新整理出来,然后写成Blog和⼤家⼀起分享。⽬前的计划如下(以下⽹络全部使⽤Pytorch搭建):
专题⼀:计算机视觉基础
介绍CNN⽹络(计算机视觉的基础)
浅谈VGG⽹络,介绍ResNet⽹络(⽹络特点是越来越深)
介绍GoogLeNet⽹络(⽹络特点是越来越宽)
介绍DenseNet⽹络(⼀个看似⼗分NB但是却实际上⽤得不多的⽹络)
整理期间还会分享⼀些⾃⼰正在参加的⽐赛的Baseline
专题⼆:GAN⽹络
搭建普通的GAN⽹络
卷积GAN
条件GAN
模式崩溃的问题及⽹络优化
  以上会有相关代码实践,代码是基于Pytorch框架。话不多说,我们先进⾏专题⼀的第⼀部分介绍,卷积神经⽹络。
⼀、CNN解决了什么问题?
  在CNN出现之前,对于图像的处理⼀直都是⼀个很⼤的问题,⼀⽅⾯因为图像处理的数据量太⼤,⽐如⼀张512 x 512的灰度图,它的输⼊参数就已经达到了252144个,更别说1024x1024x3之类的彩⾊图,这也导致了它的处理成本⼗分昂贵且效率极低。另⼀⽅⾯,图像在数字化的过程中很难保证原有的特征,这也导致了图像处理的准确率不⾼。
  ⽽CNN⽹络能够很好的解决以上两个问题。对于第⼀个问题,CNN⽹络它能够很好的将复杂的问题简单化,将⼤量的参数降维成少量的参数再做处理。也就是说,在⼤部分的场景下,我们使⽤降维不会影响结果。⽐如在⽇常⽣活中,我们⽤⼀张1024x1024x3表⽰鸟的彩⾊图和⼀张100x100x3表⽰鸟的彩⾊图,我们基本上都能够⽤⾁眼辨别出这是⼀只鸟⽽不是⼀只狗。这也是卷积神经⽹络在图像分类⾥的⼀个重要应⽤。【ps:卷积神经⽹络可以对⼀张图⽚进⾏是猫还是狗进⾏分类。如果⼀张图⽚⾥有猫有狗有鸡,我们要分别识别出每个区域的动物,并⽤颜⾊分割出来,基础的CNN⽹络还能够使⽤吗?这是⼀个拓展思考,有兴趣的读者可以看⼀下FCN⽹络。对⽐之下能够更好的理解CNN ⽹络】
  对于第⼆个问题,CNN⽹络利⽤了类似视觉的⽅式保留了图像的特征,当图像做翻转、旋转或者变换位置的时候,它也能有效的识别出来是类似的图像。
  以上两个问题的解决,都是由于CNN⽹络具有以下优势和特点:局部区域连接、权值共享。在解释这三个特点之前,我们先看⼀下CNN⽹络的三⼤主要结构,卷积层、池化层(或者叫做汇聚层)、全连接层。
⼆、CNN⽹络的结构
2.1 卷积层 - 提取特征
卷积运算
  了解卷积层,我们先要了解⼀下卷积运算。别看它叫做卷积,但是和严格意义上的数学卷积是不同的。深度学习所谓的卷积运算是互相关( cross-correlation )运算。【实际上,经过数学证明发现⽆论⽤严格卷积或互相关运算,卷积层的输出不会受太⼤影响。⽽互相关运算⽐严格卷积运算简洁的多,所以我们⼀般都采⽤互相关运算来替代严格意义上的卷积运算。】我们以⼆维数据为例(⾼ x 宽),不考虑图像的通道个数,假设输⼊的⾼度为3、宽度为3的⼆维张量,卷积核的⾼度和宽度都是2,⽽卷积核窗⼝的形状由内核的⾼度和宽度决定:
  ⼆维的互相关运算。阴影部分是第⼀个输出元素,以及⽤于计算这个输出的输⼊和核张量元素: 0 x 0 + 1x1 + 3x2 +4x3 = 19。由此可见互相关运算就是⼀个乘积求和的过程。在⼆维互相关运算中,卷积窗⼝从输⼊张量的左上⾓开始,从左到右、从上到下滑动。这⾥我们设置步长为1,即每次跨越⼀个距离。当卷积窗⼝滑到新⼀个位置时,包含在该窗⼝中的部分张量与卷积核张量进⾏按元素相乘,得到的张量再求和得到⼀个单⼀的标量值,由此我们得到了这⼀位置的输出张量值。【我们这⾥频繁提到了张量,张量(Tensor)是⼀个多维数组,它是标量、向量、矩阵的⾼维拓展。】
  看了上⾯的内容,可能有读者开始思考,如果这个输⼊矩阵是 4x4,卷积核是3x3,步长为1的时候,在向右移动时,我们发现如果要和卷积核进⾏卷积操作,左便的输⼊矩阵还缺少了⼀列;在⾏的
⽅向也是如此。如果我们忽略边缘的像素,我们可能就丢失了边缘的细节。那么这种情况下我们如何处理呢?这时我们可以进⾏填充操作(padding),在⽤pytorch实现时我们可以在Convd函数中对padding进⾏设置,这⾥我们可以设置padding=1,就能够在⾏和列上向外扩充⼀圈。【ps:实际上当处理⽐较⼤的图⽚,且任务是分类任务时,我们可以不⽤进⾏padding。因为对于⼤部分的图像分类任务,边缘的细节是是⽆关紧要的,且边缘的像素点相⽐于总的像素来讲,占⽐是很⼩的,对于整个图像分类的任务结果影响不⼤】
  对于卷积操作,我们有⼀个统⼀的计算公式。且学会相关的计算对于了解感受野和⽹络的搭建⾄关重要。学会相关的计算,我们在搭建⾃⼰的⽹络或者复现别⼈的⽹络,才能够确定好填充padding、步长stride以及卷积核kernel size的参数⼤⼩。⼀般这⾥有⼀个统⼀的公式:
假设图像的尺⼨是 input x input,卷积核的⼤⼩是kernel,填充值为padding,步长为stride,卷积后输出的尺⼨为output x output,则卷积后,尺⼨的计算公式为:
ps:如果输⼊的图像尺⼨是 mxn类型的,可以通过裁剪 or 插值转换成 mxm or nxn类型的图像;或者分别计算图像的⾼和宽⼤⼩也可以,公式都是类似的。
权重共享
  我们在前⾯有提到过CNN⽹络的⼀个特性是权重共享(share weights)也正是体现在通道处理的过程中。⼀般的神经⽹络层与层之间的连接是,每个神经元与上⼀层的全部神经元连接,这些连接线的权重独⽴于其他的神经元,所以假设上⼀层是m个神经元,当前层是n个神经元,那么共有mxn个连接,也就有mxn个权重。权重矩阵是mxn的形式。那么CNN是如何呢?权重共享是什么意思?我们引⼊下⾯这样⼀张图来帮助我们理解:
  我们先说明上图中各个模块的矩阵格式及关系:
输⼊矩阵格式:(样本数,图像⾼度,图像宽度,图像通道数)
输出矩阵格式:(样本数,图像⾼度、图像宽度、图像通道数)
卷积核的格式:(卷积核⾼度、卷积核宽度、输⼊通道数、输出通道数)
卷积核的输⼊通道数(in depth)由输⼊矩阵的通道数所决定。(红⾊标注)
输出矩阵的通道数(out depth)由卷积核的输出通道所决定。(绿⾊标注)
输出矩阵的⾼度和宽度,由输⼊矩阵、卷积核⼤⼩、步长、填充共同决定,具体计算公式见上⽂。
  当输⼊⼀张⼤⼩为8x8x3的彩⾊图时,我们已经提前设计好了卷积核后的输出通道为5,即卷积核的个数为5【即五个偏置,⼀个卷积核⼀个偏置】(通道数的设计⼀般是实验后得到的较优结果)。每个卷积核去和输⼊图像在通道上⼀⼀对应进⾏卷积操作(即互相关操作,除⾮刻意强调,这⾥所说的卷积都是互相关,步长为1,填充为0),得到了3个6x6的feature map。然后再将三个6x6的Feature map按照Eletwise相加进⾏通道融合得到最终的feature map,⼤⼩为6x6(也就是将得到的三个矩阵逐元素相加,之后所有元素再加上该矩阵的偏置值,得到新的6x6矩阵)。权重共享也是体现在这个过程中。我们单独提取出第⼀个卷积核,当它的第⼀个通道(3x3)与输⼊图像的第⼀个通道(8x8)进⾏卷积操作时,按照普通的神经⽹络连接⽅式其权重矩阵是9 x 81。但是这⾥我们要注意,我们在窗
⼝滑动进⾏卷积的操作权重是确定的,都是以输⼊图像的第⼀个通道为模板,卷积核的第⼀个通道3x3矩阵为权重值,然后得到卷积结果。这个过程中权重矩阵就是3x3,且多次应⽤于每次计算中。权重的个数有9x81减少到3x3,极⼤的减少了参数的数量。综合起来,对于第⼀个卷积核来讲,它的权重矩阵就是3x3x3+1,整个卷积过程的权重⼤⼩为3x3x3x5+5,⽽不是8x8x3x3x3x3x5。权重共享⼤⼤减少了模型的训练参数。权重共享意味着当前隐藏层中的所有神经元都在检测图像不同位置处的同⼀个特征,即检测特征相同。因此也将输⼊层到隐藏层的这种映射称为特征映射。由上我们可以理解,从某种意义上来说,通道就是某种意义上的特征图。输出的同⼀张特征图上的所有元素共享⼀个卷积核,即共享⼀个权重。通道中某⼀处(特征图上某⼀个神经元)数值的⼤⼩就是当前位置对当前特征强弱的反应。⽽为什么在CNN⽹络中我们会增加通道数⽬,其实就是在增加通道的过程中区学习图像的多个不同特征。
磷酸氢二钠稀疏连接
中华医学网  通过上⾯对于卷积的过程以及权重共享的解释,我们能够总结出CNN的另⼀个特征。有⼼的读者其实能够⾃⼰总结出来。我们在上⾯提到过,对于普通的神经⽹络,隐藏层和输⼊层之间的神经元是采⽤全连接的⽅式。然⽽CNN⽹络并不是如此。它的在局部区域创建连接,即稀疏连接。⽐如,对于⼀张输⼊的单通道的8x8图⽚,我们⽤3x3的卷积核和他进⾏卷积,卷积核中的每个元素的值是和8x8矩阵中选取了3x3的矩阵做卷积运算,然后通过滑动窗⼝的⽅式,卷积核中的每个元素(也就是神经元)
只与上⼀层的所有神经元中的9个进⾏连接。相⽐于神经元之间的全连接⽅式,稀疏连接极⼤程度上的减少了参数的数量,同时也⼀定程度上避免了模型的过拟合。这种算法的灵感是来⾃动物视觉的⽪层结构,其指的是动物视觉的神经元在感知外界物体的过程中起作⽤的只有⼀部分神经元。在计算机视觉中,像素之间的相关性与像素之间的距离同样相关,距离较近的像素间相关性强,距离较远则相关性⽐较弱,由此可见局部相关性理论也适⽤于计算机视觉的图像处理。因此,局部感知(稀疏连接)采⽤部分神经元接受图像信息,再通过综合全部的图像信息达到增强图像信息的⽬的。(⾄于我们为什么现在经常采⽤3x3卷积核,因为实验结果告诉我们,3x3卷积核常常能达到更好的实验效果。)
总结:标准的卷积操作
  在进⾏上⾯的解释后,相信⼤家已经对于什么是卷积,卷积的两点特点:稀疏链接和权重共享已经有了了解。下⾯我们来总结⼀般意义的标准的卷积操作:当输⼊的feature map数量(即输⼊的通道数)是N,卷积层filter(卷积核)个数是M时,则M个filter中,每⼀个filter都有N个channel,都要分别和输⼊的N个通道做卷积,得到N个特征图,然后将这N个feature map按Eletwise相加(即:进⾏通道融合),再加上该filter对应的偏置(⼀个filter对应⼀个共享偏置),作为该卷积核所得的特征图。同理,对其他M-1个filter也进⾏以上操作。所以最终该层的输出为M个feature map(即:输出channel等于filter的个数)。可见,输出的同⼀张特征图上的所有元素共享同⼀个卷积核,即共享⼀个权重。不
同特征图对应的卷积核不同。
卷积的意义
  如果⽤图像处理上的专业术语,我们可以将卷积叫做锐化。卷积其实是想要强调某些特征,然后将特征强化后提取出来,不同卷积核关注图⽚上不同的特征,⽐如有的更关注边缘⽽有的更关注中⼼地带等。当完成⼏个卷积层后(卷积 + 激活函数 + 池化)【后⾯讲解激活函数和池化】,如图所⽰:
  在CNN中,我们就是通过不断的改变卷积核矩阵的值来关注不同的细节,提取不同的特征。也就是说,在我们初始化卷积核的矩阵值(即权重参数)后,我们通过梯度下降不断降低loss来获得最好的权重参数,整个过程都是⾃动调整的。
1x1卷积的重⼤意义
  按照道理讲,我是不该这么快就引⼊1x1卷积的,不过考虑到它在各种⽹络中应⽤的重要性并且也不难理解,就在这⾥提前和⼤家解释⼀下1x1卷积是什么,作⽤是什么。  如果有读者在理解完上⽂所提到的卷积后,可能会发出疑问:卷积的本质不是有效的提取相邻像素间的相关特征吗?1x1卷积核的每个通道和上⼀层的通道进⾏卷积操作的时候不是没法识别相邻元素了吗?
  其实不然,1x1卷积层的确是在⾼度和宽度的维度上失去了识别相邻元素间的相互作⽤的能⼒,并且通过1x1卷积核后的输出结果的⾼和宽与上⼀层的⾼和宽是相同的。但是,通道数⽬可能是不同的。
⽽1x1卷积的唯⼀计算也正是发⽣在通道上。它通过改变1x1卷积核的数量,实现了多通道的线性叠加,使得不同的feature map进⾏线性叠加。我们通过下图来更好的认识1x1卷积的作⽤:
  上图使⽤了2个通道的1x1卷积核与3个通道的3x3输⼊矩阵进⾏卷积操作。由图可知,这⾥的输⼊和输出具有相同的⾼度和宽度,输出的每个元素都是从输⼊图像的同⼀位置的元素的线性组合。我们可以将1x1卷积层看做是每个像素位置应⽤的全连接层。同时,我们发现输出结果的通道数⽬发⽣了改变,这也是1x1卷积的⼀个重要应⽤。可以对输出通道进⾏升维或者降维,并且不改变图像尺⼨的⼤⼩,有利于跨通道的信息交流的内涵。降维之后我们可以使得参数数量变得更少,训练更快,内存占⽤也会更少。如果是在GPU上训练,显存就更加珍贵了。
  卷积⽹络的⼀个⾮常重要的应⽤就是ResNet⽹络,⽽ResNet⽹络结构,已经应⽤于各种⼤型⽹络中,可以说是随处可见。这⾥先贴个ResNet中应⽤了1x1卷积的残差块,后⾯会有⼀篇⽂章来解读ResNet⽹络:
2.2 激活函数
  由前述可知,在CNN中,卷积操作只是加权求和的线性操作。若神经⽹络中只⽤卷积层,那么⽆论有多少层,输出都是输⼊的线性组合,⽹络的表达能⼒有限,⽆法学习到⾮线性函数。因此CNN引⼊激活函数,激活函数是个⾮线性函数,常⽤于卷积层和全连接层输出的每个神经元,给神经元引⼊了⾮线性因素,使⽹络的表达能⼒更强,⼏乎可以逼近任意函数,这样的神经⽹络就可应⽤到众多的⾮线性模型中,我们可以⽤公式来定义隐藏层的每个神经元输出公式:
其中,\(b_l\)是该感知与连接的共享偏置,Wl是个nxn的共享权重矩阵,代表在输⼊层的nxn的矩形区域的特征值。
  当激活函数作⽤于卷积层的输出时:
金丹四百字
这⾥的σ是神经元的激励函数,可以是Sigmoid、tanh、ReLU等函数。
2.3 池化层(下采样) - 数据降维,避免过拟合
  在CNN中,池化层通常在卷积或者激励函数的后⾯,池化的⽅式有两种,全最⼤池化或者平均池化,池化主要有三个作⽤:
⼀是降低卷积层对⽬标位置的敏感度,即实现局部平移不变性,当输⼊有⼀定的平移时,经过池化后输出不会发⽣改变。CNN通过引⼊池化,使得其特征提取不会因为⽬标位置变化⽽受到较⼤的影响。
⼆是降低对空间降采样表⽰的敏感性
三是能够对其进⾏降维压缩,以加快运算速度,防⽌过拟合。
  与卷积层类似的是,池化层运算符有⼀个固定的窗⼝组成,该窗⼝也是根据步幅⼤⼩在输⼊的所有区域上滑动,为固定的形状窗⼝遍历每个位置计算⼀个输出。
输出的张量⾼度为2,宽度为2,这四个元素为每个池化窗⼝中的最⼤值(stride=1,padding=0):
  但是,不同于卷积层中的输⼊与卷积核之间的互相关计算,池化层不包含参数。池化层的运算符是
确定性的,我们通常计算池化窗⼝中所有元素的最⼤值或平均值(些操作分别被称为最⼤池化层和平均池化层),⽽不是像卷积层那样将各通道的输⼊在互相关操作后进⾏eletwise特征融合,这也意味着池化层的输出通道数和输⼊通道数⽬是相同的。池化操作的计算⼀般形式为,设输⼊图像尺⼨为WxHxC,宽x⾼x深度,卷积核的尺⼨为FxF,S:步长,则池化后图像的⼤⼩为:
2.4 全连接层 - 分类,输出结果
  我们刚给讲了卷积层、池化层和激活函数,这些在全连接层之前层的作⽤都是将原始数据映射到隐层特征空间来提取特征,⽽全连接层的作⽤就是将学习到的特征表⽰映射到样本的标记空间。换句话说,就是把特征正和岛⼀起(⾼度提纯特征),⽅便交给最后的分类器或者回归。
  我们也可以把全连接层的过程看做⼀个卷积过程,例如某个⽹络在经过卷积、ReLU激活后得到3x3x5的输出,然后经过全连接层转换成1x4096的形式:
  从上图我们可以看出,我们⽤⼀个3x3x5的filter去卷积激活函数的输出,得到的结果是全连接层的⼀个神经元,因为我们有4096个神经元,我们实际上就是⽤⼀个
3x3x5x4096的卷积层去卷积激活函数的输出【不带偏置】。因此全连接层中的每个神经元都可以看成⼀个不带偏置加权平均的多项式,我们可以简单写成。
  这⼀步卷积还有⼀个⾮常重要的作⽤,就是把分布式特征representation映射到样本标记空间,简单说就是把特征整合到⼀起,输出为⼀个值,这样可以⼤⼤减少特征位置对分类带来的影响。
  从上⾯的图,我们可以看出,猫在不同的位置,输出的特征值相同,但是位置不同;对于电脑来说,特征值相同,但是特征值位置不同,那分类结果可能是不⼀样的。此时全连接层的作⽤就是,在展平后忽略其空间结构特性,不管它在哪⼉,只要它有这个猫,那么就能判别它是猫。这也说明了它是⼀个跟全局图像的问题有关的问题(例如:图像是否包含⼀只猫呢)。这也说明了全连接层的结构不适合⽤于在⽅位上patter的任务,例如分割任务(后⾯的FCN就是将全连接层改成了卷积层)。不过全连接层有⼀个很⼤的缺点,就是参数过于多。所以后⾯的像ResNet⽹络、GoogLeNet都已经采⽤全局平均池化取代全连接层来融合学到的特征。另外,参数多了也引发了另外⼀个问题,模型复杂度提升,学习能⼒太好容易造成过拟合。
三、Pytorch实现LeNet⽹络
  LeNet模型是最早发布的卷积神经⽹络之⼀,它是由AT&T贝尔实验室的研究院Yann LeCun在1989年提出的,⽬的是识别图像中的⼿写数字,发表了第⼀篇通过反向传播成功训练卷积神经⽹络的研究。我们现在通过pytorch来实现:。
  LeNet它虽然很⼩,但是包含了深度学习的基本模块。我们先对LeNet结构进⾏⼀个具体的分析,这也是我们搭建任何⼀个神经⽹络之前要提前知道的:
  每个卷积块中的基本单元是⼀个卷积层、⼀个Sigmod激活函数和平均池化层。(虽然ReLU函数和最⼤池化层很有效,但是当时还没有出现)。每个卷积层使⽤5x5卷积核和⼀个Sigmoid激活函数。第⼀个卷积层有6个输出通道,第⼆个卷积层有16个输出通道。每个2x2⾚化操作通过空间下采样将维数减少4倍。卷积的输出形状由(批量⼤⼩,通道数,⾼度,宽度)决定。LeNet中有三个全连接层,分别有120、84、10个输出,因为我们在执⾏⼿写数字的分类任务(⼀共有0-9共10个数字),所以输出层的10维对应于最后
冷冻机组

本文发布于:2024-09-22 06:58:56,感谢您对本站的认可!

本文链接:https://www.17tex.com/xueshu/293356.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:卷积   图像   特征   输出   通道   矩阵   权重   操作
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议