深度学习入门|第七章 卷积神经网络(二)

摘要:
前言《文学深度学习导论》一书的学习笔记。有关详细信息,请阅读原著《三、拼图》。拼图是缩小高度和矩形空间的操作。与从目标区域获取最大值的最大池不同,平均池用于计算目标区域的平均值。在Caffe和Chainer等深度学习框架中,一个名为im2col的函数用于卷积层的实现。分别对它们应用im2col函数。在这两种情况下,第二维度中的元素数都是75。在这些粗体字中,使用im2col展开输入数据,然后使用reshape将过滤器展开为二维数组。

前言

本文学学习深度学习入门一书的学习笔记,详情请阅读原著

三、池化层

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

深度学习入门|第七章 卷积神经网络(二)第1张

图 7-14 Max 池化的处理顺序

图 7-14 的例子是按步幅 2 进行 2 × 2 的 Max 池化时的处理顺序。“Max 池化”是获取最大值的运算,“2 × 2”表示目标区域的大小。如图所示,从 2 × 2 的区域中取出最大的元素。此外,这个例子中将步幅设为了 2,所以 2 × 2 的窗口的移动间隔为 2 个元素。另外,一般来说,池化的窗口大小会和步幅设定成相同的值。比如,3 × 3 的窗口的步幅会设为 3,4 × 4 的窗口的步幅会设为 4 等。

除了 Max 池化之外,还有 Average 池化等。相对于 Max 池化是从目标区域中取出最大值,Average 池化则是计算目标区域的平均值。在图像识别领域,主要使用 Max 池化。因此,本书中说到“池化层”时,指的是 Max 池化。

池化层的特征

池化层有以下特征。

没有要学习的参数

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

通道数不发生变化

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

{95%}

图 7-15 池化中通道数不变

对微小的位置变化具有鲁棒性(健壮)

输入数据发生微小偏差时,池化仍会返回相同的结果。因此,池化对输入数据的微小偏差具有鲁棒性。比如,3 × 3 的池化的情况下,如图 7-16 所示,池化会吸收输入数据的偏差(根据数据的不同,结果有可能不一致)。

{%}

图 7-16 输入数据在宽度方向上只偏离 1 个元素时,输出仍为相同的结果(根据数据的不同,有时结果也不相同)

四、卷积层和池化层的实现

1、4维数组

如前所述,CNN 中各层间传递的数据是 4 维数据。所谓 4 维数据,比如数据的形状是 (10, 1, 28, 28),则它对应 10 个高为 28、长为 28、通道为 1 的数据。用 Python 来实现的话,如下所示。

深度学习入门|第七章 卷积神经网络(二)第4张

2、基于im2col的展开

使用im2col这个便利的函数进行简单的实现。im2col是一个函数,将输入数据展开以适合滤波器(权重)。如图 7-17 所示,对 3 维的输入数据应用im2col后,数据转换为 2 维矩阵(正确地讲,是把包含批数量的 4 维数据转换成了 2 维数据)。

深度学习入门|第七章 卷积神经网络(二)第5张

图 7-17 im2col 的示意图

im2col会把输入数据展开以适合滤波器(权重)。具体地说,如图 7-18 所示,对于输入数据,将应用滤波器的区域(3 维方块)横向展开为 1 列。im2col会在所有应用滤波器的地方进行这个展开处理。

在图 7-18 中,为了便于观察,将步幅设置得很大,以使滤波器的应用区域不重叠。而在实际的卷积运算中,滤波器的应用区域几乎都是重叠的。在滤波器的应用区域重叠的情况下,使用im2col展开后,展开后的元素个数会多于原方块的元素个数。因此,使用im2col的实现存在比普通的实现消耗更多内存的缺点。但是,汇总成一个大的矩阵进行计算,对计算机的计算颇有益处。比如,在矩阵计算的库(线性代数库)等中,矩阵计算的实现已被高度最优化,可以高速地进行大矩阵的乘法运算。因此,通过归结到矩阵计算上,可以有效地利用线性代数库。

im2col这个名称是“image to column”的缩写,翻译过来就是“从图像到矩阵”的意思。Caffe、Chainer 等深度学习框架中有名为im2col的函数,并且在卷积层的实现中,都使用了im2col

使用im2col展开输入数据后,之后就只需将卷积层的滤波器(权重)纵向展开为 1 列,并计算 2 个矩阵的乘积即可(参照图 7-19)。这和全连接层的 Affine层进行的处理基本相同。

如图 7-19 所示,基于im2col方式的输出结果是 2 维矩阵。因为 CNN 中数据会保存为 4 维数组,所以要将 2 维输出数据转换为合适的形状。以上就是卷积层的实现流程。

