资源技术动态深度学习文本分类实战报告:CNN, RNN & HAN

深度学习文本分类实战报告:CNN, RNN & HAN

2019-10-16 | |  128 |   0

原标题:深度学习文本分类实战报告:CNN, RNN & HAN      来源:AI研习社      

链接:https://www.yanxishe.com/TextTranslation/1127


简介

大家好!! 我最近作为 NLP 研究员(Intern? ) 加入了 Jatana.ai a并被要求利用深度学习的模型在文本分类方面做一些工作。


在这篇文章中,我将分享我在不同的神经网络架构上做实验时的一些经验和学习心得。


我将覆盖下面这三种主要算法:

  1. 卷积神经网络(CNN)

  2. 循环神经网络(RNN)

  3. 分层注意网络(HAN)

这次的文本分类任务将在丹麦语、意大利语、德语、英语和土耳其语的数据集上做测试。

好啦,那我们开始吧!✅


关于自然语言处理(NLP)


自然语言处理和有监督机器学习(ML)在不同的商业问题中被使用到最频繁的任务之一就是“文本分类”,自从第一个含有文本和其标签的标注数据集被用于分类器的训练之后,这就成为了有监督机器学习领域的一个任务模板。


文本分类的目标是:自动将文本文件划分成预定义好的一种或多种不同的类别。


一些文本分类的案例如下:

  • 理解社会媒体中用户的情感 (? ? ?) 

  • 检测垃圾邮件

  • 用户问询的自动标签

  • 把新文章?分类成预定义好的话题


文本分类无论在学术界 ? 还是工业界都是一个活跃的研究领域,在这篇文章中,我将试着展示并对比一些研究成果的表现,所有的实现是基于 Keras 框架的。


所有源代码和实验结果都可以在jatana_research的知识库中找到。

5bc9f3bd2b9e3.png

一个端到端的文本分类架构由以下几个部分组成:

  1. 训练文本:即输入文本,监督学习模型可以通过它来学习和预测所需的类。

  2. 特征向量:特征向量是包含描述输入数据特征信息的向量。

  3. 标签:我们模型将要预测的预定义的类别/类。

  4. 算法:它是我们的模型能够处理文本分类的算法(在我们的例子中:CNN,RNN,HAN)

  5. 预测模型:在历史数据集上训练的模型,可以实现标签的预测。




数据分析:


我们使用3种类型的数据集,其中包含多种类别,如下表所示:

1539248366265671.png


基于卷积神经网络的文本分类(CNN):

CNN是一类深度前馈人工神经网络(节点之间的连接不构成循环)并使用多层感知器的变体,其设计需要极少的预处理。 这些都受到动物视觉皮层的启发。

我参考了Yoon Kim论文和Denny Britz撰写的这篇博客


CNN通常用于计算机视觉,但是最近它们已经应用于各种NLP任务,并且结果很有希望。


让我们通过一个图表简要地看一下将CNN应用与文本数据会发生什么。当一个特殊的模式被检测时,每个卷积的结果都将触发。通过改变核的大小并连接它们的输出,可以检测多个大小(2、3或5个相邻的单词)的模式。模式可以是表达式(单词n元组)像“ I hate  ”,“ very good”,因此CNNs可以在句子中识别他们,而不管他们的位置。

5bc9f89a56603.png

图片参考:http://www.wildml.com/2015/11/understanding-convolutional-neural-networks-for-nlp/


在本节中,我使用了一个简化的CNN来构建分类器。首先,使用Beautiful Soup来删除一些HTML标签和一些不需要的字符。

5bc98399b871e.png

在此,我使用了Google Glove预训练的100维词向量 Google Glove 6B vector 100d。它的官方文档如下:


  ''' GloVe 是一种用于获取单词向量表示的无监督学习算法。它对来自语料库的聚合的全局词-词共现统计量进行训练,并且其结果展现了单词向量空间非常有趣的线性子结构。'''


