赞
踩
本系列为斯坦福CS224n《自然语言处理与深度学习(Natural Language Processing with Deep Learning)》的全套学习笔记,对应的课程视频可以在 这里 查看。
ShowMeAI为CS224n课程的全部课件,做了中文翻译和注释,并制作成了 GIF动图!点击 第11讲-NLP中的卷积神经网络 查看的课件注释与带学解读。更多资料获取方式见文末。
CS224n是顶级院校斯坦福出品的深度学习与自然语言处理方向专业课程,核心内容覆盖RNN、LSTM、CNN、transformer、bert、问答、摘要、文本生成、语言模型、阅读理解等前沿内容。
本篇笔记对应斯坦福CS224n自然语言处理专项课程的知识板块:NLP中的卷积神经网络。主要讲解卷积神经网络的结构,及其在NLP场景下的使用方式,一些模块和可调结构。
卷积神经网络是一种特殊结构的神经网络,最早被广泛应用于计算机视觉领域,但在NLP领域同样有着显著的应用效果。它相对于传统神经网络,引入了局部感受野和多滤波器概念,能在控制参数量的情况下,对输入数据进行高效地处理。具体到NLP中,它接收词向量的序列,并首先为所有子短语创建短语向量(embedding),然后CNNs 基于卷积核并行完成数据处理计算。
(关于CNN的细节也可以参考ShowMeAI的对吴恩达老师课程的总结文章 深度学习教程 | 卷积神经网络解读,内含动图讲解)
我们从一维的情况开始。考虑两个一维向量 f f f 和 g g g ,其中 f f f 是主向量, g g g 是 filter。 f f f 和 g g g 之间的卷积,第 n n n 项处的值表示为 ( f ∗ g ) [ n ] (f \ast g)[n] (f∗g)[n],它等于 ∑ m = − M M f [ n − m ] g [ m ] \sum_{m=-M}^{M} f[n-m] g[m] ∑m=−MMf[n−m]g[m] 。
对于二维卷积而言,计算如下所示, 9 × 9 9\times9 9×9 的绿色矩阵表示关注的主矩阵 f f f (在实际应用中就是输入数据矩阵)。 3 × 3 3\times3 3×3 的红色矩阵表示 filter g g g,当前正在计算的卷积位于起始位置,计算方式为 filter 和 input 区域的逐元素乘法再求和,计算结果为4。
这里使用 ShowMeAI 深度学习教程 | 卷积神经网络解读 文章中的一个动态计算过程:
考虑单词向量
x
i
∈
R
k
x_{i} \in R^{k}
xi∈Rk 和一个
n
n
n 个单词的句子的单词向量串联,
x
1
:
n
=
x
1
⊕
x
2
…
⊕
x
n
x_{1 : n}=x_{1} \oplus x_{2} \ldots \oplus x_{n}
x1:n=x1⊕x2…⊕xn 。最后,考虑卷积滤波器
w
∈
R
h
k
w \in R^{h k}
w∈Rhk ,即作用于
h
h
h 个单词。对于
k
=
2
,
n
=
5
,
h
=
3
k = 2, n = 5, h = 3
k=2,n=5,h=3,上图为NLP的单层卷积层。在 the country of my birth
这个句子中,连续三个单词的每一个可能组合都将得到一个值。
注意,滤波器
w
w
w 本身是一个向量,我们将有
c
i
=
f
(
w
T
x
i
:
i
∣
h
−
1
+
b
)
c_{i}=f\left(w^{T} x_{i : i | h-1}+b\right)
ci=f(wTxi:i∣h−1+b) 来给出
c
=
[
c
1
,
c
2
…
c
n
−
h
+
1
]
∈
R
n
−
h
+
1
\mathbf{c}=\left[c_{1}, c_{2} \dots c_{n-h+1}\right] \in R^{n-h+1}
c=[c1,c2…cn−h+1]∈Rn−h+1 。最后两个时间步,即从 my
或 birth
开始,我们没有足够的字向量来与滤波器相乘(因为
h
=
3
h = 3
h=3)。如果我们需要与后两个词向量相关的卷积,一个常见的技巧是用
h
−
1
h - 1
h−1个零向量填充句子的右边,如上图所示。
假设我们不使用补零,我们将得到最终的卷积输出, c \mathbf{c} c 有 n − h + 1 n-h+1 n−h+1 个数。通常,我们希望接收CNN的输出,并将其作为输入,输入到更深层,如前馈神经网络或RNN。但是,所有这些都需要一个固定长度的输入,而CNN输出的长度依赖于句子的长度 n n n 。解决这个问题的一个聪明的方法是使用max-pooling。CNN的输出 c ∈ R n − h − 1 \mathbf{c} \in \mathbb{R}^{n-h-1} c∈Rn−h−1 是 max-pooling 层的输入。max-pooling 的输出层 c ^ = max c \hat{c}=\max {\mathbf{c}} c^=maxc ,因此 c ^ ∈ R \hat{c} \in \mathbb{R} c^∈R 。
我们也可以使用最小池化,因为通常我们使用 ReLU 作为非线性激活函数而ReLU的下界是 0 0 0。因此,一个最小池化可能会被 ReLU 覆盖,所以我们几乎总是使用最大池化而不是最小池化。
在上面与图2相关的例子中,我们有 h = 2 h = 2 h=2,这意味着我们只使用一个特定的组合方法,即使用过滤器来查看 bi-grams。我们可以使用多个 bi-grams 过滤器,因为每个过滤器将学习识别不同类型的 bi-grams。更一般地说,我们并不仅限于使用 bi-grams ,还可以使用 tri-grams、 quad-grams 甚至更长的过滤器。每个过滤器都有一个关联的最大池化层。因此,CNN 层的最终输出将是一个长度等于过滤器数量的向量。
如果我们允许梯度流入这里使用的单词向量,那么单词向量可能会随着训练而发生显著变化。这是需要的,因为它将单词向量专门用于当前特定任务(远离 GloVe 初始化)。但是,如果单词只出现在测试集中而没有出现在训练集上呢?虽然出现在训练集中的其他语义相关的单词向量将从它们的起始点显著移动,但是这些单词仍将处于它们的初始点。神经网络将专门用于已更新的输入。因此,我们在使用这些单词的句子中会表现得很差。
一种方法是维护两组单词向量,一组“静态”(没有梯度流)和一组“动态”(通过 SGD 更新)。它们最初是一样的(GloVe 或者其他初始化)。这两个集合同时作为神经网络的输入。因此,初始化的词向量在神经网络的训练中始终起着重要的作用。在测试中给出看不见的单词可以提高正确理解的几率。
有几种处理这两个 channel 的方法,最常见的是在 CNN 中使用之前对它们进行平均。另一种方法是将 CNN 过滤器的长度加倍。也可以在经过卷积层之后得到feature maps再进行合并(比如下图一样做pooling操作合并)
参见上图。另一种问这个问题的方法是我们应该缩小还是扩大?即我们是否使用 zero-pad?
如果我们使用窄卷积,我们只在一个滤波器的所有分量都有一个匹配输入分量的位置计算卷积。在输入的开始和结束边界处显然不是这样,如图4中的左侧网络所示。
如果我们使用宽卷积,我们有一个输出分量对应于卷积滤波器的每个对齐。为此,我们必须在输入的开始和结束处填充 h − 1 h - 1 h−1 个零。
在窄卷积情况下,输出长度为 n − h + 1 n - h+ 1 n−h+1 ,而在宽卷积情况下,输出长度为 n + h − 1 n+h - 1 n+h−1。
这是对最大池化层的概括。k-max 池化层不是只从它的输入中选择最大的值,而是选择 k k k 个最大的值(并且保持原有的顺序)。设置 k = 1 k = 1 k=1 则是我们前面看到的最大池化层。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。