一.概述
RCNN不同于TextCNN和charCNN,论文Recurrent Convolutional Neural Networks for TextClassification中的RCNN是一个RCNN(rnn-cnn)结构,论文地址:Recurrent Convolutional Neural Networks for TextClassification
说到RCNN,网上一搜,可以发现,RCNN用在图像领域的目标检测这个任务上,用于捕获重要目标,不过此RCNN非彼RCNN。虽然缩写一样,文本分类中的RCNN可不是一回事,文本分类中的R可是代表RNN来着。
传统文本分类任务一般分为三个阶段,语料处理特征构建、特征选择、分类器等。深度学习方法主要是模糊了特征构建和特征选择,使用神经网络来构建和提取,而不是手工提取构建等。
RCNN代码实现github地址:https://github.com/yongzhuo/Keras-TextClassification/tree/master/keras_textclassification
1.1 特征构建
论文中提到,传统方法常常使用简单的词频(tf)、tf-idf、bow(词袋)、MI、pLSI、LDA、n-gram等,或者是词性(tag)、名词短语(kerals)、树核(tree keral)等。但是往往忽略了词序和上下文信息。而论文中的正向LSTM加上嵌入embedding构建特征,可以更好的捕获文本语义信息。其实这个以及很像双向循环神经网络BI-RNN了。
1.2 特征选择
传统常用的特征选择,其实也是数据预处理的一部分,包括去除停用词(词频过高或者过低)、正则化(L1、L2)、互信息和信息增益、线性回归和树帅选等。神经网络的还有droupout、resnet、CNN卷积等。
1.3 分类器
传统常用的分类器有线性模型LR、朴素贝叶斯NB、最近邻KNN、支持向量机SVM、树结构(xgboosting、Adaboosting、RF、Lgb)。神经网络则不同,可以直接看成神经网络构建模型选择出特征,然后直接softmax分类就好。
二.RCNN网络
2.1 RCNN网络图
2.2 RCNN模型说明
RCNN网络主要有由RNN、CNN两个组成,RNN也不是传统意义上的丢递归神经网络,它是由正向RNN、词嵌入向量、反向RNN等特征拼接起来的[lstm_forwords, embedding, lstm_backwards],获取上下文等信息。
论文中的CNN也不是真正意义上的CNN,就是一个max-pooling池化,注意看图,那是列卷积,(但实验的实际效果,还是行卷积效果比较好),提取关键信息,实际上没有conv卷积的。
模型参数: 神经元数量=100,词向量维度=50,文本最大长度=50
三.代码实现
3.1 代码实现应该不难,就是正向LSTM、反向LSTM、Embedding、max-poling,比较简单的一个模型,不过由于有了LSTM,训练那是意料之中的慢,小样本(几千、几万、几十万语料)还可以,如果百万、千万、上亿,一台机子,不做分布式,调参或者修改语料后再重新训练,那就有意思了。
3.2 github代码地址:https://github.com/yongzhuo/Keras-TextClassification/tree/master/keras_textclassification
3.3 主要模型代码
def create_model(self, hyper_parameters):
"""
构建神经网络, col, 论文中maxpooling使用的是列池化
:param hyper_parameters:json, hyper parameters of network
:return: tensor, moedl
"""
super().create_model(hyper_parameters)
embedding_output = self.word_embedding.output
# rnn layers
if self.rnn_units=="LSTM":
layer_cell = LSTM
else:
layer_cell = GRU
# 反向
x_backwords = layer_cell(units=self.rnn_units,
return_sequences=True,
kernel_regularizer=regularizers.l2(0.32 * 0.1),
recurrent_regularizer=regularizers.l2(0.32),
go_backwards = True)(embedding_output)
x_backwords_reverse = Lambda(lambda x: K.reverse(x, axes=1))(x_backwords)
# 前向
x_fordwords = layer_cell(units=self.rnn_units,
return_sequences=True,
kernel_regularizer=regularizers.l2(0.32 * 0.1),
recurrent_regularizer=regularizers.l2(0.32),
go_backwards = False)(embedding_output)
# 拼接
x_feb = Concatenate(axis=2)([x_fordwords, embedding_output, x_backwords_reverse])
####列池化##################################################
x_feb = Dropout(self.dropout)(x_feb)
dim_2 = K.int_shape(x_feb)[2]
x_feb_reshape = Reshape((dim_2, self.len_max))(x_feb)
x = MaxPooling1D(padding = 'SAME',)(x_feb_reshape)
x = Dropout(self.dropout)(x)
x = Flatten()(x)
#########################################################################
output = Dense(units=self.label, activation=self.activate_classify)(x)
self.model = Model(inputs=self.word_embedding.input, outputs=output)
self.model.summary(120)
3.4 实现效果
还可以,明显感觉比random-TextCNN效果要好些。
希望对你有所帮助!