对于未知的单词,下面的代码会随机初始化它的向量。下面是一个非常简单的卷积结构,总共使用了128个大小为5的卷积核,窗口大小为5与35的最大池化,遵循该博客中的示例。

5bc9aa8a324c4.png

这是CNN模型的结构。

1539248365712916.png


使用递归神经网络(RNN)进行文本分类:


递归神经网络(RNN)是一种节点定向连接成有向图的人工神经网络,这种特性允许它展示一段时间序列内的动态时序行为。


使用来自外部嵌入的知识可以提高RNN的精度,因为它整合了这个单词的相关新信息(词汇和语义),而这些信息是基于大规模数据语料库训练和提炼出来的。我们使用的预训练嵌入是GloVe。


RNN可能看起来很可怕?。虽然它们很难理解,但是却非常有趣。他们封装了一个非常漂亮的设计,克服了传统神经网络在处理序列数据时出现的缺点:文本,时序,视频,DNA序列等。


RNN是一系列的神经网络节点,它们像链条一样彼此连接。每个节点都将信息传递给下一节点。如果你想深入了解其内部机制,我强烈推荐Colah的博客。

5bcac811cb52e.png

图片参考自:http://colah.github.io/posts/2015-08-Understanding-LSTMs/


使用Beautiful Soup也可以在这里进行相同的预处理。我们将处理一种序列类型的文本数据。单词的顺序对于语义的理解非常重要,RNNs有希望能够处理这个问题并解决长期依赖问题。


要在文本数据上使用Keras,我们首先要对其进行预处理,为此,我们可以使用Keras的Tokenizer类。此对象将num_words作为基于字频率进行标记化后保留的最大字数的参数。

MAX_NB_WORDS = 20000

tokenizer = Tokenizer (num_words=MAX_NB_WORDS) tokenizer.fit_on_texts(texts)


一旦将标记器放置于数据上时,我们就可以使用它将文本字符串转换为数字序列。这些数字代表字典中每个单词的位置(将其视为映射)。

● 在本节中,我将尝试通过使用递归神经网络和基于注意力机制的LSTM编码器来解决该问题。

● 通过使用LSTM编码器,我们打算在运行前馈网络进行分类前,对递归神经网络的最后一个输出文本的全部信息进行编码。

● 这与神经翻译机和序列到序列的学习模型非常类似。以下是段落和文档的分层神经自动编码器的图。

5bcac88e2fae3.png

图片参考自:https://arxiv.org/pdf/1506.01057v2.pdf

● 我在Keras中使用LSTM层来实现这一点。不同于正向LSTM,在这里我使用了双向LSTM,并且连接了其各自的最后一层输出。

● Keras提供了一个非常好的双向包装器,这将使这种编码工作毫不费力。您可以在此处查看示例代码。


sequence_input = Input(shape=(MAX_SEQUENCE_LENGTH,), dtype='int32')

embedded_sequences = embedding_layer(sequence_input)

l_lstm = Bidirectional(LSTM(100))(embedded_sequences)

preds = Dense(len(macronum), activation='softmax')(l_lstm)

model = Model(sequence_input, preds)

model.compile(loss='categorical_crossentropy',optimizer='rmsprop',  metrics=['acc'])


以下是RNN模型的结构

5bcc8eb5bb1de.png

使用分层注意网络(HAN)的文本分类:


我参考了《用于文档分类的分层注意网络》这篇研究论文,它可以成为使用HAN进行文档分类的一个不错的指南。使用Beautiful Soup也可以进行相同的预处理,在这里我们使用的预训练嵌入是GloVe。


● 这里我正在构建一个分层LSTM网络。我必须按上面两节所述构建输入数据为3D格式而非2D。

● 因此输入张量将是[每批数据的评论数,句子数,每句中的单词数]。


tokenizer = Tokenizer(nb_words=MAX_NB_WORDS)

tokenizer.fit_on_texts(texts)

data = np.zeros((len(texts), MAX_SENTS, MAX_SENT_LENGTH), dtype='int32')

