1. 原始 CNN 原理简介
参考:《Python 深度学习》
1.1 简介
- CNN:Convolutional Neural Network, 卷积神经网络,也叫 convnet.
- 卷积层与全连接层的区别:全连接层学到的是全局模式,卷积层学到的是局部模式。
- 卷积神经网络的两个重要性质:(1) 学习到的模式具有平移不变性 (translation invariant),例如,在图像左下角学到的模式,可以在任何地方识别,这使得模型通过较少的数据就可以学习到具有泛化能力的数据表示。
(2) 可以学习到模式的空间层次结构 (spatial hierarchies of patterns),第一层卷积学习到较小的局部模式,第二层卷积将学习到由第一层特征组成的更大的模式。
1.2 卷积计算
- 卷积计算过程:

第一个feature map中[0,0]位置元素的计算过程:
(
0
0
0
0
0
1
0
0
1
)
∗
(
1
1
−
1
−
1
0
1
−
1
−
1
0
)
=
1
\left( \begin{array}{ccc} 0 & 0 & 0 \\ 0 & 0 & 1 \\ 0 & 0 & 1 \end{array} \right) * \left( \begin{array}{ccc} 1 & 1 & -1 \\ -1 & 0 & 1 \\ -1 & -1 & 0 \end{array} \right)=1
⎝⎛000000011⎠⎞∗⎝⎛1−1−110−1−110⎠⎞=1,
(
0
0
0
0
1
1
0
0
2
)
∗
(
−
1
0
−
1
0
0
−
1
1
−
1
0
)
=
−
1
\left( \begin{array}{ccc} 0 & 0 & 0 \\ 0 & 1 & 1 \\ 0 & 0 & 2 \end{array} \right) * \left( \begin{array}{ccc} -1 & 0 & -1 \\ 0 & 0 & -1 \\ 1 & -1 & 0 \end{array} \right)=-1
⎝⎛000010012⎠⎞∗⎝⎛−10100−1−1−10⎠⎞=−1,
(
0
0
0
0
2
0
0
0
0
)
∗
(
0
1
0
1
0
1
0
−
1
1
)
=
0
\left( \begin{array}{ccc} 0 & 0 & 0 \\ 0 & 2 & 0 \\ 0 & 0 & 0 \end{array} \right) * \left( \begin{array}{ccc} 0 & 1 & 0 \\ 1 & 0 & 1 \\ 0 & -1 & 1 \end{array} \right)=0
⎝⎛000020000⎠⎞∗⎝⎛01010−1011⎠⎞=0
因此, 1 + ( − 1 ) + 0 + b 0 = 1 + ( − 1 ) + 0 + 1 = 1 1+(-1)+0+b_0=1+(-1)+0+1=1 1+(−1)+0+b0=1+(−1)+0+1=1
- 特征图 (feature map):包含两个空间轴(高度和宽度)和一个深度轴(也叫通道轴)的3D张量。经过卷积计算后生成输出特征图 (output feature map),输出特征图中的一个叫做响应图 (response map),即其中一个过滤器对输入的响应,也代表一个输出通道上的特征。
- 过滤器 (filter):与特征图进行相乘的矩阵组(权重矩阵),每一个过滤器中的卷积核个数与前一层的通道数相同,过滤器的数目即输出通道值。卷积核 (convolution kernel) 的大小一般选作 3 × 3 3\times 3 3×3或者 5 × 5 5\times 5 5×5。每一个过滤器或输出通道意味着提取一种抽象特征。
- 填充 (padding):有两种设置,(1) “valid”,表示不使用填充,只使用有效的窗口位置,也是该设置参数的默认设置。(2) “same”,使用填充,在输入特征图的四周填充一定的行和列,使得原始输入特征图中的每一个方块都能作为卷积窗口的中心,这样输出特征图的高度和宽度与原始输入特征图相同。
- 输入特征图大小 (input_shape):(image_height, image_width, image_channels),即 (行数, 列数, channels)。
- 感受野:当前窗口覆盖原始样例输入窗口的大小。
- 步幅 (stride):卷积核在特征图上滑动的步子大小,即连续两个窗口的距离,默认值为 1 1 1。也可以使用步幅大于 1 1 1的卷积,即步进卷积 (strided convolution),步进卷积在实际中很少使用,因为这可能导致错过或淡化特征是否存在的信息。举例,步幅为2意味着特征图的高度和宽度都被做了2倍下采样。
- 图像下采样 (subsampled, downsampled):
参考:https://blog.youkuaiyun.com/stf1065716904/article/details/78450997
简单总结:图像下采样即缩小图像,经过缩小,原来图像中的一个 s ∗ s s*s s∗s窗口在新的图像中将会变成一个像素点,这个像素可能是 s ∗ s s*s s∗s窗口内所有像素的均值。
1.3 最大池化 (max-pooling) 计算
- max-pooling计算的作用:对特征图进行下采样,与步进卷积类似。max-pooling经常使用 2 × 2 2\times 2 2×2 的窗口和步幅 2 2 2 将特征图下采样 2 2 2 倍。
- max-pooling的原因:(1) 减少需要处理的特征图的元素个数,即降维。
(2) 使卷积层的观察窗口(感受野)越来越大。 - 计算过程: ( 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ) \left( \begin{array}{cccc} 1 & 2 & 3 & 4 \\ 5 & 6 & 7 & 8 \\ 9 & 10 & 11 & 12 \\ 13 & 14 & 15 & 16 \end{array} \right) ⎝⎜⎜⎛15913261014371115481216⎠⎟⎟⎞ max-pooling后的结果为 ( 6 8 14 16 ) \left( \begin{array}{cc} 6 & 8 \\ 14 & 16 \end{array} \right) (614816)
2. CNN 用于文本分类原理简介
参考:https://cloud.tencent.com/developer/article/1028705
所提论文:Convolutional Neural Networks for Sentence Classification
2.1 textCNN简介
- 提出论文:Convolutional Neural Networks for Sentence Classification
- 模型框架:模型框架如下图所示,

