深度学习入门第七章----卷积神经网络

7.1 整体结构

        CNN和之前的神经网络一样,可以通过组装层来构建,不过CNN中出现了卷积层(convolution层)和池化层(pooling层)。之前介绍的神经网络中,相邻层的所有神经元之间都有连接,这称为全连接。使用Affine层实现了全连接层,一个5层的全连接神经网络可以通过下图实现。

        如上图所示,全连接的神经网络中,Affine层后面跟着激活函数ReLU层(或sigmoid层) ,堆叠了4层,最后由Softmax层输出最终结果。

        CNN的一个例子如下

         如上图所示,CNN新增了conv层和pooling层。可以理解为之前的Affine-ReLU连接被替换成convolution-ReLU-(pooling)连接。靠近输出的层使用了之前的Affine-Softmax组合。

7.2 卷积层

        CNN中各层传递的数据是有形状的数据(比如三维数据),这与之前的全连接网络不同。

7.2.1 全连接层出现的问题

        之前的全连接神经网络使用了全连接层(Affine层)。全连接层中,相邻层的神经元全部连接在一起,输出的数量可以任意决定。全连接层的问题是,数据的形状被忽视了。比如输入数据是图像时,图像通常是高、长、通道方向上的3维形状。但是,向全连接层输入时,需要将3维数据拉平为1维数据。前面提到的使用了MNIST数据集的例子中,输入图像就是1通道、高28像素、长28像素的(1,28,28)形状,但却被排成1列,以784个数据的形式输入到最开始的Affine层。

        图像是三维形状,这个形状中应该含有重要的空间信息,三维形状中可能隐藏有值得提取的本质模式。但是全连接层会忽视形状,将全部的输入数据作为相同的神经元处理,所以无法利用形状相关的信息

        而卷积层可以保持形状不变,当输入数据是图像时,卷积层会以3维数据的形式接收数据,并同样以3维数据的形式输出到下一层。因此在CNN中,可以正确理解图像等具有形状的数据。

        CNN中有时将卷积层的输入输出称为特征图。

7.2.2 卷积运算

        先看一个卷积运算的例子。

        如上图所示,卷积运算对输入数据应用滤波器。在本例中,输入大小是(4,4),输出大小是(2,2)。对于输入数据,卷积运算以一定间隔滑动滤波器的窗口并应用。 此处的窗口是指下图中灰色的3×3部分。然后将各个位置上滤波器的元素和输入的对应元素相乘求和,把结果保存到输出的对应位置。 偏置通常只有1个(1×1)。 

        在全连接神经网络中,除了权重参数,还存在偏置。在CNN中,滤波器的参数就对应之前的权重。CNN也存在偏置。包含偏置的卷积运算处理流如下图所示。

7.2.3 填充

        进行卷积层的处理之前,有时要向输入数据的周围填入固定的数据(比如0等)这称为填充。比如上面的例子中,对(4,4)的输入数据应用幅度为1的填充。幅度为1的填充是指用幅度为1像素的0填充周围。

        如上图所示,大小为(4,4)的输入数据变成了(6,6),应用大小(3,3)的滤波器,生成了大小(4,4)的输出数据。

        使用填充主要是为了调整输出的大小。比如,对大小为(4,4)的输入数据应用(3,3)的滤波器时,输出大小变为(2,2),相当于输出大小比输入大小缩小了2个元素。这在反复进行多次卷积运算的深度网络中会成为问题。因为如果每次进行卷积运算都会缩小空间,那么在某个时刻输出大小就有可能变为1,导致无法再应用卷积运算。 为了避免出现这样的情况,就要使用填充。因此,卷积运算就可以在保持空间大小不变的情况下将数据传给下一层。

7.2.4 步幅

        应用滤波器的位置间隔称为步幅,之前例子的步幅都是1,如果将步幅设置为2,则如下图所示。

        在上图的例子,对输入大小为(7,7)的数据,以步幅2应用了滤波器,输出变成了(3,3)。即步幅可以指定应用滤波器的间隔。 增大步幅后,输出大小会变小,增大填充后,输出大小会变大。假设输入大小为(H,W),滤波器大小为(FH,FW),输出大小为(OH,OW),填充为P,步幅为S,则输出大小可以通过下式计算。

        只要代入值就可以计算输出大小,但是所设定的值必须使上式分别可以除尽。无法除尽时,要采取报错等对策。

7.2.5 3维数据的卷积运算 

        现在看一下加上了通道方向的3维数据进行卷积运算的例子。通道方向上有多个特征图时,会按通道进行输入数据和滤波器的卷积运算,并将结果相加,从而得到输出。

         在3维数据的卷积运算中,输入数据和滤波器的通道数要设为相同的值。在本例中均为3。滤波器大小可以设为任意值。但每个通道的滤波器大小要相同。

7.2.6 结合方块思考

        将数据和滤波器结合长方体的方块来考虑。把3维数据表示为多维数组时,书写顺序是(channel,height,width)。比如通道数为C,高度H,长度W的数据的形状可以写成(C,H,W)滤波器书写顺序也一样。

        在上面图中,数据输出是一张特征图,即通道数为1的特征图。如果要在通道方向上有多个卷积运算的输出,需要用到多个滤波器(权重)。

        如上图所示,应用了FN个滤波器,输出特征图就生成了FN个。 将这FN个特征图汇集在一起,就得到了形状为(FN,OH,OW)的方块。将方块传给下一层,就是CNN的处理流。

        作为4维数据,滤波器的权重数据要按(output_channel,input_channel, height, width)的顺序书写。比如,通道数为3、大小为5×5的滤波器有20个时,可以写成(20,3,5,5)。

        如果i进一步追加偏置的加法运算处理,则结果如下图所示

        在上图,每个通道只有1个偏置。

