本文主要是基于Yoon Kim的Convolutional Neural Networks for Sentence Classification,用中文重新梳理一遍。
模型
这篇文章使用的模型如下图所示。
第一层网络是词嵌入层,用来将文本转换成低维度的向量;第二层是卷积层,使用多个卷积核;第三层是max-pool最大池化层,产出一个长的feature向量,添加dropout;最后是softmax层,进行分类。
网络构建-源码解读
init函数
参数解读为:
sequence_length – 句子的长度,可以取所有句子的最长长度,其余不足长度的打pad。
num_classes – 分类类别数量
vocab_size – 词典的大小,embedding层的向量维度为 [vocabulary_size, embedding_size].
embedding_size – 每个词的维度
filter_sizes – 卷积核的尺寸,如[3,4,5], 如大小为3的卷积核的维度为3*embedding_size,对于每个卷积核,可以有num_filters个
num_filters – 每个size的卷积核的数量
定义输入占位符
首先定义输入数据
tf.placeholder:创建一个占位符,这样我们在训练网络或者测试的时候可以给网络喂数据。[None, sequence_length]是输入的数据维度,None表示输入的数据量不确定,可以为任意值。一般为一批数据的大小。
dropout_keep_prob为dropout层选择一个神经元的概率。在使用网络预测时,禁掉这个参数,直接赋值为1.
词嵌入层
网络定义的第一层为词嵌入层,用来将词映射成低纬度的向量标示。
tf.device("/cpu:0") :操作在CPU上。一般情况下,tensorflow会尝试在GPU上执行计算,如果GPU有的话。但是目前词嵌入还没有GPU支持的版本,如果设定为GPU会报错。
tf.name_scope :创建一个叫“embedding”的命名空间,他下面的所有操作都在这个命名空间下,在tensorBoar读网络时能更有层次感。
卷积层
现在开始构建卷积层+最大池化层。这里使用不同尺寸的卷积核。最终将不同尺度的feature merge成一个大的向量。
W是卷积核的矩阵,h是经过非线性校正之后的卷积计算结果。 VALID padding意思是我们使用窄卷积,不对边界padding,产出 [1, sequence_length - filter_size + 1, 1, 1]. 最大池化的时候使用一个特定的核可以只产出一维特征,最终产出[batch_size, 1, 1, num_filters],最终将所有卷积的结果组合成一个大的向量,[batch_size, num_filters_total],tf.reshape=-1,进行尺度方向扭转。
Dropout层
Dropout层在一定的概率下随机的选择某些神经元“失活”,但是权重参数等保存。一般训练时设为0.5,预测时设为1.
Scores and Predictions
使用dropout之后,max-pool计算完的特征,我们可以通过矩阵计算并选择最大值产出预测结果。同时,我们可以使用softmax将原始结果进行归一化,但是这并不会改变最终的预测。
Loss and Accuracy
使用已经计算的score可以得到损失值。loss是对网络损失的衡量,我们的目标是最小化它。在分类中常用交叉损失。
对于准确率,我们也定义以个表达式,它是跟踪训练和测试的有效衡量标准。
可视化
下图是整个网的络结构。
这里,我们介绍了网络结构及每层结构的输入输出以及执行的计算,下一篇文章我们会介绍训练过程。
Implementing a CNN for Text Classification in TensorFlow
Convolutional Neural Networks for Sentence Classification
领取专属 10元无门槛券
私享最新 技术干货