(注释:上图中经过卷积后的向量均少画了一个维度。)
- 说明:(1) 在textCNN中,输入的特征图矩阵中,每一行代表一个单词的词向量。
(2) 过滤器中卷积核的宽度必须与词向量的维度一样大,因为拿出一个单词词向量的一部分是没有意义的。卷积核的高度可以随意设置。
(3) 输入的特征图可以有多个通道,例如设置channel=2,一个通道中的矩阵为固定的初始化的词向量矩阵,另一个通道中的矩阵为进行微调的初始化的词向量矩阵。 - textCNN 计算过程:
- 首先,令 X i ∈ R k X_i \in \mathbb{R}^k Xi∈Rk是句子中第 i 个单词的词向量,一个长度为n的句子表示为, X 1 : n = X 1 ⊕ X 2 ⊕ ⋯ ⊕ X n X_{1:n}=X_1\oplus X_2\oplus \cdots \oplus X_n X1:n=X1⊕X2⊕⋯⊕Xn,符号 ⊕ \oplus ⊕表示连接,假设只有一个通道。
- 令一个过滤器中的卷积核为
W
∈
R
h
×
k
W\in \mathbb{R}^{h\times k}
W∈Rh×k,该卷积核与一个包含h个词的词窗口
X
i
:
i
+
h
−
1
X_{i:i+h-1}
Xi:i+h−1进行卷积计算得到一个特征
c
i
c_i
ci:
c i = f ( W ∗ X i : i + h − 1 + b ) c_i=f(W*X_{i:i+h-1}+b) ci=f(W∗Xi:i+h−1+b)
其中, b b b为偏置, f f f为非线性激活函数。该过滤器与句子中的每一个词窗口 { X 1 : h , X 2 : h + 1 , … , X n − h + 1 : n } \{ X_{1:h},X_{2:h+1},\dots,X_{n-h+1:n}\} {X1:h,X2:h+1,…,Xn−h+1:n}作卷积计算得到响应图 c = [ c 1 , … , c n − h + 1 ] \mathbf{c}=[c_1,\dots,c_{n-h+1}] c=[c1,…,cn−h+1],响应图 c ∈ R n − h + 1 \mathbf{c}\in \mathbb{R}^{n-h+1} c∈Rn−h+1是一个向量。 - 然后进行max-pooling操作 c ^ = m a x ( c ) \widehat{c}=max(\mathbf{c}) c =max(c),假设有m个过滤器,经过max-pooling操作后得到特征图 z = [ c ^ i , … , c ^ m ] \mathbf{z}=[\widehat{c}_i,\dots,\widehat{c}_m] z=[c i,…,c m], z ∈ R m \mathbf{z}\in \mathbb{R}^{m} z∈Rm是一个向量。
- 最后,将向量
z
\mathbf{z}
z输入到一个全连接层得到最终的输出
y
y
y:
y = f ( W ~ ⋅ z + b ~ ) y=f(\widetilde{W}\cdot\mathbf{z}+\widetilde{b}) y=f(W ⋅z+b )
2.2 优化
- CNN-multichannel
- dropout
- L2 norms
2.3 超参数调节
参考:
(1) 论文 A Sensitivity Analysis of (and Practitioners’ Guide to) Convolutional Neural Networks for Sentence Classification
(2) 以上论文的笔记
2.3.1 关于超参数调节中的几个概念
- K-Max Pooling:取所选size范围内topK的值,并保留这些特征值原始的先后顺序。
- K-Max Pooling的好处:可以表达同一类特征出现多次的情形,即可以表达某类特征的强度;另外,因为这些Top K特征值的相对顺序得以保留,所以应该说其保留了部分位置信息,但是这种位置信息只是特征间的相对顺序,而非绝对位置信息。
- 以上K-Max Pooling参考:https://blog.youkuaiyun.com/malefactor/article/details/51078135,http://www.elecfans.com/rengongzhineng/580083_2.html
2.4 字符级CNN用于文本分类
参考:(1) 论文Character-level Convolutional Networks for Text Classification
(2) 以上论文的笔记
2.4.1 简介
-
关于输入
- 首先,根据语料构建一个字母表,字母表的大小记为 m m m,论文中 m = 70 m=70 m=70。
- 然后,对字母表使用one-hot进行编码,再额外增加一个全零向量用来表示不在字母表中的字符以及空白字符。那么,每个字母使用 m m m维的one-hot向量表示。需要注意的是,字符的离散化顺序是反向的,即反向处理字符编码,这样最新读入的字符总是在输出开始的地方。(注释,不理解反向处理字符编码)
- 将每个序列的长度固定为 l 0 l_0 l0,超过长度 l 0 l_0 l0的字符都被忽略掉。
- 然后就可以将 l 0 × m l_0 \times m l0×m维的输入矩阵输入到网络中。
-
论文中模型的结构:论文中设计了两个卷积网络,一个大的ConvNet和一个小的ConvNet,其分别令 l 0 = 1024 l_0=1024 l0=1024 和 l 0 = 256 l_0=256 l0=256,两个网络均有6个卷积层和3个全连接层,均在3个全连接层中插入两个dropout模块进行正则化,dropout的概率为0.5。
- 卷积层的具体结构如下图所示:
- 全连接层的具体结构如下图所示:
- 网络的总体框架如下图所示:
2.4.2 如何处理中文
参考论文:Character-level Convolutional Network for Text Classification Applied to Chinese Corpus
2.4.2 数据增强
- 替换同义词