卷积网络CNN

卷积网络是近年来非常流行的网络结构,常用于处理图像(2维卷积)和自然语言(1维卷积)。在不明觉厉的情况下使用卷积层,往往使用别人设计的结构,凑参数往模型里塞,同复杂的原理书中的内容又有点对不上号。本篇从应用场景,具体用法入手,深入到每一个重要参数:具体用途、用法及计算方法。

为什么使用卷积网络

先来看看全连接网络的参数:

网络有三个输入x1,x2,x3和两个输出y1,y2,具体计算方法是:

如果y1与x3没有什么关系,通过训练两者之间的参数w31可能趋近于0,但该连接仍然存在。对于输入为3输出为2的网络需要训练32=6个参数。图片数据非常庞大,如果训练一张10001000像素,RGB三通道的图片,则输入元素有3M个,如果第一个隐藏层有1000个元素,则需要训练100010003*1000个参数,使得网络非常庞大,同时需要非常大量的数据才能避免过拟合。

卷积网络的优势在于共享参数,比如一个3x3的检测物体边缘卷积核训练好后,即可用于整个图片,此时需要学习的参数只有3x3=9个,如果在一层中训练20个3x3的卷积核用于检测不同特征,也只需要训练3x3x20=60个参数。

需要注意的问题是使用同样一组参数(卷积核)处理层的多个输入特征时,每组输入特征需要具有共同的性质,才能被处理,比如图片中的每个小区域边缘都具有相同的性质,可使用同种方法检测;但是预测汽车价格时,各个特征都代表完全不同的含义,就无法将不同意义的特征分组后使用同样的方法处理。

具体用法

卷积网络常用于图像处理,它常与池化层同时使用。以Pytorch为例,在模型的init初始化中创建层:

self.conv=torch.nn.Conv2d(3,16,2,stride=1,padding=1)  
self.pool=torch.nn.MaxPool2d(4,4)  

在forward前向传播时使用层:

out = self.conv(X)  
out = self.pool(out)  

传入卷积层的一般是4维数据[m,w,h,c]。此处创建的卷积层可以处理任意大小的图片。构造该层的参数如下:

torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True)  

其中前五个参数最为重要:

  • in_channel:输入通道数
  • out_channel:输出通道数
  • kernel_size:卷积核大小
  • stride:步长
  • padding:扩边

下面从原理角度介绍各个参数的功能。

重要概念

卷积网络的原理如下图所示,一个3x3的卷积核作用于6x6的图片之上,通过每个相邻的3x3区域计算一个值,具体方法是对应点做元素乘法之后相加,映射成右图中的一个点,然后逐步移动(Stride)遍历左图中所有区域,计算出右图中所有点作为输出。

图片来自吴恩达深度学习

kernel卷积核

卷积核kernel,有时也叫作filter,具体的计算方法下:

可以看到乘加的方法与全连接非常相似,不同的是使用卷积核之后,输出y中的每个元素只与部分x元素连接,计算量更小,即稀疏连接;使用同一组f与各个位置的x计算,参数更少,即共享参数。

padding扩边

上图中使用3x3的卷积核对6x6的图片做卷积操作,输出是3x3的图片,输出明显变小了,如果经过多次卷积图片会越变越小,另外,在卷积过程中边缘像素也被弱化了(边缘像素只对少数输出点起作用,使各像素点贡献不均衡)。为解决这一问题,一般工具都提供padding扩边功能,在卷积处理之前,延着边扩一圈(或者几圈),元素填充为0,如图片大小为6x6,padding为1时,图片大小变成8x8。目标是使得输出与处理之前的输入大小一致

卷积可分为Valid Convolutions(带padding)和Same Convolutions(不带padding)两种。padding的大小一般设置为p=(f+1)/2。其中f是卷积核大小,由于上/下,左/右都需要加边,所以除2,可以看到如果卷积核为偶数,则p有小数部分,因此,一般卷积核心都为奇数,以免造成不对称;另外,奇数填充有一个中心点,这样也能更好地描述卷积操作的位置。