深度学习入门|第七章 卷积神经网络(二)第6张

图 7-19 卷积运算的滤波器处理的细节:将滤波器纵向展开为 1 列,并计算和 im2col 展开的数据的矩阵乘积,最后转换(reshape)为输出数据的大小

3、卷积层的实现

im2col函数接口

im2col (input_data, filter_h, filter_w, stride=1, pad=0)
  • input_data——由(数据量,通道,高,长)的 4 维数组构成的输入数据
  • filter_h——滤波器的高
  • filter_w——滤波器的长
  • stride——步幅
  • pad——填充

im2col会考虑滤波器大小、步幅、填充,将输入数据展开为 2 维数组。下例中,实际使用一下这个im2col

importsys, os
sys.path.append(os.pardir)
from common.util importim2col

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) #10个数据
col2 = im2col(x2, 5, 5, stride=1, pad=0)
print(col2.shape) #(90, 75)

这里举了两个例子。第一个是批大小为 1、通道为 3 的 7 × 7 的数据,第二个的批大小为 10,数据形状和第一个相同。分别对其应用im2col函数,在这两种情形下,第 2 维的元素个数均为 75。这是滤波器(通道为 3、大小为 5 × 5)的元素个数的总和。批大小为 1 时,im2col的结果是(9, 75)。而第 2 个例子中批大小为 10,所以保存了 10 倍的数据,即(90, 75)

使用im2col来实现卷积层。这里我们将卷积层实现为名为Convolution的类。

classConvolution:
    def __init__(self, W, b, stride=1, pad=0):
        self.W =W
        self.b =b
        self.stride =stride
        self.pad =pad

    defforward(self, x):
        FN, C, FH, FW =self.W.shape
        N, C, H, W =x.shape
        out_h = int(1 + (H + 2*self.pad - FH) /self.stride)
        out_w = int(1 + (W + 2*self.pad - FW) /self.stride)

        col =im2col(x, FH, FW, self.stride, self.pad)
        col_W = self.W.reshape(FN, -1).T #滤波器的展开
        out = np.dot(col, col_W) +self.b

        out = out.reshape(N, out_h, out_w, -1).transpose(0, 3, 1, 2)

        return out

卷积层的初始化方法将滤波器(权重)、偏置、步幅、填充作为参数接收。滤波器是(FN, C, FH, FW)的 4 维形状。另外,FNCFHFW分别是 Filter Number(滤波器数量)、Channel、Filter Height、Filter Width 的缩写。

这里用粗体字表示 Convolution 层的实现中的重要部分。在这些粗体字部分,用im2col展开输入数据,并用reshape将滤波器展开为 2 维数组。然后,计算展开后的矩阵的乘积。

展开滤波器的部分(代码段中的粗体字)如图 7-19 所示,将各个滤波器的方块纵向展开为 1 列。这里通过reshape(FN,-1)将参数指定为-1,这是reshape的一个便利的功能。通过在reshape时指定为-1reshape函数会自动计算-1维度上的元素个数,以使多维数组的元素个数前后一致。比如,(10, 3, 5, 5) 形状的数组的元素个数共有 750 个,指定reshape(10,-1)后,就会转换成 (10, 75) 形状的数组。

forward的实现中,最后会将输出大小转换为合适的形状。转换时使用了 NumPy 的transpose函数。transpose会更改多维数组的轴的顺序。如图 7-20 所示,通过指定从 0 开始的索引(编号)序列,就可以更改轴的顺序。

深度学习入门|第七章 卷积神经网络(二)第7张

图 7-20 基于 NumPy 的 transpose 的轴顺序的更改:通过指定索引(编号),更改轴的顺序

以上就是卷积层的forward处理的实现。通过使用im2col进行展开,基本上可以像实现全连接层的 Affine 层一样来实现(5.6 节)。接下来是卷积层的反向传播的实现,因为和 Affine 层的实现有很多共通的地方,所以就不再介绍了。但有一点需要注意,在进行卷积层的反向传播时,必须进行im2col的逆处理。这可以使用本书提供的col2im函数(col2im的实现在common/util.py中)来进行。除了使用col2im这一点,卷积层的反向传播和 Affine 层的实现方式都一样。卷积层的反向传播的实现在common/layer.py

4、池化层的实现

池化层的实现和卷积层相同,都使用im2col展开输入数据。不过,池化的情况下,在通道方向上是独立的,这一点和卷积层不同。具体地讲,如图 7-21 所示,池化的应用区域按通道单独展开。

深度学习入门|第七章 卷积神经网络(二)第8张

图 7-21 对输入数据展开池化的应用区域(2×2 的池化的例子)

