update chapter 05

This commit is contained in:
hwade 2019-03-18 22:35:00 +08:00
parent 76777dd8cd
commit ec3a6c37fd
11 changed files with 154 additions and 421 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -2,32 +2,40 @@
# 第五章 卷积神经网络CNN
# 第五章 卷积神经网络CNN
卷积神经网络是一种用来处理局部和整体相关性的计算网络结构,被应用在图像识别、自然语言处理甚至是语音识别领域,因为图像数据具有显著的局部与整体关系,其在图像识别领域的应用获得了巨大的成功。
## 5.1 卷积神经网络的组成层
以图像分类任务为例在表5.1所示卷积神经网络中一般包含5种类型的网络层次结构
表5.1 卷积神经网络的组成
| CNN层次结构 | 输出尺寸 | 作用 |
| :--------: | :------: | :---- |
| 输入层 | $W_1\times H_1\times 3$ | 卷积网络的原始输入,可以是原始或预处理后的像素矩阵 |
| 卷积层 | $W_1\times H_1\times K$ | 参数共享、局部连接,利用平移不变性从全局特征图提取局部特征 |
| 激活层 | $W_1\times H_1\times K$ | 将卷积层的输出结果进行非线性映射 |
| 池化层 | $W_2\times H_2\times K$ | 进一步筛选特征,可以有效减少后续网络层次所需的参数量 |
| 全连接层 | $(W_2 \cdot H_2 \cdot K)\times C$ | 将多维特征展平为2维特征通常最低维度特征对应任务的学习目标类别或回归值 |
| CNN层次结构 | 输出尺寸 | 作用 |
| :---------: | :-------------------------------: | :----------------------------------------------------------- |
| 输入层 | $W_1\times H_1\times 3$ | 卷积网络的原始输入,可以是原始或预处理后的像素矩阵 |
| 卷积层 | $W_1\times H_1\times K$ | 参数共享、局部连接,利用平移不变性从全局特征图提取局部特征 |
| 激活层 | $W_1\times H_1\times K$ | 将卷积层的输出结果进行非线性映射 |
| 池化层 | $W_2\times H_2\times K$ | 进一步筛选特征,可以有效减少后续网络层次所需的参数量 |
| 全连接层 | $(W_2 \cdot H_2 \cdot K)\times C$ | 将多维特征展平为2维特征通常低维度特征对应任务的学习目标类别或回归值 |
> $W_1\times H_1\times 3$对应原始图像或经过预处理的像素值矩阵3对应RGB图像的通道;$K$表示卷积层中卷积核(滤波器)的个数;$W_2\times H_2$ 为池化后特征图的尺度,在全局池化中尺度对应$1\times 1$;$(W_2 \cdot H_2 \cdot K)$是将多维特征压缩到1维之后的大小$C$对应的则是图像类别个数。
### 5.1.1 输入层
输入层通常是输入卷积神经网络的原始数据或经过预处理的数据可以是图像识别领域中原始三维的多彩图像也可以是音频识别领域中经过傅利叶变换的二维波形数据甚至是自然语言处理中一维表示的句子向量。以图像分类任务为例输入层输入的图像一般包含RGB三个通道是一个由长宽分别为$H$和$W$组成的3维像素值矩阵$H\times W \times 3$,卷积网络会将输入层的数据传递到一系列卷积、池化等操作进行特征提取和转化,最终由全连接层对特征进行汇总和结果输出。根据计算能力、存储大小和模型结构的不同,卷积神经网络每次可以批量处理的图像个数不尽相同,若指定输入层接收到的图像个数为$N$,则输入层的输出数据为$N\times H\times W\times 3$。
输入层(Input Layer)通常是输入卷积神经网络的原始数据或经过预处理的数据可以是图像识别领域中原始三维的多彩图像也可以是音频识别领域中经过傅利叶变换的二维波形数据甚至是自然语言处理中一维表示的句子向量。以图像分类任务为例输入层输入的图像一般包含RGB三个通道是一个由长宽分别为$H$和$W$组成的3维像素值矩阵$H\times W \times 3$,卷积网络会将输入层的数据传递到一系列卷积、池化等操作进行特征提取和转化,最终由全连接层对特征进行汇总和结果输出。根据计算能力、存储大小和模型结构的不同,卷积神经网络每次可以批量处理的图像个数不尽相同,若指定输入层接收到的图像个数为$N$,则输入层的输出数据为$N\times H\times W\times 3$。
### 5.1.2 卷积层
卷积层通常用作对输入层输入数据进行特征提取,通过卷积核矩阵对原始数据中隐含关联性的一种抽象。卷积操作原理上其实是对两张像素矩阵进行点乘求和的数学操作,其中一个矩阵为输入的数据矩阵,另一个矩阵则为卷积核(滤波器或特征矩阵),求得的结果表示为原始图像中提取的特定局部特征。
卷积层(Convolution Layer)通常用作对输入层输入数据进行特征提取通过卷积核矩阵对原始数据中隐含关联性的一种抽象。卷积操作原理上其实是对两张像素矩阵进行点乘求和的数学操作其中一个矩阵为输入的数据矩阵另一个矩阵则为卷积核滤波器或特征矩阵求得的结果表示为原始图像中提取的特定局部特征。图5.1表示卷积操作过程中的不同填充策略,上半部分采用零填充,下半部分采用有效卷积(舍弃不能完整运算的边缘部分)。
![conv-same](img/ch5/convolution.png)
图5.1 卷积操作示意图
### 5.1.3 激活层
激活层负责对卷积层抽取的特征进行激活由于卷积操作是由输入矩阵与卷积核矩阵进行相差的线性变化关系需要激活层对其进行非线性的映射。激活层主要由激活函数组成即在卷积层输出结果的基础上嵌套一个非线性函数让输出的特征图具有非线性关系。卷积网络中通常采用ReLU来充当激活函数还包括tanh和sigmoid等ReLU的函数形式如公式5-1所示能够限制小于0的值为0,同时大于等于0的值保持不变。
激活层(Activation Layer)负责对卷积层抽取的特征进行激活由于卷积操作是由输入矩阵与卷积核矩阵进行相差的线性变化关系需要激活层对其进行非线性的映射。激活层主要由激活函数组成即在卷积层输出结果的基础上嵌套一个非线性函数让输出的特征图具有非线性关系。卷积网络中通常采用ReLU来充当激活函数还包括tanh和sigmoid等ReLU的函数形式如公式5-1所示能够限制小于0的值为0,同时大于等于0的值保持不变。
$$
f(x)=\begin{cases}
0 &\text{if } x<0 \\
@ -37,234 +45,167 @@ f(x)=\begin{cases}
$$
### 5.1.4 池化层
池化层通常
池化层又称为降采样层(Downsampling Layer),作用是对感受域内的特征进行筛选,提取区域内最具代表性的特征,能够有效地降低输出特征尺度,进而减少模型所需要的参数量。按操作类型通常分为最大池化(Max Pooling)、平均池化(Average Pooling)和求和池化(Sum Pooling),它们分别提取感受域内最大、平均与总和的特征值作为输出,最常用的是最大池化。
### 5.1.5 全连接层
全连接层(Full Connected Layer)负责对卷积神经网络学习提取到的特征进行汇总,将多维的特征输入映射为二维的特征输出,高维表示样本批次,低位常常对应任务目标。
## 5.2 卷积在图像中有什么直观作用
在卷积神经网络中卷积常用来提取图像的特征但不同层次的卷积操作提取到的特征类型是不相同的特征类型粗分如表5.2所示。
表5.2 卷积提取的特征类型
| 卷积层次 | 特征类型 |
| :--------: | :----: |
| :------: | :------: |
| 浅层卷积 | 边缘特征 |
| 中层卷积 | 局部特征 |
| 深层卷积 | 全局特征 |
图像与不同卷积核的卷积可以用来执行边缘检测、锐化和模糊等操作。表5.3显示了应用不同类型的卷积核(滤波器)后的各种卷积图像。
表5.3 一些常见卷积核的作用
| 卷积作用 | 卷积核 | 卷积后图像 |
| :--------: | :----: | :----: |
| 输出原图 | $\begin{bmatrix} 0 & 0 & 0 \\ 0 & 1 & 0 \\ 0 & 0 & 0 \end{bmatrix}$ | ![origin_img](./img/ch5/cat.jpg) |
| 边缘检测(突出边缘差异)| $\begin{bmatrix} 1 & 0 & -1 \\ 0 & 0 & 0 \\ -1 & 0 & 1 \end{bmatrix}$ | ![edgeDetect-1](./img/ch5/cat-edgeDetect.jpg) |
| 边缘检测(突出中间值) | $\begin{bmatrix} -1 & -1 & -1 \\ -1 & 8 & -1 \\ -1 & -1 & -1 \end{bmatrix}$ | ![edgeDetect-2](./img/ch5/cat-edgeDetect-2.jpg) |
| 图像锐化 | $\begin{bmatrix} 0 & -1 & 0 \\ -1 & 5 & -1 \\ 0 & -1 & 0 \end{bmatrix}$ | ![sharpen_img](./img/ch5/cat-sharpen.jpg) |
| 方块模糊 | $\begin{bmatrix} 1 & 1 & 1 \\ 1 & 1 & 1 \\ 1 & 1 & 1 \end{bmatrix} \times \frac{1}{9}$ | ![box_blur](./img/ch5/cat-boxblur.jpg) |
| 高斯模糊 | $\begin{bmatrix} 1 & 2 & 1 \\ 2 & 4 & 2 \\ 1 & 2 & 1 \end{bmatrix} \times \frac{1}{16}$ | ![gaussian_blur](./img/ch5/cat-blur-gaussian.jpg) |
| 卷积作用 | 卷积核 | 卷积后图像 |
| :----------------------: | :----------------------------------------------------------: | :-----------------------------------------------: |
| 输出原图 | $\begin{bmatrix} 0 & 0 & 0 \\ 0 & 1 & 0 \\ 0 & 0 & 0 \end{bmatrix}$ | ![origin_img](./img/ch5/cat.jpg) |
| 边缘检测(突出边缘差异) | $\begin{bmatrix} 1 & 0 & -1 \\ 0 & 0 & 0 \\ -1 & 0 & 1 \end{bmatrix}$ | ![edgeDetect-1](./img/ch5/cat-edgeDetect.jpg) |
| 边缘检测(突出中间值) | $\begin{bmatrix} -1 & -1 & -1 \\ -1 & 8 & -1 \\ -1 & -1 & -1 \end{bmatrix}$ | ![edgeDetect-2](./img/ch5/cat-edgeDetect-2.jpg) |
| 图像锐化 | $\begin{bmatrix} 0 & -1 & 0 \\ -1 & 5 & -1 \\ 0 & -1 & 0 \end{bmatrix}$ | ![sharpen_img](./img/ch5/cat-sharpen.jpg) |
| 方块模糊 | $\begin{bmatrix} 1 & 1 & 1 \\ 1 & 1 & 1 \\ 1 & 1 & 1 \end{bmatrix} \times \frac{1}{9}$ | ![box_blur](./img/ch5/cat-boxblur.jpg) |
| 高斯模糊 | $\begin{bmatrix} 1 & 2 & 1 \\ 2 & 4 & 2 \\ 1 & 2 & 1 \end{bmatrix} \times \frac{1}{16}$ | ![gaussian_blur](./img/ch5/cat-blur-gaussian.jpg) |
## 5.3 卷积层有哪些基本参数?
卷积层中需要用到卷积核滤波器或特征检测器与图像特征矩阵进行点乘运算利用卷积核与对应的特征感受域进行划窗式运算时需要设定卷积核对应的大小、步长、个数以及填充的方式如表5.4所示。
表5.4 卷积层的基本参数
| 参数名 | 作用 | 常见设置 |
| :--------: | :---- | :---- |
| 卷积核大小 (Kernel Size) | 卷积核的大小定义了卷积的感受野 | 在过去常设为5,如LeNet-5;现在多设为3,通过叠加$3\times3$的卷积核来达到更大的感受域 |
| 卷积核步长 (Stride) | 定义了卷积核在卷积过程中的步长 | 常见设置为1,表示滑窗距离为1,可以覆盖所有相邻位置特征的组合;当设置为更大值时相当于对特征组合降采样 |
| 填充方式 (Padding) | 在卷积核尺寸不能完美匹配输入的图像矩阵时需要进行一定的填充策略 | 设置为'SAME'表示对不足卷积核大小的边界位置进行某种填充(通常零填充)以保证卷积输出维度与与输入维度一致;当设置为'VALID'时则对不足卷积尺寸的部分进行舍弃,输出维度就无法保证与输入维度一致 |
| 输入通道数 (In Channels) | 指定卷积操作时卷积核的深度 | 默认与输入的特征矩阵通道数(深度)一致;在某些压缩模型中会采用通道分离的卷积方式 |
| 输出通道数 (Out Channels) | 指定卷积核的个数 | 若设置为与输入通道数一样的大小,可以保持输入输出维度的一致性;若采用比输入通道数更小的值,则可以减少整体网络的参数量 |
表5.4 卷积层的基本参数
| 参数名 | 作用 | 常见设置 |
| :-----------------------: | :----------------------------------------------------------- | :----------------------------------------------------------- |
| 卷积核大小 (Kernel Size) | 卷积核的大小定义了卷积的感受野 | 在过去常设为5,如LeNet-5;现在多设为3,通过堆叠$3\times3$的卷积核来达到更大的感受域 |
| 卷积核步长 (Stride) | 定义了卷积核在卷积过程中的步长 | 常见设置为1,表示滑窗距离为1,可以覆盖所有相邻位置特征的组合;当设置为更大值时相当于对特征组合降采样 |
| 填充方式 (Padding) | 在卷积核尺寸不能完美匹配输入的图像矩阵时需要进行一定的填充策略 | 设置为'SAME'表示对不足卷积核大小的边界位置进行某种填充(通常零填充)以保证卷积输出维度与与输入维度一致;当设置为'VALID'时则对不足卷积尺寸的部分进行舍弃,输出维度就无法保证与输入维度一致 |
| 输入通道数 (In Channels) | 指定卷积操作时卷积核的深度 | 默认与输入的特征矩阵通道数(深度)一致;在某些压缩模型中会采用通道分离的卷积方式 |
| 输出通道数 (Out Channels) | 指定卷积核的个数 | 若设置为与输入通道数一样的大小,可以保持输入输出维度的一致性;若采用比输入通道数更小的值,则可以减少整体网络的参数量 |
> 卷积操作维度变换公式:
>
> $O_d =\begin{cases} \lceil \frac{(I_d - k_{size})+ 1)}{s}\rceil ,& \text{padding=VALID}\\ \lceil \frac{I_d}{s}\rceil,&\text{padding=SAME} \end{cases}$
>
> 其中,$I_d$为输入维度,$O_d$为输出维度,$k_{size}$为卷积核大小,$s$为步长
## 5.4 卷积核有什么类型?
常见的卷积主要是由连续紧密的卷积核对输入的图像特征进行滑窗式点乘求和操作除此之外还有其他类型的卷积核在不同的任务中会用到具体分类如表5.5所示。
表5.5 卷积核分类
| 卷积类别 | 示意图 | 作用 |
| :--------: | :----: | :---- |
| 普通卷积 | ![image](./img/ch5/img7.png) | 最常用的卷积核,连续紧密的矩阵形式可以提取图像区域中的相邻像素之间的关联关系,$3\times3$的卷积核可以获得$3\times3$像素范围的感受视野 |
| 扩张卷积(带孔卷积或空洞卷积) | ![image](./img/ch5/img8.png) | 引入一个称作扩张率Dilation Rate的参数使同样尺寸的卷积核可以获得更大的感受视野相应的在相同感受视野的前提下比普通卷积采用更少的参数。同样是$3\times3$的卷积核尺寸,扩张卷积可以提取$5\times5$范围的区域特征,在实时图像分割领域广泛应用 |
| 转置卷积 | ![image](./img/ch5/img10.png) | 先对原始特征矩阵进行填充使其维度扩大到适配卷积目标输出维度,然后进行普通的卷积操作的一个过程,因其输入到输出的维度变换关系恰好与普通卷积的变换关系相反,但这个变换并不是真正的逆变换操作,通常称为转置卷积(Transpose Convolution)而不是反卷积(Deconvolution)。转置卷积常见于目标检测领域中对小目标的检测和图像分割领域还原输入图像尺度。 |
| 可分离卷积 | ![image](./img/ch5/img11.png) | 常见的卷积操作是同时对原始图像$H\times W\times C$三个方向的卷积运算,假设有$K$个相同尺寸的卷积核,这样的卷积操作需要用到的参数为$H\times W\times C\times K$个;若将长宽与深度方向的卷积操作分离出变为$H\times W$与$C$的两步卷积操作,则同样的卷积核个数$K$,只需要$(H\times W + C)\times K$个参数,便可得到同样的输出尺度。可分离卷积(Seperable Convolution)通常应用在模型压缩或一些轻量的卷积神经网络中如MobileNet、SqueezeNet等 |
表5.5 卷积核分类
| 卷积类别 | 示意图 | 作用 |
| :----------------------------: | :---------------------------: | :----------------------------------------------------------- |
| 标准卷积 | ![image](./img/ch5/img7.png) | 最常用的卷积核,连续紧密的矩阵形式可以提取图像区域中的相邻像素之间的关联关系,$3\times3$的卷积核可以获得$3\times3$像素范围的感受视野 |
| 扩张卷积(带孔卷积或空洞卷积) | ![image](./img/ch5/img8.png) | 引入一个称作扩张率Dilation Rate的参数使同样尺寸的卷积核可以获得更大的感受视野相应的在相同感受视野的前提下比普通卷积采用更少的参数。同样是$3\times3$的卷积核尺寸,扩张卷积可以提取$5\times5$范围的区域特征,在实时图像分割领域广泛应用 |
| 转置卷积 | ![image](./img/ch5/img10.png) | 先对原始特征矩阵进行填充使其维度扩大到适配卷积目标输出维度,然后进行普通的卷积操作的一个过程,其输入到输出的维度变换关系恰好与普通卷积的变换关系相反,但这个变换并不是真正的逆变换操作,通常称为转置卷积(Transpose Convolution)而不是反卷积(Deconvolution)。转置卷积常见于目标检测领域中对小目标的检测和图像分割领域还原输入图像尺度。 |
| 可分离卷积 | ![image](./img/ch5/img11.png) | 标准的卷积操作是同时对原始图像$H\times W\times C$三个方向的卷积运算,假设有$K$个相同尺寸的卷积核,这样的卷积操作需要用到的参数为$H\times W\times C\times K$个;若将长宽与深度方向的卷积操作分离出变为$H\times W$与$C$的两步卷积操作,则同样的卷积核个数$K$,只需要$(H\times W + C)\times K$个参数,便可得到同样的输出尺度。可分离卷积(Seperable Convolution)通常应用在模型压缩或一些轻量的卷积神经网络中如MobileNet$^{[1]}$、Xception$^{[2]}$等 |
## 5.5 二维卷积与三维卷积有什么区别?
- **二维卷积**
二维卷积操作如图5.3所示,为了更直观的说明,分别展示在单通道和多通道输入中,对单个通道输出的卷积操作。在单通道输入的情况下,若输入卷积核尺寸为 $(k_h, k_w, 1)$,卷积核在输入图像的空间维度上进行滑窗操作,每次滑窗和 $(k_h, k_w)$窗口内的值进行卷积操作得到输出图像中的一个值。在多通道输入的情况下假定输入图像特征通道数为3卷积核尺寸则为$(k_h, k_w, 3)$每次滑窗与3个通道上的$(k_h, k_w)$窗口内的所有值进行卷积操作,得到输出图像中的一个值。
二维卷积操作如图5.3所示,为了更直观的说明,分别展示在单通道和多通道输入中,对单个通道输出的卷积操作。在单通道输入的情况下,若输入卷积核尺寸为 $(k_h, k_w, 1)$,卷积核在输入图像的空间维度上进行滑窗操作,每次滑窗和 $(k_h, k_w)$窗口内的值进行卷积操作得到输出图像中的一个值。在多通道输入的情况下假定输入图像特征通道数为3卷积核尺寸则为$(k_h, k_w, 3)$每次滑窗与3个通道上的$(k_h, k_w)$窗口内的所有值进行卷积操作,得到输出图像中的一个值。
![image](./img/ch5/img12.png)
- **三维卷积**
3D卷积操作如图所示同样分为单通道和多通道且假定只使用1个卷积核即输出图像仅有一个通道。对于单通道输入与2D卷积不同之处在于输入图像多了一个深度(depth)维度,卷积核也多了一个$k_d$维度因此3D卷积核的尺寸为$(k_h, k_w, k_d)$,每次滑窗与$(k_h, k_w, k_d)$窗口内的值进行相关操作得到输出3D图像中的一个值。对于多通道输入则与2D卷积的操作一样每次滑窗与3个channels上的$(k_h, k_w, k_d)$窗口内的所有值进行相关操作得到输出3D图像中的一个值。
3D卷积操作如图所示同样分为单通道和多通道且假定只使用1个卷积核即输出图像仅有一个通道。对于单通道输入与2D卷积不同之处在于输入图像多了一个深度(depth)维度,卷积核也多了一个$k_d$维度因此3D卷积核的尺寸为$(k_h, k_w, k_d)$,每次滑窗与$(k_h, k_w, k_d)$窗口内的值进行相关操作得到输出3D图像中的一个值。对于多通道输入则与2D卷积的操作一样每次滑窗与3个channels上的$(k_h, k_w, k_d)$窗口内的所有值进行相关操作得到输出3D图像中的一个值。
![image](./img/ch5/img13.png)
## 5.7 有哪些池化方法?
池化操作通常也叫做子采样(Subsampling)或降采样(Downsampling),在构建卷积神经网络时,往往会用在卷积层之后,通过池化来降低卷积层输出的特征维度,有效减少网络参数的同时还可以防止过拟合现象。池化操作可以降低图像维度的原因,本质上是因为图像具有一种“静态性”的属性,这个意思是说在一个图像区域有用的特征极有可能在另一个区域同样有用。因此,为了描述一个大的图像,很直观的想法就是对不同位置的特征进行聚合统计。例如,可以计算图像在固定区域上特征的平均值 (或最大值)来代表这个区域的特征。
表5.6 池化分类
| 池化类型 | 示意图 | 作用 |
| :-----: | :-----: | :--- |
| 一般池化(General Pooling) | ![max_pooling](./img/ch5/general_pooling.png) | 通常包括最大池化(Max Pooling)和平均池化(Mean Pooling)。以最大池化为例,池化范围$(2\times2)$和滑窗步长$(stride=2)$ 相同,仅提取一次相同区域的范化特征。 |
| 重叠池化(Overlapping Pooling) | ![overlap_pooling](./img/ch5/overlap_pooling.png) | 与一般池化操作相同,但是池化范围$P_{size}$与滑窗步长$stride$关系为$P_{size}>stride$,同一区域内的像素特征可以参与多次滑窗提取,得到的特征表达能力更强,但计算量更大。 |
| 空间金字塔池化$^*$(Spatial Pyramid Pooling) | ![spatial_pooling](./img/ch5/spatial_pooling.png) | 在进行多尺度目标的训练时,卷积层允许输入的图像特征尺度是可变的,紧接的池化层若采用一般的池化方法会使得不同的输入特征输出相应变化尺度的特征,而卷积神经网络中最后的全连接层则无法对可变尺度进行运算,因此需要对不同尺度的输出特征采样到相同输出尺度。|
>SPPNet$^{[3]}$就引入了空间池化的组合,对不同输出尺度采用不同的滑窗大小和步长以确保输出尺度相同$(win_{size}=\lceil \frac{in}{out}\rceil; stride=\lfloor \frac{in}{out}\rfloor; )$,同时用如金字塔式叠加的多种池化尺度组合,以提取更加丰富的图像特征。常用于多尺度训练和目标检测中的区域提议网络(Region Proposal Network)的兴趣区域(Region of Interest)提取
表5.6 池化分类
### 5.7.1 一般池化General Pooling
池化操作与卷积操作不同,过程如下图。
| 池化类型 | 示意图 | 作用 |
| :-----------------------------------------: | :-----------------------------------------------: | :----------------------------------------------------------- |
| 一般池化(General Pooling) | ![max_pooling](./img/ch5/general_pooling.png) | 通常包括最大池化(Max Pooling)和平均池化(Mean Pooling)。以最大池化为例,池化范围$(2\times2)$和滑窗步长$(stride=2)$ 相同,仅提取一次相同区域的范化特征。 |
| 重叠池化(Overlapping Pooling) | ![overlap_pooling](./img/ch5/overlap_pooling.png) | 与一般池化操作相同,但是池化范围$P_{size}$与滑窗步长$stride$关系为$P_{size}>stride$,同一区域内的像素特征可以参与多次滑窗提取,得到的特征表达能力更强,但计算量更大。 |
| 空间金字塔池化$^*$(Spatial Pyramid Pooling) | ![spatial_pooling](./img/ch5/spatial_pooling.png) | 在进行多尺度目标的训练时,卷积层允许输入的图像特征尺度是可变的,紧接的池化层若采用一般的池化方法会使得不同的输入特征输出相应变化尺度的特征,而卷积神经网络中最后的全连接层则无法对可变尺度进行运算,因此需要对不同尺度的输出特征采样到相同输出尺度。 |
![image](./img/ch5/img14.png)
池化操作过程如图所示对固定区域的特征使用某一个值来表示。最常见的池化操作有两种分为平均池化mean pooling和最大池化max pooling
> SPPNet$^{[3]}$就引入了空间池化的组合,对不同输出尺度采用不同的滑窗大小和步长以确保输出尺度相同$(win_{size}=\lceil \frac{in}{out}\rceil; stride=\lfloor \frac{in}{out}\rfloor; )$,同时用如金字塔式叠加的多种池化尺度组合,以提取更加丰富的图像特征。常用于多尺度训练和目标检测中的区域提议网络(Region Proposal Network)的兴趣区域(Region of Interest)提取
1、平均池化计算图像区域的平均值作为该区域池化后的值。
2、最大池化选图像区域的最大值作为该区域池化后的值。
上述的池化过程,相邻的池化窗口间没有重叠部分。
### 5.7.2 重叠池化General Pooling
重叠池化即是一种相邻池化窗口之间会有重叠区域的池化技术。论文中[2]中作者使用了重叠池化其他的设置都不变的情况下top-1和top-5 的错误率分别减少了0.4% 和0.3%。
### 5.7.3 空金字塔池化Spatial Pyramid Pooling
空间金字塔池化可以将任意尺度的图像卷积特征转化为相同维度这不仅可以让CNN处理任意尺度的图像还能避免cropping和warping操作导致一些信息的丢失。一般的卷积神经网络都需要固定输入图像大小这是因为全连接层的输入需要固定输入维度但在卷积操作时并没有对图像大小有限制所以作者提出了空间金字塔池化方法先让图像进行卷积操作然后使用SPP方法转化成维度相同的特征最后输入到全连接层。
## 5.8 $1\times1$卷积作用?
![image](./img/ch5/img17.png)
NIN(Network in Network)$^{[4]}$是第一篇探索$1\times1$卷积核的论文这篇论文通过在卷积层中使用MLP替代传统线性的卷积核使单层卷积层内具有非线性映射的能力也因其网络结构中嵌套MLP子网络而得名NIN。NIN对不同通道的特征整合到MLP自网络中让不同通道的特征能够交互整合使通道之间的信息得以流通其中的MLP子网络恰恰可以用$1\times1$的卷积进行代替。
根据论文作者所述空间金字塔池化的思想来自于Spatial Pyramid Model,它是将一个pooling过程变成了多个尺度的pooling。用不同大小的池化窗口作用于卷积特征这样就可以得到1X1,2X2,4X4的池化结果由于conv5中共有256个滤波器所以得到1个256维的特征4个256个特征以及16个256维的特征然后把这21个256维特征链接起来输入全连接层通过这种方式把不同大小的图像转化成相同维度的特征。
![image](./img/ch5/img18.png)
对于不同的图像如果想要得到相同大小的pooling结果就需要根据图像大小动态的计算池化窗口大小和步长。假设conv5输出的大小为a*a需要得到n*n大小的池化结果可以让窗口大小sizeX为[a/n],步长为[a/n]。下图展示了以conv5输出大小是13*13为例spp算法的各层参数。
![image](./img/ch5/img19.png)
总结来说SPP方法其实就是一种使用多个尺度的池化方法可以获取图像中的多尺度信息。在卷积神经网络中加入SPP后可以让CNN处理任意大小的输入这让模型变得更加的灵活。
## 5.8 1x1卷积作用
1×1的卷积主要有以下两个方面的作用
1. 实现信息的跨通道交互和整合。
2. 对卷积核通道数进行降维和升维,减小参数量。
下面详细解释一下:
**第一点 实现信息的跨通道交互和整合**
对1×1卷积层的探讨最初是出现在NIN的结构论文作者的动机是利用MLP代替传统的线性卷积核从而提高网络的表达能力。文中从跨通道池化的角度进行解释认为文中提出的MLP其实等价于在传统卷积核后面接cccp层从而实现多个feature map的线性组合实现跨通道的信息整合。而查看代码实现cccp层即等价于1×1卷积层。
**第二点 对卷积核通道数进行降维和升维,减小参数量**
1x1卷积层能带来降维和升维的效果在一系列的GoogLeNet中体现的最明显。对于每一个Inception模块如下图左图是原始模块右图是加入1×1卷积进行降维的模块。虽然左图的卷积核都比较小但是当输入和输出的通道数很大时卷积核的参数量也会变的很大而右图加入1×1卷积后可以降低输入的通道数因此卷积核参数、运算复杂度也就大幅度下降。以GoogLeNet的3a模块为例输入的feature map是28×28×1923a模块中1×1卷积通道为643×3卷积通道为128,5×5卷积通道为32如果是左图结构那么卷积核参数为1×1×192×64+3×3×192×128+5×5×192×32而右图对3×3和5×5卷积层前分别加入了通道数为96和16的1×1卷积层这样卷积核参数就变成了1×1×192×64+1×1×192×96+3×3×96×128+1×1×192×16+5×5×16×32参数大约减少到原来的三分之一。同时在并行pooling层后面加入1×1卷积层后也可以降低输出的feature map数量左图pooling后feature map是不变的再加卷积层得到的feature map会使输出的feature map扩大到416如果每个模块都这样网络的输出会越来越大。而右图在pooling后面加了通道数为32的1×1卷积使得输出的feature map数降到了256。GoogLeNet利用1×1的卷积降维后得到了更为紧凑的网络结构虽然总共有22层但是参数数量却只是8层AlexNet的十二分之一当然其中也有丢掉全连接层的原因。
GoogLeNet$^{[5]}$则采用$1\times1$卷积核来减少模型的参数量。在原始版本的Inception模块中由于每一层网络采用了更多的卷积核大大增加了模型的参数量。此时在每一个较大卷积核的卷积层前引入$1\times1$卷积可以通过分离通道与宽高卷积来减少模型参数量。以图5.2为例,在不考虑参数偏置项的情况下,若输入和输出的通道数为$C_1=16$,则左半边网络模块所需的参数为$(1\times1+3\times3+5\times5+0)\times C_1\times C_1=8960$;假定右半边网络模块采用的$1\times1$卷积通道数为$C_2=8$$(满足C_1>C_2)$,则右半部分的网络结构所需参数量为$(1\times1\times (3C_1+C_2)+3\times3\times C_2 +5\times5\times C_2)\times C_1=5248$ ,可以在不改变模型表达能力的前提下大大减少所使用的参数量。
![image](./img/ch5/img20.png)
而非常经典的ResNet结构同样也使用了1×1卷积并且是在3×3卷积层的前后都使用了不仅进行了降维还进行了升维使得卷积层的输入和输出的通道数都减小参数数量进一步减少如下图结构所示。
![image](./img/ch5/img21.png)
图5.2 Inception模块
综上所述,$1\times 1$卷积的作用主要为以下两点:
- 实现信息的跨通道交互和整合。
- 对卷积核通道数进行降维和升维,减小参数量。
## 5.9 卷积层和池化层有什么区别?
首先可以从结构上可以看出,卷积之后输出层的维度减小,深度变深。但池化层深度不变。同时池化可以把很多数据用最大值或者平均值代替。目的是降低数据量。降低训练的参数。对于输入层,当其中像素在邻域发生微小位移时,池化层的输出是不变的,从而能提升鲁棒性。而卷积则是把数据通过一个卷积核变化成特征,便于后面的分离。
卷积层核池化层在结构上具有一定的相似性都是对感受域内的特征进行提取并且根据步长设置获取到不同维度的输出但是其内在操作是有本质区别的如表5.7所示。
1:卷积
| | 卷积层 | 池化层 |
| :--------: | :------------------------------------: | :------------------------------: |
| **结构** | 零填充时输出维度不变,而通道数改变 | 通常特征维度会降低,通道数不变 |
| **稳定性** | 输入特征发生细微改变时,输出结果会改变 | 感受域内的细微变化不影响输出结果 |
| **作用** | 感受域内提取局部关联特征 | 感受域内提取泛化特征,降低维度 |
| **参数量** | 与卷积核尺寸、卷积核个数相关 | 不引入额外参数 |
当从一个大尺寸图像中随机选取一小块,比如说 8x8 作为样本,并且从这个小块样本中学习到了一些特征,这时我们可以把从这个 8x8 样本中学习到的特征作为探测器,应用到这个图像的任意地方中去。特别是,我们可以用从 8x8 样本中所学习到的特征跟原本的大尺寸图像作卷积,从而对这个大尺寸图像上的任一位置获得一个不同特征的激活值。
下面给出一个具体的例子:假设你已经从一个 96x96 的图像中学习到了它的一个 8x8 的样本所具有的特征,假设这是由有 100 个隐含单元的自编码完成的。为了得到卷积特征,需要对 96x96 的图像的每个 8x8 的小块图像区域都进行卷积运算。也就是说,抽取 8x8 的小块区域并且从起始坐标开始依次标记为1112...一直到8989然后对抽取的区域逐个运行训练过的稀疏自编码来得到特征的激活值。在这个例子里显然可以得到 100 个集合,每个集合含有 89x89 个卷积特征。
![image](./img/ch5/img22.png)
2说下池化其实池化很容易理解先看图
转自: http://blog.csdn.net/silence1214/article/details/11809947
![image](./img/ch5/img23.png)
比如上方左侧矩阵A是20*20的矩阵要进行大小为10*10的池化那么左侧图中的红色就是10*10的大小对应到右侧的矩阵右侧每个元素的值是左侧红色矩阵每个元素的值得和再处于红色矩阵的元素个数也就是平均值形式的池化。
3上面说了下卷积和池化再说下计算中需要注意到的。在代码中使用的是彩色图彩色图有3个通道那么对于每一个通道来说要单独进行卷积和池化有一个地方尤其是进行卷积的时候要注意到隐藏层的每一个值是对应到一幅图的3个通道穿起来的所以分3个通道进行卷积之后要加起来正好才能对应到一个隐藏层的神经元上也就是一个feature上去。
## 5.10 卷积核是否一定越大越好?
首先,给出答案。不是。
在AlexNet网络结构中用到了一些非常大的卷积核比如11×11、5×5卷积核。之前研究者的想法是卷积核越大receptive field感受野越大因此获得的特征越好。虽说如此但是大的卷积核会导致计算量大幅增加不利于训练更深层的模型而相应的计算性能也会降低。于是在VGG、Inception网络中实验发现利用2个3×3卷积核的组合比1个5×5卷积核的效果更佳同时参数量3×3×2+1 VS 5×5×1+1会更少因此后来3×3卷积核被广泛应用在各种模型中。
多个小卷积核的叠加使用远比一个大卷积核单独使用效果要好的多,在连通性不变的情况下,大大降低了参数量和计算复杂度。当然,卷积核也不是越小越好,对于特别稀疏的数据,当使用比较小的卷积核的时候可能无法表示其特征,如果采用较大的卷积核则会导致复杂度极大的增加。
在早期的卷积神经网络中如LeNet-5、AlexNet用到了一些较大的卷积核$11\times11$和$5\times 5$受限于当时的计算能力和模型结构的设计无法将网络叠加得很深因此卷积网络中的卷积层需要设置较大的卷积核以获取更大的感受域。但是这种大卷积核反而会导致计算量大幅增加不利于训练更深层的模型相应的计算性能也会降低。后来的卷积神经网络VGG、GoogLeNet等发现通过堆叠2个$3\times 3$卷积核可以获得与$5\times 5$卷积核相同的感受视野,同时参数量会更少($3×3×2+1$ < $ 5×5×1+1$$3\times 3$卷积核被广泛应用在许多卷积神经网络中。因此可以认为,在大多数情况下通过堆叠较小的卷积核比直接采用单个更大的卷积核会更加有效。
但是,这并不是表示更大的卷积核就没有作用,在某些领域应用卷积神经网络时仍然可以采用较大的卷积核。譬如在自然语言处理领域,由于文本内容不像图像数据可以对特征进行很深层的抽象,往往在该领域的特征提取只需要较浅层的神经网络即可。在将卷积神经网络应用在自然语言处理领域时,通常都是较为浅层的卷积层组成,但是文本特征有时又需要有较广的感受域让模型能够组合更多的特征(如词组和字符),此时直接采用较大的卷积核将是更好的选择。
综上所述,卷积核的大小并没有绝对的优劣,需要视具体的应用场景而定,但是极大和极小的卷积核都是不合适的,单独的$1\times 1$极小卷积核只能用作分离卷积而不能对输入的原始特征进行有效的组合,极大的卷积核通常会组合过多的无意义特征从而浪费了大量的计算资源。
总而言之,我们多倾向于选择多个相对小的卷积核来进行卷积。
## 5.11 每层卷积是否只能用一种尺寸的卷积核?
经典的神经网络都属于层叠式网络并且每层仅用一个尺寸的卷积核例如VGG结构中使用了大量的3×3卷积层。事实上同一层feature map可以分别使用多个不同尺寸的卷积核以获得不同尺度的特征再把这些特征结合起来得到的特征往往比使用单一卷积核的要好例如GoogLeNet、Inception系列的网络均是每层使用了多个卷积核结构。如下图所示输入的feature map在同一层分别经过1×1、3×3、5×5三种不同尺寸的卷积核再将分别得到的特征进行组合。
经典的神经网络一般都属于层叠式网络每层仅用一个尺寸的卷积核如VGG结构中使用了大量的$3×3$卷积层。事实上同一层特征图可以分别使用多个不同尺寸的卷积核以获得不同尺度的特征再把这些特征结合起来得到的特征往往比使用单一卷积核的要好如GoogLeNet、Inception系列的网络均是每层使用了多个卷积核结构。如图5.3所示,输入的特征在同一层分别经过$1×1$、$3×3$和$5×5$三种不同尺寸的卷积核,再将分别得到的特征进行整合,得到的新特征可以看作不同感受域提取的特征组合,相比于单一卷积核会有更强的表达能力。
![image](./img/ch5/img24.png)
图5.3 Inception模块结构
## 5.12 怎样才能减少卷积层参数量?
发明GoogleNet的团队发现如果仅仅引入多个尺寸的卷积核会带来大量的额外的参数受到Network In Network中1×1卷积核的启发为了解决这个问题他们往Inception结构中加入了一些1×1的卷积核如图所示
减少卷积层参数量的方法可以简要地归为以下几点
![image](./img/ch5/img25.png)
- 使用堆叠小卷积核代替大卷积核VGG网络中2个$3\times 3$的卷积核可以代替1个$5\times 5$的卷积核
- 使用分离卷积操作:将原本$K\times K\times C$的卷积操作分离为$K\times K\times 1$和$1\times1\times C$的两部分操作
- 添加$1\times 1$的卷积操作:与分离卷积类似,但是通道数可变,在$K\times K\times C_1$卷积前添加$1\times1\times C_2$的卷积核(满足$C_2 <C_1$
- 在卷积层前使用池化操作:池化可以降低卷积层的输入特征维度
加入1×1卷积核的Inception结构
![image](./img/ch5/img26.png)
根据上图我们来做个对比计算假设输入feature map的维度为256维要求输出维度也是256维。有以下两种操作
* 1256维的输入直接经过一个3×3×256的卷积层输出一个256维的feature map那么参数量为256×3×3×256 = 589,824
* 2256维的输入先经过一个1×1×64的卷积层再经过一个3×3×64的卷积层最后经过一个1×1×256的卷积层输出256维参数量为256×1×1×64 + 64×3×3×64 + 64×1×1×256 = 69,632。足足把第一种操作的参数量降低到九分之一
1×1卷积核也被认为是影响深远的操作往后大型的网络为了降低参数量都会应用上1×1卷积核。
## 5.13 在进行卷积操作时,必须同时考虑通道和区域吗?
![image](./img/ch5/img27.png)
标准的卷积过程可以看上图一个2×2的卷积核在卷积时对应图像区域中的所有通道均被同时考虑那么问题来了为什么一定要同时考虑图像区域和通道呢能不能将通道和空间区域分开考虑
![image](./img/ch5/img28.png)
Xception网络由此诞生。我们首先对每一个通道进行各自的卷积操作有多少个通道就有多少个过滤器。得到新的通道feature maps之后这时再对这批新的通道feature maps进行标准的1×1跨通道卷积操作。这种操作被称为 “DepthWise convolution”称为深度可分离卷积。在imagenet 1000类分类任务中取得了非常鲁棒的效果同时也减少了大量的参数。我们可以通过一个例子来算一算使用深度可分离卷积能d假设输入通道数为3要求输出通道数为256。
1. 使用标准的卷积操作使用3×3×256的卷积核参数量为3×3×3×256 = 6,912
2. 使用深度可分离的结构分两步完成。参数量为3×3×3 + 3×1×1×256 = 795。
参数量仅为标准卷积的九分之一! 因此使用depthwise操作比标准的卷积操作在降低不少参数量的同时得到了更好的分类效果。
标准卷积中,采用区域与通道同时处理的操作,这样做可以简化卷积层内部的结构,每一个输出的特征像素都由所有通道的同一个区域提取而来。但是这种方式缺乏灵活性,并且在深层的网络结构中使得运算变得相对低效,更为灵活的方式是使区域和通道的卷积分离开来,通道分离(深度分离)卷积网络由此诞生。我们首先对每一个通道进行各自的卷积操作,有多少个通道就有多少个过滤器。得到新的通道特征矩阵之后,再对这批新通道特征进行标准的$1×1$跨通道卷积操作。
## 5.14 采用宽卷积的好处有什么?
### 5.14.1 窄卷积和宽卷积
宽卷积对应的是窄卷积,实际上并不是卷积操作的类型,指的是卷积过程中的填充方法,对应的是'SAME'填充和'VALID'填充。'SAME'填充通常采用零填充的方式对卷积核不满足整除条件的输入特征进行补全,以使卷积层的输出维度保持与输入特征维度一致;'VALID'填充的方式则相反实际并不进行任何填充在输入特征边缘位置若不足以进行卷积操作则对边缘信息进行舍弃因此在步长为1的情况下该填充方式的卷积层输出特征维度可能会略小于输入特征的维度。此外由于前一种方式通过补零来进行完整的卷积操作可以有效地保留原始的输入特征信息。
对于窄卷积来说是从第一个点开始做卷积每次窗口滑动固定步幅。比如下图左部分为窄卷积。那么注意到越在边缘的位置被卷积的次数越少。于是有了宽卷积的方法可以看作在卷积之前在边缘用0补充常见有两种情况一个是全补充入下图右部分这样输出大于输入的维度。另一种常用的方法是补充一部0值使得输出和输入的维度一致。这里文中给了一个公式 。这里npadding在全补充里是filter-1在输入输出相等时就要主要奇偶性了注意到卷积核常为奇数。
![image](./img/ch5/img29.png)
## 5.15 理解转置卷积与棋盘效应
### 5.14.2 为什么采用宽卷积?
### 5.15.1 转置卷积
通过将输入边角的值纳入到滑窗中心进行计算,以便损失更少的信息。
## 5.15 在卷积操作后,输出特征图(图像)大小如何计算?
在进行卷积操作时往往根据需要我们需设定一些参数。常见的参数有卷积核大小k, 窗口滑动的步长s, 进行填充的像素p, 假设输入特征图大小为Iw*Iw。则由以下公式可计算出输出特征图的大小Ow。
O_w = \frac{(I_w - k + 2p))}{s} + 1
## 5.16 如何得到卷积层输出的深度?
参数共享在卷积层中使用参数共享是用来控制参数的数量。假设在第一个卷积层就有55x55x96=290,400个神经元每个有11x11x3=364个参数和1个偏差。将这些合起来就是290400x364=105,705,600个参数。单单第一层就有这么多参数显然这个数目是非常大的。
作一个合理的假设:如果一个特征在计算某个空间位置(x,y)的时候有用,那么它在计算另一个不同位置(x2,y2)的时候也有用。基于这个假设可以显著地减少参数数量。换言之就是将深度维度上一个单独的2维切片看做深度切片depth slice比如一个数据体尺寸为[55x55x96]的就有96个深度切片每个尺寸为[55x55]。在每个深度切片上的神经元都使用同样的权重和偏差。在这样的参数共享下例子中的第一个卷积层就只有96个不同的权重集了一个权重集对应一个深度切片共有96x11x11x3=34,848个不同的权重或34,944个参数+96个偏差
```w_conv1=weight_variable([5,5,1,32])```
可以看出上面的32表示的是卷积层输出的深度因为大家都明白width和height都可以通过公式计算得到但是很多文献都没有告诉深度是如何得到的下面是我的认识
1. 因为这个深度是没有公式可以计算出来的因为深度是一个经验值如上面代码的32 其实是一个经验值是通过调整参数发现32是一个最合适的值可以得到最好的准确率但是不同的图像的深度是不一样的。
2. 这个深度表示用了多少个卷积核,下面这个图可以说明一下:
![image](./img/ch5/img30.png)
上图就可以很有效的说明 :卷积层输出的深度==卷积核的个数。
## 5.17 激活函数通常放在卷积神经网络的哪个操作之后?
通常放在卷积层之后。
## 5.18 如何理解最大池化层有几分缩小?
池化层:对输入的特征图进行压缩,一方面使特征图变小,简化网络计算复杂度;一方面进行特征压缩,提取主要特征。
池化操作一般有两种一种是Avy Pooling,一种是max Pooling。
![image](./img/ch5/img31.png)
同样地采用一个2*2的filter,max pooling是在每一个区域中寻找最大值这里的stride=2,最终在原特征图中提取主要特征得到右图。
>注1Avy pooling现在不怎么用了方法是对每一个2*2的区域元素求和再除以4得到主要特征而一般的filter取2*2,最大取3*3,stride取2压缩为原来的1/4.
>注2这里的pooling操作是特征图缩小有可能影响网络的准确度因此可以通过增加特征图的深度来弥补。
## 5.19 理解图像卷积与反卷积
### 5.19.1 图像卷积
@ -304,8 +245,8 @@ O_w = \frac{(I_w - k + 2p))}{s} + 1
经过上面的解释与推导对卷积有基本的了解但是在图像上的deconvolution究竟是怎么一回事可能还是不能够很好的理解因此这里再对这个过程解释一下。 目前使用得最多的deconvolution有2种上文都已经介绍。
* 方法1full卷积 完整的卷积可以使得原来的定义域变大。
* 方法2记录pooling index然后扩大空间再用卷积填充。
- 方法1full卷积 完整的卷积可以使得原来的定义域变大。
- 方法2记录pooling index然后扩大空间再用卷积填充。
图像的deconvolution过程如下
@ -320,74 +261,7 @@ O_w = \frac{(I_w - k + 2p))}{s} + 1
可以看出翻卷积的大小是由卷积核大小与滑动步长决定, in是输入大小 k是卷积核大小 s是滑动步长 out是输出大小 得到 out = (in - 1) * s + k 上图过程就是, (2 - 1) * 3 + 4 = 7
## 5.20 不同卷积后图像大小计算?
### 5.20.1 类型划分
2维卷积的计算分为了3类1.full 2.same 3. valid
1、**full**
![image](./img/ch5/img41.png)
蓝色为原图像白色为对应卷积所增加的padding通常全部为0绿色是卷积后图片。图6的卷积的滑动是从卷积核右下角与图片左上角重叠开始进行卷积滑动步长为1卷积核的中心元素对应卷积后图像的像素点。可以看到卷积后的图像是4X4比原图2X2大了我们还记1维卷积大小是n1+n2-1这里原图是2X2卷积核3X3卷积后结果是4X4与一维完全对应起来了。其实这才是完整的卷积计算其他比它小的卷积结果都是省去了部分像素的卷积
2、**same**
![image](./img/ch5/img42.png)
3、**valid**
![image](./img/ch5/img43.png)
### 5.20.2 计算公式
这里我们可以总结出fullsamevalid三种卷积后图像大小的计算公式
1. full: 滑动步长为1图片大小为N1xN1卷积核大小为N2xN2卷积后图像大小N1+N2-1 x N1+N2-1。
2. same: 滑动步长为1图片大小为N1xN1卷积核大小为N2xN2卷积后图像大小N1xN1。
3. valid:滑动步长为S图片大小为N1xN1卷积核大小为N2xN2卷积后图像大小(N1-N2)/S+1 x (N1-N2)/S+1。
## 5.21 步长、填充大小与输入输出关系总结?
在设计深度学习网络的时候,需要计算输入尺寸和输出尺寸,那么就要设计卷积层的的各种参数。这里有一些设计时候的计算公式,方便得到各层的参数。
这里简化下,约定:
![image](./img/ch5/img44.png)
### 5.21.1 没有0填充单位步长
![image](./img/ch5/img45.png)
### 5.21.2 零填充,单位步长
![image](./img/ch5/img46.png)
<1>半填充
![image](./img/ch5/img47.png)
<2>全填充
![image](./img/ch5/img48.png)
参考图如下图所示
![image](./img/ch5/img49.png)
![image](./img/ch5/img50.png)
### 5.21.3 不填充,非单位步长
![image](./img/ch5/img51.png)
### 5.21.4 零填充,非单位步长
![image](./img/ch5/img52.png)
![image](./img/ch5/img53.png)
![image](./img/ch5/img54.png)
![image](./img/ch5/img55.png)
http://blog.csdn.net/u011692048/article/details/77572024
https://arxiv.org/pdf/1603.07285.pdf
## 5.22 理解反卷积和棋盘效应
@ -439,179 +313,40 @@ C为卷积操作的卷积核。此时为上采样理解为反卷积操作中
发现插值增量图像可细分为原图像表示的矩阵下移1行后乘以1/2与原图像表示的矩阵上移1行后乘以1/2。
## 5.23 CNN主要的计算瓶颈
## 5.24 卷积神经网络的参数设置
卷积神经网络中常见的参数在其他类型的神经网络中也是类似的但是参数的设置还得结合具体的任务才能设置在合理的范围具体的参数列表如表XX所示。
表XX 卷积神经网络常见参数
| 参数名 | 常见设置 | 参数说明 |
| :----: | :-----: | :---- |
| 学习率(Learning Rate) | $0-1$ | 反向传播网络中更新权值矩阵的步长,在一些常见的网络中会在固定迭代次数或模型不再收敛后对学习率进行指数下降(如$lr=lr\times 0.1$)。当学习率越大计算误差对权值矩阵的影响越大,容易在某个局部最优解附近震荡;越小的学习率对网络权值的更新越精细,但是需要花费更多的时间去迭代 |
| 批次大小(Batch Size) | $1-N$ | 批次大小指定一次性流入模型的数据样本个数,根据任务和计算性能限制判断实际取值,在一些图像任务中往往由于计算性能和存储容量限制只能选取较小的值。在相同迭代次数的前提下,数值越大模型越稳定,范化能力越强,损失值曲线越平滑,模型也更快地收敛,但是每次迭代需要花费更多的时间 |
| 数据轮次(Epoch) | $1-N$ | 数据轮次指定所有训练数据在模型中训练的次数,根据数据集规模和分布情况会设置为不同的值。当模型较为简单或训练数据规模较小时,通常轮次不宜过高,否则模型容易过拟合;模型较为复杂或训练数据规模足够大时,可适当提高数据的训练轮次。 |
| 权重衰减系数(Weight Decay) | $0-0.001$ | 模型训练过程中反向传播权值更新的权重衰减值 |
CNN的训练主要是在卷积层和子采样层的交互上其主要的计算瓶颈是
* 1前向传播过程下采样每个卷积层的maps
* 2反向传播过程上采样高层子采样层的灵敏度map以匹配底层的卷积层输出maps的大小
* 3sigmoid的运用和求导。
## 5.25 提高卷积神经网络的范化能力
卷积神经网络与其他类型的神经网络类似在采用反向传播进行训练的过程中比较依赖输入的数据分布当数据分布较为极端的情况下容易导致模型欠拟合或过拟合表XX记录了提高卷积网络范化能力的方法。
表XX 提高卷积网络范化能力的方法
| 方法 | 说明 |
| :---: | :--- |
| 使用更多数据 | 在有条件的前提下,尽可能多地获取训练数据是最理想的方法,更多的数据可以让模型得到充分的学习,也更容易提高范化能力 |
| 使用更大批次 | 在相同迭代次数和学习率的条件下,每批次采用更多的数据将有助于模型更好的学习到正确的模式,模型输出结果也会更加稳定 |
| 调整数据分布 | 大多数场景下的数据分布是不均匀的,模型过多地学习某类数据容易导致其输出结果偏向于该类型的数据,此时通过调整输入的数据分布可以一定程度提高范化能力 |
| 调整目标函数 | 在某些情况下,目标函数的选择会影响模型的范化能力,如目标函数$f(y,y')=|y-y'|$在某类样本已经识别较为准确而其他样本误差较大的侵害概况下,不同类别在计算损失结果的时候距离权重是相同的,若将目标函数改成$f(y,y')=(y-y')^2$则可以使误差小的样本计算损失的梯度比误差大的样本更小,进而有效地平衡样本作用,提高模型范化能力 |
| 调整网络结构 | 在浅层卷积神经网络中,参数量较少往往使模型的范化能力不足而导致欠拟合,此时通过叠加卷积层可以有效地增加网络参数,提高模型表达能力;在深层卷积网络中,若没有充足的训练数据则容易导致模型过拟合,此时通过简化网络结构减少卷积层数可以起到提高模型范化能力的作用 |
| 数据增强 | 数据增强又叫数据增广,在有限数据的前提下通过平移、旋转、加噪声等一些列变换来增加训练数据,同类数据的表现形式也变得更多样,有助于模型提高范化能力,需要注意的是数据变化应尽可能不破坏元数数据的主体特征(如在图像分类任务中对图像进行裁剪时不能将分类主体目标裁出边界)。 |
| 权值正则化 | 权值正则化就是通常意义上的正则化,一般是在损失函数中添加一项权重矩阵的正则项作为惩罚项,用来惩罚损失值较小时网络权重过大的情况,此时往往是网络权值过拟合了数据样本(如$Loss=f(WX+b,y')+\frac{\lambda}{\eta}\sum{|W|}$)。 |
| 屏蔽网络节点 | 该方法可以认为是网络结构上的正则化,通过随机性地屏蔽某些神经元的输出让剩余激活的神经元作用,可以使模型的容错性更强。 |
> 对大多数神经网络模型同样通用
举例:
对于第一和第二个问题我们考虑的是如何用Matlab内置的图像处理函数去实现上采样和下采样的操作。对于上采样imresize函数可以搞定但需要很大的开销。一个比较快速的版本是使用Kronecker乘积函数kron。通过一个全一矩阵ones来和我们需要上采样的矩阵进行Kronecker乘积就可以实现上采样的效果。对于前向传播过程中的下采样imresize并没有提供在缩小图像的过程中还计算nxn块内像素的和的功能所以没法用。一个比较好和快速的方法是用一个全一的卷积核来卷积图像然后简单的通过标准的索引方法来采样最后卷积结果。例如如果下采样的域是2x2的那么我们可以用2x2的元素全是1的卷积核来卷积图像。然后再卷积后的图像中我们每个2个点采集一次数据y=x(1:2:end,1:2:end),这样就可以得到了两倍下采样,同时执行求和的效果。
对于第三个问题实际上有些人以为Matlab中对sigmoid函数进行inline的定义会更快其实不然Matlab与C/C++等等语言不一样Matlab的inline反而比普通的函数定义更费时间。所以我们可以直接在代码中使用计算sigmoid函数及其导数的真实代码。
## 5.24 卷积神经网络的经验参数设置
对于卷积神经网络的参数设置,没有很明确的指导原则,以下仅是一些经验集合。
1、learning-rate 学习率学习率越小模型收敛花费的时间就越长但是可以逐步稳健的提高模型精确度。一般初始设置为0.1然后每次除以0.2或者0.5来改进,得到最终值;
2、batch-size 样本批次容量影响模型的优化程度和收敛速度需要参考你的数据集大小来设置具体问题具体分析一般使用32或64在计算资源允许的情况下可以使用大batch进行训练。有论文提出大batch可以加速训练速度并取得更鲁棒的结果
3、weight-decay 权重衰减用来在反向传播中更新权重和偏置一般设置为0.005或0.001
4、epoch-number 训练次数包括所有训练样本的一个正向传递和一个反向传递训练至模型收敛即可和迭代次数iteration不一样
总之,不是训练的次数越多,测试精度就会越高。会有各种原因导致过拟合,比如一种可能是预训练的模型太复杂,而使用的数据集样本数量太少,种类太单一。
## 5.25 提高泛化能力的方法总结(代码示例)
本节主要以代码示例来说明可以提高网络泛化能力的方法。
代码实验是基于mnist数据集mnist是一个从0到9的手写数字集合共有60000张训练图片10000张测试图片。每张图片大小是28*28大小。目的就是通过各种手段来构建一个高精度的分类神经网络。
### 5.25.1 手段
一般来说,提高泛化能力的方法主要有以下几个:
> * 使用正则化技术
> * 增加神经网络层数
> * 使用恰当的代价函数
> * 使用权重初始化技术
> * 人为增广训练集
> * 使用dropout技术
### 5.25.2 主要方法
下面我们通过实验结果来判断每种手段的效果。
1普通的全连接神经网络
网络结构使用一个隐藏层其中包含100个隐藏神经元输入层是784输出层是one-hot编码的形式最后一层是Softmax层。损失函数采用对数似然代价函数60次迭代学习速率η=0.1随机梯度下降的小批量数据mini-SGD大小为10没使用正则化。在测试集上得到的结果是97.8%,代码如下:
```python
>>> import network3
>>> from network3 import Network
>>> from network3 import ConvPoolLayer, FullyConnectedLayer, SoftmaxLayer
>>> training_data, validation_data, test_data = network3.load_data_shared()
>>> mini_batch_size = 10
>>> net = Network([FullyConnectedLayer(n_in=784, n_out=100),
SoftmaxLayer(n_in=100, n_out=10)], mini_batch_size)
>>> net.SGD(training_data, 60, mini_batch_size, 0.1, validation_data, test_data)
```
2使用卷积神经网络 — 仅一个卷积层
输入层是卷积层卷积核大小是5*5一共20个特征映射。最大池化层的大小为2*2。后面接一层100个隐藏神经元的全连接层。结构如图所示
![image](./img/ch5/img62.png)
在这个结构中我们把卷积层和池化层看做是训练图像的特征提取而后的全连接层则是一个更抽象层次的特征提取整合全局信息。同样设定是60次迭代批量数据大小是10学习率是0.1.代码如下,
```python
>>> net = Network([
ConvPoolLayer(image_shape=(mini_batch_size, 1, 28, 28),
filter_shape=(20, 1, 5, 5),
poolsize=(2, 2)),
FullyConnectedLayer(n_in=20*12*12, n_out=100),
SoftmaxLayer(n_in=100, n_out=10)], mini_batch_size)
>>> net.SGD(training_data, 60, mini_batch_size, 0.1,
validation_data, test_data)
```
经过三次运行取平均后准确率是98.78%提高得较多。错误率降低了1/3。
3使用卷积神经网络 — 两个卷积层
我们接着插入第二个卷积层把它插入在之前结构的池化层和全连接层之间同样是使用5*5的局部感受野2*2的池化层。
```python
>>> net = Network([
ConvPoolLayer(image_shape=(mini_batch_size, 1, 28, 28),
filter_shape=(20, 1, 5, 5),
poolsize=(2, 2)),
ConvPoolLayer(image_shape=(mini_batch_size, 20, 12, 12),
filter_shape=(40, 20, 5, 5),
poolsize=(2, 2)),
FullyConnectedLayer(n_in=40*4*4, n_out=100),
SoftmaxLayer(n_in=100, n_out=10)], mini_batch_size)
>>> net.SGD(training_data, 60, mini_batch_size, 0.1, validation_data, test_data)
```
这一次准确率达到了99.06%。
4使用卷积神经网络 — 两个卷积层+线性修正单元(ReLU)+正则化
上面的网络结构我们使用的是Sigmod激活函数现在我们换成线性修正激活函数ReLU 同样设定参数为60次迭代学习速率η=0.03使用L2正则化正则化参数λ=0.1,代码如下:
```python
>>> from network3 import ReLU
>>> net = Network([
ConvPoolLayer(image_shape=(mini_batch_size, 1, 28, 28),
filter_shape=(20, 1, 5, 5),
poolsize=(2, 2),
activation_fn=ReLU),
ConvPoolLayer(image_shape=(mini_batch_size, 20, 12, 12),
filter_shape=(40, 20, 5, 5),
poolsize=(2, 2),
activation_fn=ReLU),
FullyConnectedLayer(n_in=40*4*4, n_out=100, activation_fn=ReLU),
SoftmaxLayer(n_in=100, n_out=10)], mini_batch_size)
>>> net.SGD(training_data, 60, mini_batch_size, 0.03,
validation_data, test_data, lmbda=0.1)
```
这一次准确率达到了99.23%超过了使用sigmoid激活函数的99.06%. ReLU的优势是当取最大极限时梯度不会饱和。
5卷积神经网络 —两个卷基层+线性修正单元(ReLU)+正则化+拓展数据集
拓展训练集数据的一个简单方法是将每个训练图像由一个像素来代替无论是上一个像素下一个像素或者左右的像素。其他的方法也有改变亮度改变分辨率图片旋转扭曲位移等。我们把50000幅图像人为拓展到250000幅图像。使用与第四小节一样的网络因为我们训练时使用了5倍的数据所以减少了过拟合的风险。
```python
>>> expanded_training_data, _, _ = network3.load_data_shared(
"../data/mnist_expanded.pkl.gz")
>>> net = Network([
ConvPoolLayer(image_shape=(mini_batch_size, 1, 28, 28),
filter_shape=(20, 1, 5, 5),
poolsize=(2, 2),
activation_fn=ReLU),
ConvPoolLayer(image_shape=(mini_batch_size, 20, 12, 12),
filter_shape=(40, 20, 5, 5),
poolsize=(2, 2),
activation_fn=ReLU),
FullyConnectedLayer(n_in=40*4*4, n_out=100, activation_fn=ReLU),
SoftmaxLayer(n_in=100, n_out=10)], mini_batch_size)
>>> net.SGD(expanded_training_data, 60, mini_batch_size, 0.03,
validation_data, test_data, lmbda=0.1)
```
这次得到了99.37的训练正确率。
6卷积神经网络 — 两个卷基层+线性修正单元(ReLU)+正则化+拓展数据集+继续插入额外的全连接层
继续上面的网络我们拓展全连接层的规模使用300个隐藏神经元和1000个神经元的额精度分别是99.46%和99.43%.
```python
>>> net = Network([
ConvPoolLayer(image_shape=(mini_batch_size, 1, 28, 28),
filter_shape=(20, 1, 5, 5),
poolsize=(2, 2),
activation_fn=ReLU),
ConvPoolLayer(image_shape=(mini_batch_size, 20, 12, 12),
filter_shape=(40, 20, 5, 5),
poolsize=(2, 2),
activation_fn=ReLU),
FullyConnectedLayer(n_in=40*4*4, n_out=100, activation_fn=ReLU),
FullyConnectedLayer(n_in=100, n_out=100, activation_fn=ReLU),
SoftmaxLayer(n_in=100, n_out=10)], mini_batch_size)
>>> net.SGD(expanded_training_data, 60, mini_batch_size, 0.03,
validation_data, test_data, lmbda=0.1)
```
这次取得了99.43%的精度。拓展后的网络并没有帮助太多。
7卷积神经网络 — 两个卷基层+线性修正单元(ReLU)+拓展数据集+继续插入额外的全连接层+dropout技术
dropout的基本思想就是在训练网络时随机的移除单独的激活值使得模型更稀疏不太依赖于训练数据的特质。我们尝试应用dropout到最终的全连接层(而不是在卷积层)。由于训练时间将迭代次数设置为40全连接层使用1000个隐藏神经元因为dropout会丢弃一些神经元。Dropout是一种非常有效且能提高泛化能力降低过拟合的方法
```python
>>> net = Network([
ConvPoolLayer(image_shape=(mini_batch_size, 1, 28, 28),
filter_shape=(20, 1, 5, 5),
poolsize=(2, 2),
activation_fn=ReLU),
ConvPoolLayer(image_shape=(mini_batch_size, 20, 12, 12),
filter_shape=(40, 20, 5, 5),
poolsize=(2, 2),
activation_fn=ReLU),
FullyConnectedLayer(
n_in=40*4*4, n_out=1000, activation_fn=ReLU, p_dropout=0.5),
FullyConnectedLayer(
n_in=1000, n_out=1000, activation_fn=ReLU, p_dropout=0.5),
SoftmaxLayer(n_in=1000, n_out=10, p_dropout=0.5)],
mini_batch_size)
>>> net.SGD(expanded_training_data, 40, mini_batch_size, 0.03,
validation_data, test_data)
```
使用dropout得到了99.60%的准确率。
8卷积神经网络 — 两个卷基层+线性修正单元(ReLU)+正则化+拓展数据集+继续插入额外的全连接层+弃权技术+组合网络
组合网络类似于随机森林或者adaboost的集成方法创建几个神经网络让他们投票来决定最好的分类。我们训练了5个不同的神经网络每个都大到了99.60%的准去率用这5个网络来进行投票表决一个图像的分类。
采用这种集成方法精度又得到了微小的提升达到了99.67%。
## 5.26 CNN在CV与NLP领域运用的联系与区别
## 5.26 卷积神经网络在不同领域的应用
卷积神经网络中的卷积操作是其关键组成而卷积操作只是一种数学运算方式实际上对不同类型的数值表示数据都是通用的尽管这些数值可能表示的是图像像素值、文本序列中单个字符或是语音片段中单字的音频。只要使原始数据能够得到有效地数值化表示卷积神经网络能够在不同的领域中得到应用要关注的是如何将卷积的特性更好地在不同领域中应用如表XX所示。
表XX 卷积神经网络不同领域的应用
| 应用领域 | 输入数据图示 | 说明 |
| :-----: | :----------: | :-- |
| 图像处理 | ![image_process](img/ch5/Image-process.png) | |
| 自然语言处理 | ![NLP](img/ch5/NLP.png) | |
| 语音处理 | ![audio_process](img/ch5/audio-recognition.png) | |
### 5.26.1 联系
@ -626,7 +361,9 @@ dropout的基本思想就是在训练网络时随机的移除单独的激活值
2. 局部组合性CNN中每个滤波器都把较低层的局部特征组合生成较高层的更全局化的特征。这在CV里很好理解像素组合成边缘边缘生成形状最后把各种形状组合起来得到复杂的物体表达。在语言里当然也有类似的组合关系但是远不如图像来的直接。而且在图像里相邻像素必须是相关的相邻的词语却未必相关。
## 5.27 卷积神经网络凸显共性的方法?
### 5.27.1 局部连接
我们首先了解一个概念,感受野,即每个神经元仅与输入神经元相连接的一块区域。
在图像卷积操作中,神经元在空间维度上是局部连接,但在深度上是全连接。局部连接的思想,是受启发于生物学里的视觉系统结构,视觉皮层的神经元就是仅用局部接受信息。对于二维图像,局部像素关联性较强。这种局部连接保证了训练后的滤波器能够对局部特征有最强的响应,使神经网络可以提取数据的局部特征;
下图是一个很经典的图示,左边是全连接,右边是局部连接。
@ -636,6 +373,7 @@ dropout的基本思想就是在训练网络时随机的移除单独的激活值
对于一个1000 × 1000的输入图像而言如果下一个隐藏层的神经元数目为10^6个采用全连接则有1000 × 1000 × 10^6 = 10^12个权值参数如此巨大的参数量几乎难以训练而采用局部连接隐藏层的每个神经元仅与图像中10 × 10的局部图像相连接那么此时的权值参数数量为10 × 10 × 10^6 = 10^8将直接减少4个数量级。
### 5.27.2 权值共享
权值共享,即计算同一深度的神经元时采用的卷积核参数是共享的。权值共享在一定程度上讲是有意义的,是由于在神经网络中,提取的底层边缘特征与其在图中的位置无关。但是在另一些场景中是无意的,如在人脸识别任务,我们期望在不同的位置学到不同的特征。
需要注意的是,权重只是对于同一深度切片的神经元是共享的。在卷积层中,通常采用多组卷积核提取不同的特征,即对应的是不同深度切片的特征,而不同深度切片的神经元权重是不共享。相反,偏置这一权值对于同一深度切片的所有神经元都是共享的。
权值共享带来的好处是大大降低了网络的训练难度。如下图假设在局部连接中隐藏层的每一个神经元连接的是一个10 × 10的局部图像因此有10 × 10个权值参数将这10 × 10个权值参数共享给剩下的神经元也就是说隐藏层中10^6个神经元的权值参数相同那么此时不管隐藏层神经元的数目是多少需要训练的参数就是这 10 × 10个权值参数也就是卷积核的大小
@ -650,11 +388,19 @@ dropout的基本思想就是在训练网络时随机的移除单独的激活值
![image](./img/ch5/img65.png)
## 5.28 全卷积与Local-Conv的异同点
## 5.28 全连接、局部连接、全卷积与局部卷积
大多数神经网络中高层网络通常会采用全连接层(Global Connected Layer),通过多对多的连接方式对特征进行全局汇总,可以有效地提取全局信息。但是全连接的方式需要大量的参数,是神经网络中最占资源的部分之一,因此就需要由局部连接(Local Connected Layer),仅在局部区域范围内产生神经元连接,能够有效地减少参数量。根据卷积操作的作用范围可以分为全卷积(Global Convolution)和局部卷积(Local Convolution)。实际上这里所说的全卷积就是标准卷积,即在整个输入特征维度范围内采用相同的卷积核参数进行运算,全局共享参数的连接方式可以使神经元之间的连接参数大大减少;局部卷积又叫平铺卷积(Tiled Convolution)或非共享卷积(Unshared Convolution)是局部连接与全卷积的折衷。四者的比较如表XX所示。
表XX 卷积网络中连接方式的对比
| 连接方式 | 示意图 | 说明 |
| :------: | :---: | :--- |
| 全连接 | ![full-connected](img/ch5/full-connected.png) | 层间神经元完全连接,每个输出神经元可以获取到所有输入神经元的信息,有利于信息汇总,常置于网络末层;连接与连接之间独立参数,大量的连接大大增加模型的参数规模。 |
| 局部连接 | ![local-connected](img/ch5/local-connected.png) | 层间神经元只有局部范围内的连接,在这个范围内采用全连接的方式,超过这个范围的神经元则没有连接;连接与连接之间独立参数,相比于全连接减少了感受域外的连接,有效减少参数规模 |
| 全卷积 | ![convolution](img/ch5/conv.png) | 层间神经元只有局部范围内的连接,在这个范围内采用全连接的方式,连接所采用的参数在不同感受域之间共享,有利于提取特定模式的特征;相比于局部连接,共用感受域之间的参数可以进一步减少参数量。 |
| 局部卷积 | ![local-conv](img/ch5/local-conv.png) | 层间神经元只有局部范围内的连接,感受域内采用全连接的方式,而感受域之间间隔采用局部连接与全卷积的连接方式;相比与全卷积成倍引入额外参数,但有更强的灵活性和表达能力;相比于局部连接,可以有效控制参数量 |
如果每一个点的处理使用相同的Filter则为全卷积如果使用不同的Filter则为Local-Conv。
## 5.29 举例理解Local-Conv的作用
## 5.29 局部卷积的应用
并不是所有的卷积都会进行权重共享在某些特定任务中会使用不权重共享的卷积。下面通过人脸这一任务来进行讲解。在读人脸方向的一些paper时会发现很多都会在最后加入一个Local Connected Conv也就是不进行权重共享的卷积层。总的来说这一步的作用就是使用3D模型来将人脸对齐从而使CNN发挥最大的效果。
![image](./img/ch5/img66.png)
@ -685,17 +431,4 @@ Softmax: 4030维。
使用不共享的卷积核,由于需要训练的参数量大大增加,因此往往需要通过其他方法增加数据量。
## 5.30 简述卷积神经网络进化史
主要讨论CNN的发展并且引用刘昕博士的思路对CNN的发展作一个更加详细的介绍将按下图的CNN发展史进行描述
![image](./img/ch5/img67
1. 列表项
http://mp.weixin.qq.com/s?__biz=MzI1NTE4NTUwOQ==&mid=2650324619&idx=1&sn=ca1aed9e42d8f020d0971e62148e13be&scene=1&srcid=0503De6zpYN01gagUvn0Ht8D#wechat_redirect
CNN的演化路径可以总结为以下几个方向
> * 进化之路一:网络结构加深
> * 进化之路二:加强卷积功能
> * 进化之路三:从分类到检测
> * 进化之路四:新增功能模块