一文了解TextCNN文本分类

在之前的文章中,我介绍了撩一发深度文本分类之RNN via Attention,解决有毒评论文本分类问题。然而,在工业界,RNN、LSTM、GRU等循环神经网络不能并行计算,尽管研究者提出了一些其他的模型,如SRU等。CNN尽管效果在某些时候会稍逊RNN以及RNN的变体,但是CNN在速度方面却有着无可比拟的效果,且由于它的可并行性广被工业界喜爱。

在本文中,我将介绍 「TextCNN」 算法,帮助有需要的朋友入门深度学习自然语言处理。关于TextCNN算法,有两篇不错的paper可供参考:

(1) Convolutional Neural Networks for Sentence Classification

(2) A Sensitivity Analysis of (and Practitioners’ Guide to) Convolutional Neural Networks for Sentence Classification

TextCNN简介

卷积神经网络(CNN),做过图像的朋友都知道,比如图像分类、目标检测、分割等,很多都是利用CNN提取图像的深层次图像表征,并且取得了state-of-the-art performance,在图像领域大放异彩。那么在文本领域是否也可以提取文本的特征呢?2014年Yoon Kim这位大佬揭晓了答案,完全可以,而且也可以取得不错的效果。在文本中,并不是所有的文本都是全部依赖,正如我们在之前一篇文章中利用TFIDF+LR 来解决这个问题一样,我们利用ngram信息,捕捉文本的局部相关性特征。CNN的原理也是如此,我们可以通过卷积核,来补捉文本的局部相关性特征。同时,我们也可以使用多个不同的卷积核,来捕捉多个ngram信息。

TextCNN原理

下面我以一张经典的图来简单介绍了以下TextCNN模型。在2014年提出,Yoon Kim使用了卷积 + 最大池化这两个在图像领域非常成功的好基友组合。我们先看一下他的结构。如下图所示,示意图中第一层输入为7*5的词向量矩阵,其中词向量维度为5,句子长度为7,然后第二层使用了3组宽度分别为2、3、4的卷积核,图中每种宽度的卷积核使用了两个。其中每个卷积核在整个句子长度上滑动,得到n个激活值,图中卷积核滑动的过程中没有使用padding,因此宽度为4的卷积核在长度为7的句子上滑动得到4个特征值。然后出场的就是卷积的好基友全局池化了,每一个卷积核输出的特征值列向量通过在整个句子长度上取最大值得到了6个特征值组成的feature map来供后级分类器作为分类的依据。

TextCNN实现

在本文中,我将借助有毒评论分类比赛数据https://www.kaggle.com/c/jigsaw-toxic-comment-classification-challenge,来实现下TextCNN,帮助有需要的朋友入门深度自然语言处理。

上面简单介绍了下TextCNN的结构,我将借助有毒评论分类比赛数据https://www.kaggle.com/c/jigsaw-toxic-comment-classification-challenge,来实现下TextCNN。有毒评论问题我们在上几篇文章中已经分析了文本的一些特征,这里我就不下详细描述了,大家有兴趣的话,可以看我之前的几篇文章。

本文的主要动机是为了解决RNN的不可并行性,利用CNN的高速并行性。因此,在performance上可以会有些差。话不多说,下面就是我们TextCNN的架构,采用keras简单实现了下,和原始论文的模型有些不一样。

def TextCNN(maxlen):
    inp = Input(shape=(maxlen,))
    x = Embedding(max_features, embed_size, weights=[embedding_matrix])(inp)


    conv1 = Conv1D(filters=64, kernel_size=1, padding=same)(x)
    conv1 = MaxPool1D(pool_size=32)(conv1)




    conv2 = Conv1D(filters=64, kernel_size=2, padding=same)(x)
    conv2 = MaxPool1D(pool_size=32)(conv2)


    conv3 = Conv1D(filters=64, kernel_size=3, padding=same)(x)
    conv3 = MaxPool1D(pool_size=32)(conv3)


    conv4 = Conv1D(filters=64, kernel_size=4, padding=same)(x)
    conv4 = MaxPool1D(pool_size=32)(conv4)


    cnn = concatenate([conv1, conv2, conv3, conv4], axis=-1)
    flat = Flatten()(cnn)


    x = Dense(50, activation=relu)(flat)
    x = Dropout(0.1)(x)
    x = Dense(6, activation=sigmoid)(x)
    model = Model(inputs=inp, outputs=x)
    model.compile(loss=binary_crossentropy, optimizer=adam, metrics=[accuracy])
    model.summary()
    return model
model=TextCNN(maxlen)
model.fit(X_t, y, batch_size=32, epochs=2, validation_split=0.1)
submission = pd.DataFrame.from_dict({id: test[id]})
y_test = model.predict([X_te], batch_size=1024, verbose=1)
submission[list_classes] = pd.DataFrame(y_test)

上面就是一个非常粗糙的TextCNN模型,我提交了下,效果有点不太理想。如果想要提升下模型效果,可以考虑增加多层卷积,或者残差卷积等等。这仅仅作为入门的一个baseline。如果你想要运行完整代码可以参考我的github: https://github.com/hecongqing/TextClassification

推荐阅读

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值