stride步长

步长是卷积核在原图上每一步移动的距离。下图是步长为2时,第一步和第二步的卷积操作。

简单地讲就是每次移动几个像素,stride一般设置为1或2,如何设置stride与卷积核大小相关,如果卷积核为3,步长为1,则各个卷积之间有一定的重叠;如果设置为4,则会漏掉一些像素。另外,如果stride设置较大会使输出图片变小,这也起到了一定的池化作用。

输出图片的大小可按以下公式计算:

其中n是图片大小,f是卷积核大小,pad为扩边大小,stride为步长,注意当除法结果非整数时向下取整。

channel通道

通道变换是相对较难以理解的问题,从使用角度看,输入卷积层的是一张256x256x3,即长宽各为256像素,包含RGB三个颜色通道的图片,输出为32x32x16,即大小为32x32,提取了16组特征。下面来看看如何从3通道变成16通道。

如图所示,对三维数据进行三维卷积后,输出为二维(27次元素乘法之后做加法),如果使用16个三维卷积核做卷积,输出则是4x4x16个特征。可以说训练了16个卷积核,用于提取不同的16种特征。对照初始化时的操作,无需指定图片大小,只需指定输入通道数i,输出通道数o,即可提取o种特征。

数据格式

传入conv2d的数据格式一般是4维数组[m,w,h,c],后三维分别是图片的宽高和输入通道数,第一维用于处理多张图片。需要注意的是forward时的输入通道数需要与初始化conv2d时设置的输入通道数一致。

池化层

池化层的主要作用是缩小图片,以及提高鲁棒性。上面提到,通过卷积的步长也能达到使输出变小的效果,池化层的另一个重要功能提高鲁棒性。

池化层一般放置在卷积层之后,用于将某一种特征中的多个值用单个值表示,这里只讨论最简单普通的用法:与卷积层配合使用的池化层。最常见的两种池化分别是最大池化和平均池化,又以最大池化为主。

池化的主要参数也是:大小f,步长s,以及具体的池化方法max/mean。最常见的数池化是f=2,s=2,type=maxpool,如下图所示:

maxpool可看作是提取了最显著的特征,另外,需要注意:

  • 池化可能有两个区域或者多个区域有重叠部分。
  • 池化层没有需要训练的weight参数,也因为这个原因,在描述一个模型的层数时,一般不将池化层计算在内,只作为卷积层的附属。
  • 对于三维数据,池化只对其中的wxh操作,输出的channel大小不变。

瓶颈层

瓶颈层的概念源于GoogleNet中提出inception,inception对输入图像并行执行多个卷积运算和池化操作,并将所有结果拼接为一个非常深地特征图(特征很多)。可以想见,这会引发大量计算,需要很多网络参数。

因此引入了瓶颈层,用于减少计算量,瓶颈指网络中最窄的位置。它常借助1x1的卷积层实现,上面介绍了创建一个卷积层至少需要指定输入通道数,输出通道数,以及卷积核大小,瓶颈层的卷积核大小为1x1,输入通道由输入数据决定,输出通道数人工指定,如果需要将192种特征压缩到16种,则输出通道设为16。因此,可以通过池化层缩减图片宽高,通过瓶颈层缩减通道数。

加入瓶颈层的方法不仅用于图像处理,在自然语言处理及其它功能的网络中也是常用技巧,比如某层输入为10000个元素,输出为1000个元素,则参数数量为10000x1000=10000000,如果加入100元素的瓶颈层,则计算参数为10000x100+1000x100=1100000,计算缩减到之前的十分之一。

卷积网络常规用法

  • 尽量使用论文中的超参数,不要自己从头设置。
  • 网络结构中,一般wxh越来越小,channel越来越大,且常常是成倍减少或增加。
  • 前边是若干卷积层,后面是一个或几个全连接层,最后是softmax。
  • 层间数据越来越少,但不要下降太快。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值