for i, sentences in enumerate(reviews):

    for j, sent in enumerate(sentences):

        if j< MAX_SENTS:

            wordTokens = text_to_word_sequence(sent)

            k=0

            for _, word in enumerate(wordTokens):

                if(k<MAX_SENT_LENGTH and tokenizer.word_index[word]<MAX_NB_WORDS):

                    data[i,j,k] = tokenizer.word_index[word]

                    k=k+1


在此之后,我们可以使用Keras魔术函数TimeDistributed构建如下分层LSTM网络输入层。我们也可以参考这篇文章。


embedding_layer=Embedding(len(word_index)+1,EMBEDDING_DIM,weights=[embedding_matrix],

input_length=MAX_SENT_LENGTH,trainable=True)

sentence_input = Input(shape=(MAX_SENT_LENGTH,), dtype='int32')

embedded_sequences = embedding_layer(sentence_input)

l_lstm = Bidirectional(LSTM(100))(embedded_sequences)

sentEncoder = Model(sentence_input, l_lstm)


review_input = Input(shape=(MAX_SENTS,MAX_SENT_LENGTH), dtype='int32')

review_encoder = TimeDistributed(sentEncoder)(review_input)

l_lstm_sent = Bidirectional(LSTM(100))(review_encoder)

preds = Dense(len(macronum), activation='softmax')(l_lstm_sent)

model = Model(review_input, preds)


如下是HAN模型的架构。

5bcc8fc1caeed.png


结果

1571238510775927.png

?为准确率, ?为损失

1571238546952241.png

观察发现:

  • 基于上述图表,CNN取得了良好的验证准确率以及高度的一致性,RNN和HAN也实现了高准确性,但在所有数据集中它们并不具有一致性。

  • 发现RNN对于生产就绪场景的实现是最差的一种结构。

  • CNN模型在训练时间方面优于其他两个模型(RNN和HAN),但是如果我们拥有较大的数据集,HAN比CNN和RNN表现更好。

  • 对于拥有很多训练样本的数据集1和数据集2,HAN达到了最佳验证准确度,而当训练样本非常小时,HAN没有表现出那么好(数据集3)

  • 当训练样本较少时(数据集3),CNN达到最佳验证准确度。

1571238633209188.png

性能改进:

为了达到最好的性能?,我们可以:

1、微调超参数: 超参数是在训练前设置的变量,它决定了网络的结构以及如何训练网络。(例如:学习率,批量大小,迭代数)。实现微调可以通过:手动搜索,网格搜索,随机搜索…  

2、提高文本预处理: 可以根据数据集的需要,更好地对输入数据进行预处理  ,例如删除一些特殊符号,数字,停用词等...

3、使用Dropout层:Dropout是一种正则化方法,可以避免过拟合(提高验证精度),从而增加泛化能力。


基础配置:

以上实验均在Nvidia Tesla K80 GPU的8核  vCPU上进行。此外,所有实验均在Rahul Kumar 的指导下进行 ?  同时,我还要感谢Jatana.ai为我提供了一个非常好的基础设施和全程支持?

THE END

免责声明:本文来自互联网新闻客户端自媒体,不代表本网的观点和立场。

合作及投稿邮箱:E-mail:editor@tusaishared.com

上一篇:推荐系统的评价标准

下一篇:最全面的百度NLP自然语言处理技术解析

用户评价
全部评价

热门资源

  • 应用笔画宽度变换...

    应用背景:是盲人辅助系统,城市环境中的机器导航...

  • GAN之根据文本描述...

    一些比较好玩的任务也就应运而生,比如图像修复、...

  • 端到端语音识别时...

    从上世纪 50 年代诞生到 2012 年引入 DNN 后识别效...

  • 人体姿态估计的过...

    人体姿态估计是计算机视觉中一个很基础的问题。从...

  • 谷歌发布TyDi QA语...

    为了鼓励对多语言问答技术的研究,谷歌发布了 TyDi...