BILSTM-Conv2D 文本分类模型
- 论文链接:https://arxiv.org/pdf/1611.06639.pdf
- GitHub链接:https://github.com/scientist272/BILSTM-CONV2D-TEXT-CLASSIFIER
在文本序列时,BILSTM不仅可以采集过去的信息,也可以采集未来的信息,当输入一个序列,如“ABCD”时,BILSTM会将该序列正向输入得到一个输出向量,再将该序列反向输入得到一个输出向量,这两个向量可经过拼接,加和,点乘等处理后交给下一层处理。
1D的卷积神经网络用在文本分类模型中只会采集文本向量这个维度的信息,2D的卷积网络不仅可以采集文本向量这个温度,还可以采集时间戳这个维度,这个模型的思想是将BILSTM处理后得到的向量当作一个图片,再交给Conv2D处理,池化,最后输出分类结果。
由于LSTM输出的向量是一个(samples,timestamp,features)维度的向量,在LSTM和Conv2D中间需要添加一个reshape层,将其reshape成一个四维的矩阵(卷积的图片标准输入维度),才能交给Conv2D处理。
self.model = Sequential()
self.model.add(Embedding(self.vocab_size+1,self.embedding_dim,input_length=self.max_len,weights=[self.embeddings_matrix], trainable=False))
self.model.add(Dropout(0.5))
self.model.add(Bidirectional(LSTM(self.rnn_units,return_sequences=True),merge_mode='sum'))
self.model.add(Dropout(0.2))
self.model.add(Reshape((-1,self.rnn_units,1)))
self.model.add(Conv2D(64,kernel_size=(3,3),activation='relu'))
self.model.add(MaxPool2D(pool_size=(2,2)))
self.model.add(Dropout(0.4))
self.model.add(Flatten())
self.model.add(Dense(self.category_num+1,activation='softmax'))
self.model.compile(loss='sparse_categorical_crossentropy', optimizer='adadelta',metrics=['accuracy'])
self.model.summary()
这里的Embedding层用于word2vec(单词转换为向量),我用了事先训练好的Glove,词汇库有60亿,单词维度为100。这样不用训练embedding,训练时间缩短了很多,同时这些训练好的向量准确度也更高。
数据我用的一个BBC的新闻文件,有2000多条新闻,5个新闻种类。训练了10个epochs后,测试集准确率达到了98.2%。相同的数据用Conv1D的模型测试,准确率只能达到97.5%左右。
最后,贴上模型的示意图
BILSTM正向和反向输出向量的结合方式为相加。
详细代码见GitHub,模型已经训练好,可以在json配置文件中自己定制参数重新训练,也可以将要分类的文本写在json文件中测试模型分类结果。