7.2.7 批处理 

        卷积运算需要将在各层传递的数据保存维4维数据,就是按(batch_num,channel,height,width)的顺序保存数据。比如将上图的处理改成对N个数据进行批处理时,数据的形状如下图所示。

        即批处理将N次处理汇总成了1次进行。

7.3 池化层

        池化是缩小高、长方向上的空间的运算。比如下图所示,进行将2 ×2的区域集约成1个元素的处理,缩小空间大小。

         上面的例子是按步幅2进行2×2的Max池化时的处理顺序。在图像识别领域,主要使用Max池化。

        池化层的特征:

        1.没有要学习的参数:池化层和卷积层不同,没有要学习的参数。池化只是从目标区域中取最 大值(或者平均值),所以不存在要学习的参数。

        2.通道数不发生变化:经过池化运算,输入数据和输出数据的通道数不会发生变化。如下图所示,计算是按通道独立进行的。

        输入数据发生微小偏差时,池化仍会返回相同的结果。因此,池化对输入数据的微小偏差具有鲁棒性。 如下图所示,池化会吸收输入数据的偏差。

7.4 卷积层和池化层的实现 

7.4.1 4维数组

        CNN中各层之间传递的是4维数组,比如数据的形状是(10,1,28,28)表示它对应10个高为28、长为28、通道为1的数据,用python实现如下

x = np.random.rand(10, 1, 28, 28)
print(x.shape) # (10, 1, 28, 28)

如果要访问第1个数据,写x[0]即可。

print(x[0].shape) # (1, 28, 28)

 如果要访问第一个数据的第一个通道的空间数据,可以写成这样

print(x[0][0])

7.4.2 基于im2col的展开

        CNN中处理的是4维数据,如果老老实实实现卷积运算,要重复好几层的for语句,而且NumPy中存在使用for语句后处理变慢的缺点,这里不使用for语句,使用im2col函数进行简单的实现。

        im2col将输入数据展开以适合滤波器(权重)。如下图所示,对3维输入数据应用im2col后,数据转换为2维矩阵。

        在上图例,im2col会将应用滤波器的区域(3维方块)横向展开为1列。 

        为了便于观察,在上图将步幅设置得很大,以使滤波器的应用区域不重叠。而在实际的卷积运算中,滤波器的应用区域几乎都是重叠的。在重叠的情况下,使用im2col展开后,展开的元素个数会多于原方块的元素个数。因此,使用im2col的实现存在比普通的实现消耗更多内存的缺点。

        使用im2col展开输入数据后,只需将卷积层的滤波器(权重)纵向展开为1列,并计算两个矩阵的乘积即可。如下图所示,基于im2col方式输出结果是2维矩阵,因为CNN中数据会保存4维数组,所以要将2维数组转换为合适的形状。以上就是卷积层的实现流程。

7.4.3 卷积层的实现

 im2col函数有以下接口:

 im2col (input_data, filter_h, filter_w, stride=1, pad=0)

 input_data―由(数据量,通道,高,长)的 4维数组构成的输入数据

filter_h―滤波器的高

filter_w―滤波器的长

stride―步幅

pad―填充

现在来实际应用一下im2col。

import sys,os
import numpy as np
sys.path.append(os.pardir)
from common.util import im2col

x1 = np.random.rand(1, 3, 7, 7)
col1 = im2col(x1, 5, 5, stride = 1, pad = 0)
print(col1.shape) # (9, 75)

x2 = np.random.rand(10, 3, 7, 7)
col2 = im2col(x2, 5, 5, stride = 1, pad = 0)
print(col2.shape) # (90,75)

         上述两种情况下,第二维的元素个数均为75,这是滤波器(通道为3、大小为5×5)的元素个数的总和。卷积层的代码实现不再赘述。

7.4.4 池化层的实现

        池化层和卷积层相同,都使用im2col展开输入数据,但是池化的情况下,在通道方向上是独立的,池化的应用区域按通道单独展开

        池化层的forward处理流程如下图所示

7.5 CNN的实现

7.6 CNN的可视化

7.6.1 第一层权重的可视化

        滤波器可以可视化为1通道的灰度图像,现在将第一层的滤波器显示为图像,并比较学习前后的权重,结果如下图所示

         在上图,学习前的滤波器是随机进行初始化的,所以在黑白的浓淡上没有规律可循,但学习后的滤波器变成了有规律的图像。

        卷积层的滤波器会提取边缘或斑块等原始信息,CNN会将这些原始信息传递给后面的层。

7.6.2 基于分层结构的信息提取

        根据深度学习的可视化相关研究,随着层次加深,提取的信息也越来越抽象。

7.7 具有代表性的CNN

7.7.1 LeNet

        LeNet激活函数使用sigmoid函数,而现在的CNN使用ReLU函数。原始的LeNet使用子采样缩小中间数据的大小,而现在CNN中Max池化是主流。

7.7.2 AlexNet

        激活函数使用ReLU,使用进行局部正规化的LRN,使用Dropout。

7.8 小结

        使用im2col函数可以简单、高效地实现卷积层和池化层。在深度学习的发展中,GPU和大数据做出了很大的贡献。

  • 19
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值