文本情感分类
文本分类是自然语言处理的一个常见任务,它把一段不定长的文本序列变换为文本的类别。
它的一个子问题:使用文本情感分类来分析文本作者的情绪。这个问题也叫情感分析,并有着广泛的应用。
同搜索近义词和类比词一样,文本分类也属于词嵌入的下游应用。在本节中,我们将应用预训练的词向量和含多个隐藏层的双向循环神经网络与卷积神经网络,来判断一段不定长的文本序列中包含的是正面还是负面的情绪。
预处理数据
读取数据后,我们先根据文本的格式进行单词的切分,再利用 torchtext.vocab.Vocab
创建词典。
词典和词语的索引创建好后,就可以将数据集的文本从字符串的形式转换为单词下标序列的形式,以待之后的使用。
双向循环神经网络
在“双向循环神经网络”一节中,我们介绍了其模型与前向计算的公式,这里简单回顾一下:
给定输入序列 { X 1 , X 2 , … , X T } \{\boldsymbol{X}_1,\boldsymbol{X}_2,\dots,\boldsymbol{X}_T\} {X1,X2,…,XT},其中 X t ∈ R n × d \boldsymbol{X}_t\in\mathbb{R}^{n\times d} Xt∈Rn×d 为时间步(批量大小为 n n n,输入维度为 d d d)。在双向循环神经网络的架构中,设时间步 t t t 上的正向隐藏状态为 H → t ∈ R n × h \overrightarrow{\boldsymbol{H}}_{t} \in \mathbb{R}^{n \times h} Ht∈Rn×h (正向隐藏状态维度为 h h h),反向隐藏状态为 H ← t ∈ R n × h \overleftarrow{\boldsymbol{H}}_{t} \in \mathbb{R}^{n \times h} Ht∈Rn×h (反向隐藏状态维度为 h h h)。我们可以分别计算正向隐藏状态和反向隐藏状态:
H → t = ϕ ( X t W x h ( f ) + H → t − 1 W h h ( f ) + b h ( f ) ) H ← t = ϕ ( X t W x h ( b ) + H ← t + 1 W h h ( b ) + b h ( b ) ) \begin{aligned} &\overrightarrow{\boldsymbol{H}}_{t}=\phi\left(\boldsymbol{X}_{t} \boldsymbol{W}_{x h}^{(f)}+\overrightarrow{\boldsymbol{H}}_{t-1} \boldsymbol{W}_{h h}^{(f)}+\boldsymbol{b}_{h}^{(f)}\right)\\ &\overleftarrow{\boldsymbol{H}}_{t}=\phi\left(\boldsymbol{X}_{t} \boldsymbol{W}_{x h}^{(b)}+\overleftarrow{\boldsymbol{H}}_{t+1} \boldsymbol{W}_{h h}^{(b)}+\boldsymbol{b}_{h}^{(b)}\right) \end{aligned} Ht=ϕ(XtWxh(f)+Ht−1Whh(f)+bh(f))Ht=ϕ(XtWxh(b)+Ht+1Whh(b)+bh(b))
其中权重 W x h ( f ) ∈ R d × h , W h h ( f ) ∈ R h × h , W x h ( b ) ∈ R d × h , W h h ( b ) ∈ R h × h \boldsymbol{W}_{x h}^{(f)} \in \mathbb{R}^{d \times h}, \boldsymbol{W}_{h h}^{(f)} \in \mathbb{R}^{h \times h}, \boldsymbol{W}_{x h}^{(b)} \in \mathbb{R}^{d \times h}, \boldsymbol{W}_{h h}^{(b)} \in \mathbb{R}^{h \times h} Wxh(f)∈Rd×h,Whh(f)∈Rh×h,Wxh(b)∈Rd×h,Whh(b)∈Rh×h 和偏差 b h ( f ) ∈ R 1 × h , b h ( b ) ∈ R 1 × h \boldsymbol{b}_{h}^{(f)} \in \mathbb{R}^{1 \times h}, \boldsymbol{b}_{h}^{(b)} \in \mathbb{R}^{1 \times h} bh(f)∈R1×h,bh(b)∈R1×h 均为模型参数, ϕ \phi ϕ 为隐藏层激活函数。
然后我们连结两个方向的隐藏状态
H
→
t
\overrightarrow{\boldsymbol{H}}_{t}
Ht 和
H
←
t
\overleftarrow{\boldsymbol{H}}_{t}
Ht 来得到隐藏状态
H
t
∈
R
n
×
2
h
\boldsymbol{H}_{t} \in \mathbb{R}^{n \times 2 h}
Ht∈Rn×2h,并将其输入到输出层。输出层计算输出
O
t
∈
R
n
×
q
\boldsymbol{O}_{t} \in \mathbb{R}^{n \times q}
Ot∈Rn×q(输出维度为
q
q
q):
O
t
=
H
t
W
h
q
+
b
q
\boldsymbol{O}_{t}=\boldsymbol{H}_{t} \boldsymbol{W}_{h q}+\boldsymbol{b}_{q}
Ot=HtWhq+bq
其中权重
W
h
q
∈
R
2
h
×
q
\boldsymbol{W}_{h q} \in \mathbb{R}^{2 h \times q}
Whq∈R2h×q 和偏差
b
q
∈
R
1
×
q
\boldsymbol{b}_{q} \in \mathbb{R}^{1 \times q}
bq∈R1×q 为输出层的模型参数。不同方向上的隐藏单元维度也可以不同。
TextCNN 模型
TextCNN 模型主要使用了一维卷积层和时序最大池化层。假设输入的文本序列由 n n n 个词组成,每个词用 d d d 维的词向量表示。那么输入样本的宽为 n n n,输入通道数为 d d d。TextCNN 的计算主要分为以下几步。
- 定义多个一维卷积核,并使用这些卷积核对输入分别做卷积计算。宽度不同的卷积核可能会捕捉到不同个数的相邻词的相关性。
- 对输出的所有通道分别做时序最大池化,再将这些通道的池化输出值连结为向量。
- 通过全连接层将连结后的向量变换为有关各类别的输出。这一步可以使用丢弃层应对过拟合。
下图用一个例子解释了 TextCNN 的设计。这里的输入是一个有 11 个词的句子,每个词用 6 维词向量表示。因此输入序列的宽为 11,输入通道数为 6。给定 2 个一维卷积核,核宽分别为 2 和 4,输出通道数分别设为 4 和 5。因此,一维卷积计算后,4 个输出通道的宽为 11−2+1=10,而其他 5 个通道的宽为 11−4+1=8。尽管每个通道的宽不同,我们依然可以对各个通道做时序最大池化,并将 9 个通道的池化输出连结成一个 9 维向量。最终,使用全连接将 9 维向量变换为 2 维输出,即正面情感和负面情感的预测。