第8章:神经网络

在本章中,我们构建一个基于神经网络的分类器,以解决第6章中的新闻分类任务。编写程序时,请活用PyTorch, TensorFlow, Chainer等深度学习库。

70. 基于词向量之和来生成特征

考虑将第50问中构建的训练集、验证集与测试集表示为矩阵或向量的形式。具体地,对于每一个数据集,分别构建:

  • 特征矩阵\(X\),由所有实例的特征向量\(\boldsymbol{x}_i\)拼接而成;
  • 标签向量\(Y\),由所有实例所对应的真实类别标注\(y_i\)排列而成。

即:

\[X = \begin{pmatrix} \boldsymbol{x}_1 \\ \boldsymbol{x}_2 \\ \dots \\ \boldsymbol{x}_n \\ \end{pmatrix} \in \mathbb{R}^{n \times d}, Y = \begin{pmatrix} y_1 \\ y_2 \\ \dots \\ y_n \\ \end{pmatrix} \in \mathbb{N}^{n}\]

上式中,\(n\)代表数据集中的实例总数。 \(\boldsymbol{x}_i \in \mathbb{R}^d\) 及 \(y_i \in \mathbb{N}\) 分别代表第\(i \in {1,...,n}\)个实例所对应的特征向量及真实类别标签。 设 \(\mathbb{N}_4\) 代表小于4的自然数(包括0),本次任务中,我们进行{“Business”, “Science”, “Entertainment”, “Health”}的四分类,则任一实例的真实类别标签\(y_i\)均可用\(y_i \in \mathbb{N}_4\)表示。下文以\(L\)代表类别的种数(这里\(L=4\))。

第\(i\)个实例的特征向量\(\boldsymbol{x}_i\)可以通过下式计算:

\[\boldsymbol{x}_i = \frac{1}{T_i} \sum_{t=1}^{T_i} \mathrm{emb}(w_{i,t}),\]

其中第\(i\)个实例由单词序列\((w_{i,1},...,w_{i,T_i})\)构成,共\(T_i\)个词,对应该实例的标题;每个词\(w\)对应的词向量为\(emb(w) \in \mathbb{R}^{d}\)(维度为\(d\))。 我们直接使用60问中所提供的预训练词向量,因此维度为300(即\(d=300\))。

第\(i\)个实例的真实类别标签\(y_i\)通过下式定义(保证类别名与其标签一一对应即可):

\[y_i = \begin{cases} 0 & (\mbox{if article }\boldsymbol{x}_i\mbox{ belongs to Business category}) \\ 1 & (\mbox{if article }\boldsymbol{x}_i\mbox{ belongs to Science category}) \\ 2 & (\mbox{if article }\boldsymbol{x}_i\mbox{ belongs to Entertainment category}) \\ 3 & (\mbox{if article }\boldsymbol{x}_i\mbox{ belongs to Health category}) \\ \end{cases}\]

基于上述要求, 创建以下矩阵和向量,并保存至文件:

  • 训练集的特征矩阵: \(X_{\rm train} \in \mathbb{R}^{N_t \times d}\)
  • 训练集的标签向量: \(Y_{\rm train} \in \mathbb{N}^{N_t}\)
  • 验证集的特征矩阵: \(X_{\rm valid} \in \mathbb{R}^{N_v \times d}\)
  • 验证集的标签向量: \(Y_{\rm valid} \in \mathbb{N}^{N_v}\)
  • 测试集的特征矩阵: \(X_{\rm test} \in \mathbb{R}^{N_e \times d}\)
  • 测试集的标签向量: \(Y_{\rm test} \in \mathbb{N}^{N_e}\)

其中\(N_t, N_v, N_e\)分别代表训练集,验证集,测试集中的实例总数。

71. 基于单层神经网络的预测

读取第70问中所保存的矩阵与向量,在训练集上进行如下计算:

\[\hat{\boldsymbol{y}}_1 = {\rm softmax}(\boldsymbol{x}_1 W), \\ \hat{Y} = {\rm softmax}(X_{[1:4]} W)\]

其中,\({\rm softmax}\)代表softmax函数,\(X_{[1:4]} \in \mathbb{R}^{4 \times d}\)代表由\(\boldsymbol{x}_1, \boldsymbol{x}_2, \boldsymbol{x}_3, \boldsymbol{x}_4\)纵向连接而成的矩阵,即:

\[X_{[1:4]} = \begin{pmatrix} \boldsymbol{x}_1 \\ \boldsymbol{x}_2 \\ \boldsymbol{x}_3 \\ \boldsymbol{x}_4 \\ \end{pmatrix}\]

\(W \in \mathbb{R}^{d \times L}\)是单层神经网络的权重矩阵。本问的计算中,暂时直接使用随机初始化的值(第73问中将通过机器学习更新此权重矩阵)。 注意\(\hat{\boldsymbol{y}}_1 \in \mathbb{R}^L\)代表使用未经学习的权重矩阵\(W\)计算后,实例\(x_1\)所属类别的概率分布。 类似地,\(\hat{Y} \in \mathbb{R}^{n \times L}\)代表训练集中的实例\(x_1, x_2, x_3, x_4\)所属类别的概率分布。

72. 计算损失(loss)及梯度(gradients)

在训练集中的实例\(x_1\)与实例集合\(x_1, x_2, x_3, x_4\)上分别计算交叉熵损失(cross-entropy loss)及对矩阵\(W\)的梯度。对于单个实例\(x_1\),使用下式计算损失:

\[l_i = - \log [\mbox{样本}x_i\mbox{被分类为}y_i\mbox{的概率}]\]

对于一个实例集合,求集合中各实例损失的平均值,作为该集合的交叉熵损失。

73. 基于随机梯度下降法(SGD)的训练

使用随机梯度下降法(Stochastic Gradient Descent)更新矩阵\(W\)。 选用适当的基准终止训练(如“100个epochs后终止”)。

74. 计算正确率

使用第73问中训练所得的矩阵对训练集与验证集进行分类,并分别计算正确率。

75. 损失与正确率的可视化

修改第73问中的代码,使得每个epoch完成训练后,以折线图的方式记录模型当前:

  • 在训练集上的损失;
  • 在训练集上的正确率;
  • 在验证集上的损失;
  • 在验证集上的正确率。

通过该组折线图监控训练的进程。

76. 检查点(Checkpoints)

修改第75问中的代码,使得每个epoch训练结束后,保存检查点(模型参数的值,优化算法的状态等)至文件。

77. Mini-batches

修改第76问中的代码,使得以每\(B\)个实例为单位计算损失和梯度,并更新权重矩阵\(W\)(mini-batch化)。改变\(B\)的值为\(1, 2, 4, 8, \dots\),比较不同情况下训练一个epoch所耗费的时间。

78. GPU训练

修改77问中的代码,使得训练能够在GPU上进行。

79. 多层神经网络

修改第78问中的代码,通过引入偏置项(bias)、增加网络层数等操作,改变神经网络的架构,以构建一个高性能的分类器。