像这样展开之后,只需对展开的矩阵求各行的最大值,并转换为合适的形状即可(图 7-22)。

深度学习入门|第七章 卷积神经网络(二)第9张

图 7-22 池化层的实现流程:池化的应用区域内的最大值元素用灰色表示

上面就是池化层的forward处理的实现流程。下面来看一下 Python 的实现示例。

classPooling:
    def __init__(self, pool_h, pool_w, stride=1, pad=0):
        self.pool_h =pool_h
        self.pool_w =pool_w
        self.stride =stride
        self.pad =pad

    defforward(self, x):
        N, C, H, W =x.shape
        out_h = int(1 + (H - self.pool_h) /self.stride)
        out_w = int(1 + (W - self.pool_w) /self.stride)

        #展开(1)
        col =im2col(x, self.pool_h, self.pool_w, self.stride, self.pad)
        col = col.reshape(-1, self.pool_h*self.pool_w)

        #最大值(2)
        out = np.max(col, axis=1)
        #转换(3)
        out = out.reshape(N, out_h, out_w, C).transpose(0, 3, 1, 2)

        return out

如图 7-22 所示,池化层的实现按下面 3 个阶段进行。

  1. 展开输入数据。
  2. 求各行的最大值。
  3. 转换为合适的输出大小。

各阶段的实现都很简单,只有一两行代码。

最大值的计算可以使用 NumPy 的np.max方法。np.max可以指定axis参数,并在这个参数指定的各个轴方向上求最大值。比如,如果写成np.max(x, axis=1),就可以在输入x的第 1 维的各个轴方向上求最大值。

以上就是池化层的forward处理的介绍。如上所述,通过将输入数据展开为容易进行池化的形状,后面的实现就会变得非常简单。

关于池化层的backward处理,之前已经介绍过相关内容,这里就不再介绍了。另外,池化层的backward处理可以参考 ReLU 层的实现中使用的 max 的反向传播(5.5.1 节)。池化层的实现在common/layer.py中。

免责声明:文章转载自《深度学习入门|第七章 卷积神经网络(二)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇(持续更新)一些黑科技和技巧专业术语常用名词缩写中英文对照下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

CNN中的卷积

1、什么是卷积:图像中不同数据窗口的数据和卷积核(一个滤波矩阵)作内积的操作叫做卷积。其计算过程又称为滤波(filter),本质是提取图像不同频段的特征。 2、什么是卷积核:也称为滤波器filter,带着一组固定权重的神经元,通常是n*m二维的矩阵,n和m也是神经元的感受野。n*m 矩阵中存的是对感受野中数据处理的系数。一个卷积核的滤波可以用来提取特定的特...

利用LSTM(长短期记忆网络)来处理脑电数据

目录 LSTM 原理介绍 LSTM的核心思想 一步一步理解LSTM 代码案例 本分享为脑机学习者Rose整理发表于公众号:脑机接口社区(微信号:Brain_Computer).QQ交流群:903290195 Rose小哥今天介绍一下用LSTM来处理脑电数据。 LSTM 原理介绍 LSTMs(Long Short Term Memory net...

多项式 之 快速傅里叶变换(FFT)/数论变换(NTT)/常用套路【入门】

原文链接https://www.cnblogs.com/zhouzhendong/p/Fast-Fourier-Transform.html 多项式 之 快速傅里叶变换(FFT)/数论变换(NTT)/例题与常用套路【入门】 前置技能 对复数以及复平面有一定的了解 对数论要求了解:逆元,原根,中国剩余定理 对分治有充足的认识 对多项式有一定的认识,并会写...

目标检测相关基础概念

目标检测相关基础概念 算法分类 flowchart LR 1[Object Detection] 2[two stage]-->R-CNN-->SPP-NET-->A[Fast R-CNN]-->B[Faster R-CNN] 3[one stage]-->a[OverFeat] 1-->2 1-->3 a--&g...

MobileNet系列之MobileNet_v3

​ MobileNet系列之MobileNet_v1 MobileNet系列之MobileNet_v2 导言:     继MobileNet_v1和v2提出后,在2019年,MobileNet_v3在众人的期盼下出来了,MobileNet_v3论文提出了两个模型,MobileNet_v3-Large和MobileNet_v3-small,其主要区别在于层数...

基于tensorflow的CNN卷积神经网络对Fasion-MNIST数据集的分类器(1)

写一个基于tensorflow的cnn,分类fasion-MNIST数据集 这个就是fasion-mnist数据集 这张图片是CNN的一般结构 先上代码,在分析: import tensorflow as tf import pandas as pd import numpy as np config = tf.ConfigProto() confi...