文本分类描述了一类常见的问题,例如预测推文和电影评论的情感,以及将电子邮件分类为垃圾邮件或非垃圾邮件。
深度学习方法在文本分类方面表现出色,在一系列标准学术基准问题上取得了最先进的结果。
在这篇文章中,您将了解在开发用于文本分类的深度学习模型时需要考虑的一些最佳实践。
阅读本文后,你将了解:
- 在开始处理文本分类问题时,需要考虑深度学习方法的通用组合。
- 第一个要尝试的架构,以及关于如何配置超参数的具体建议。
- 更深的网络可能代表着该领域在灵活性和能力方面的未来。
通过我的新书《深度学习自然语言处理》启动您的项目,其中包括逐步教程和所有示例的Python源代码文件。
让我们开始吧。

深度学习在文档分类中的最佳实践
图片由storebukkebruse拍摄,部分权利保留。
概述
本教程分为5个部分,它们是:
- 词嵌入 + CNN = 文本分类
- 使用单层CNN架构
- 调整CNN超参数
- 考虑字符级CNN
- 考虑更深的CNN用于分类
需要深度学习处理文本数据的帮助吗?
立即参加我的免费7天电子邮件速成课程(附代码)。
点击注册,同时获得该课程的免费PDF电子书版本。
1. 词嵌入 + CNN = 文本分类
文本分类的操作方式涉及使用词嵌入来表示单词,以及使用卷积神经网络(CNN)来学习如何在分类问题上区分文档。
Yoav Goldberg 在其关于深度学习用于自然语言处理的入门指南中评论道,神经网络通常比经典的线性分类器提供更好的性能,特别是与预训练的词嵌入结合使用时。
网络的非线性特性,以及轻松整合预训练词嵌入的能力,通常会带来卓越的分类准确性。
—— 自然语言处理神经网络模型入门,2015。
他还评论说,卷积神经网络在文档分类中很有效,主要是因为它们能够以不依赖于其在输入序列中位置的方式挑选出显著特征(例如,词元或词元序列)。
带有卷积层和池化层的网络对于分类任务很有用,在这种任务中,我们期望找到关于类别成员身份的强烈局部线索,但这些线索可能出现在输入的不同位置。[…] 我们希望学习到某些词序列是主题的良好指示符,而不一定关心它们在文档中的位置。卷积层和池化层允许模型学习找到这些局部指示符,无论它们的位置如何。
—— 自然语言处理神经网络模型入门,2015。
因此,该架构由三个关键部分组成:
- 词嵌入:词语的分布式表示,其中含义相似(基于其用法)的不同词语也具有相似的表示。
- 卷积模型:一种特征提取模型,它学习从使用词嵌入表示的文档中提取显著特征。
- 全连接模型:根据预测输出解释提取的特征。
Yoav Goldberg 在他的书中强调了 CNN 作为特征提取模型的作用
... CNN本质上是一种特征提取架构。它本身不构成一个独立的、有用的网络,而是旨在集成到更大的网络中,并与它协同训练以产生最终结果。CNN层的职责是提取有意义的子结构,这些子结构对于手头的整体预测任务很有用。
—— 第152页,自然语言处理的神经网络方法,2017。
这三个元素的结合体现在可能是组合中最常被引用的例子之一,在下一节中描述。
2. 使用单层CNN架构
您可以利用单层 CNN 在文档分类中取得良好效果,也许可以在不同大小的核上应用不同的滤波器,以便在不同尺度上对词表示进行分组。
Yoon Kim 在他关于使用预训练词向量进行卷积神经网络分类任务的研究中发现,使用预训练的静态词向量效果非常好。他建议,在非常大的文本语料库(例如,基于Google新闻的1000亿个词元训练的免费word2vec 向量)上训练的预训练词嵌入可以为自然语言处理提供良好的通用特征。
尽管对超参数的调整很少,但一个简单的单层卷积CNN表现得非常出色。我们的结果进一步证实了无监督预训练词向量是深度学习在自然语言处理中一个重要组成部分。
—— 用于句子分类的卷积神经网络,2014。
他还发现,对词向量进行进一步的任务特定调整可以使性能略有提高。
Kim描述了将CNN用于自然语言处理的通用方法。句子被映射到嵌入向量,并作为矩阵输入模型。卷积操作通过不同大小的核(例如,每次2或3个词)对输入进行逐词处理。然后使用最大池化层处理生成的特征图,以压缩或汇总提取的特征。
该架构基于 Ronan Collobert 等人在其论文《(几乎)从零开始的自然语言处理》中采用的方法,2011年。在该论文中,他们开发了一个单一的端到端神经网络模型,带有卷积层和池化层,可用于一系列基本自然语言处理问题。
Kim 提供了一个图表,通过不同大小的核以不同颜色(红色和黄色)展示了滤波器的采样过程,这有助于理解。

自然语言处理中CNN滤波器和池化架构的示例。
选自《用于句子分类的卷积神经网络》,2014年。
他有用地报告了他通过网格搜索发现并用于7个文本分类任务的模型配置,总结如下:
- 传递函数:修正线性。
- 核大小:3、4、5。
- 过滤器数量:100
- 丢弃率:0.5
- 权重正则化 (L2): 3
- 批次大小:50
- 更新规则:Adadelta
这些配置可以作为您自己实验的起点。
3. 调整CNN超参数
在针对您的文档分类问题调整卷积神经网络时,有些超参数比其他超参数更重要。
张烨和拜伦·华莱士对配置用于文档分类的单层卷积神经网络所需的超参数进行了敏感性分析。这项研究的动机是他们声称模型对其配置很敏感。
不幸的是,基于CNN的模型(即使是简单的模型)的一个缺点是,它们要求实践者指定要使用的确切模型架构并设置相应的超参数。对于初学者来说,做出这样的决定可能看起来像是一种黑魔法,因为模型中有许多自由参数。
—— 用于句子分类的卷积神经网络的敏感性分析(以及实践者指南),2015。
他们的目标是提供可用于配置新文本分类任务中CNN的通用配置。
他们提供了一个很好的模型架构图示和配置模型的决策点,如下所示。

用于句子分类的卷积神经网络架构
摘自《用于句子分类的卷积神经网络的敏感性分析(以及实践者指南)》,2015年。
该研究得出了一些有用的发现,可以作为配置用于文本分类的浅层CNN模型的起点。
一般发现如下:
- 预训练的word2vec和GloVe嵌入的选择因问题而异,但两者都比使用one-hot编码的词向量表现更好。
- 核大小很重要,应针对每个问题进行调整。
- 特征图的数量也很重要,应该进行调整。
- 1-最大池化通常优于其他类型的池化。
- Dropout对模型性能影响不大。
他们继续提供了更具体的启发式方法,如下:
- 以word2vec或GloVe词嵌入作为起点,并在拟合模型时对其进行调整。
- 在1-10的范围内,对不同核大小进行网格搜索,以找到适合您问题的最佳配置。
- 在相同的搜索中,搜索100-600范围内的过滤器数量,并探索0.0-0.5的dropout率。
- 探索使用tanh、relu和线性激活函数。
关键的警告是,这些发现基于使用单个句子作为输入的二元文本分类问题的经验结果。
我建议阅读全文以获取更多详细信息:
- 用于句子分类的卷积神经网络的敏感性分析(以及实践者指南), 2015.
4. 考虑字符级CNN
可以使用卷积神经网络在字符级别对文本文档进行建模,这些网络能够学习单词、句子、段落等的相关分层结构。
Xiang Zhang 等人使用基于字符的文本表示作为卷积神经网络的输入。这种方法的优势在于,如果CNN能够学习抽象出显著细节,就可以克服清理和准备文本所需的所有耗时工作。
除了之前研究的结论,即ConvNets不需要语言的句法或语义结构知识外,深度ConvNets也不需要单词知识。这种工程上的简化对于能够适用于不同语言的单一系统来说至关重要,因为字符始终是必要的结构,无论是否可能进行分词。只处理字符还有一个优点,那就是可以自然地学习异常字符组合,例如拼写错误和表情符号。
—— 用于文本分类的字符级卷积网络,2015。
该模型读取固定大小字母表中的one-hot编码字符。编码字符以1,024个字符的块或序列读取。随后是6个卷积层和池化层的堆栈,以及网络输出端的3个全连接层,以进行预测。

用于文本分类的字符级卷积神经网络
选自《用于文本分类的字符级卷积网络》,2015年。
该模型取得了一些成功,在文本语料库较大的问题上表现更好。
…分析表明,字符级ConvNet是一种有效的方法。[…]我们的模型在比较中表现如何取决于许多因素,例如数据集大小、文本是否经过整理以及字母表的选择。
—— 用于文本分类的字符级卷积网络,2015。
使用这种方法的扩展版本的结果在下一节中讨论的后续论文中被推向了最先进水平。
5. 考虑更深的CNN用于分类
使用非常深的卷积神经网络可以获得更好的性能,尽管标准的、可重复使用的架构尚未被用于分类任务。
Alexis Conneau 等人评论了用于自然语言处理的相对较浅的网络,以及用于计算机视觉应用的更深网络所取得的成功。例如,Kim(上文)将模型限制为单个卷积层。
论文中回顾的用于自然语言的其他架构被限制在5到6层。这些与计算机视觉中使用的成功架构形成了对比,后者拥有19层甚至多达152层。
他们建议并证明,使用名为VDCNN的非常深的卷积神经网络模型进行分层特征学习具有优势。
…我们建议使用多达29层的深度卷积架构来达到这个目标。我们的架构设计灵感来自计算机视觉的最新进展 […] 所提出的深度卷积网络显示出比以前的ConvNets方法显著更好的结果。
他们方法的核心是对单个字符而不是词语进行嵌入。
我们提出了一种新的用于文本处理的架构(VDCNN),它直接在字符级别操作,并且只使用小的卷积和池化操作。
—— 用于文本分类的非常深的卷积网络,2016。
在撰写本文时,对8个大型文本分类任务套件的结果显示出比浅层网络更好的性能。具体来说,除了两个数据集之外,在所有测试数据集上都达到了最先进的结果。
总的来说,他们从探索更深层次的架构方法中得出了一些关键发现:
- 非常深的架构在小型和大型数据集上都表现良好。
- 更深的网络可以降低分类错误。
- 最大池化比其他更复杂的池化类型能取得更好的结果。
- 通常,更深的网络会降低准确性;架构中使用的快捷连接很重要。
……这是首次在自然语言处理中展示卷积神经网络的“深度优势”。
—— 用于文本分类的非常深的卷积网络,2016。
进一步阅读
如果您想深入了解此主题,本节提供了更多资源。
- 自然语言处理神经网络模型入门, 2015.
- 用于句子分类的卷积神经网络, 2014.
- (几乎)从零开始的自然语言处理, 2011.
- 用于文本分类的非常深的卷积网络, 2016.
- 用于文本分类的字符级卷积网络, 2015.
- 用于句子分类的卷积神经网络的敏感性分析(以及实践者指南), 2015.
您是否遇到过关于深度学习文档分类的优秀资源?
在下面的评论中告诉我。
总结
在这篇文章中,您了解了开发用于文档分类的深度学习模型的一些最佳实践。
具体来说,你学到了:
- 文本分类的一个关键方法是使用词嵌入和卷积神经网络。
- 单层模型在中等规模问题上表现良好,并提供了如何配置它的思路。
- 直接处理文本的深度模型可能是自然语言处理的未来。
你有什么问题吗?
在下面的评论中提出你的问题,我会尽力回答。
谢谢 Jason 的这篇文章。然而,关于整个文档如何分类,我有些不清楚。
你写道:“句子被映射到嵌入向量,并作为矩阵输入模型。”
所以如果我的文档有100个句子,我必须做100个预测,每个句子一个?然后选择最常预测的类别?
不,您可以将整个文档映射到嵌入向量。
是的,但是大多数库,比如 Keras,接受固定大小的矩阵作为输入。所以我必须提前固定输入的大小。将其固定为文档的最大大小会创建巨大的输入矩阵。我说的对吗,还是我遗漏了什么?
这对于许多公式来说是正确的,但并非规则。
您可以定义不指定输入/输出长度的模型,并真正处理可变长度的输入和输出。我本周有一篇文章专门讨论这个话题。
我明白在这个公式中 https://3qeqpr26caki16dnhd19sv6by6v-wpengine.netdna-ssl.com/wp-content/uploads/2017/08/Convolutional-Neural-Network-Architecture-for-Sentence-Classification.png,输入可以是可变长度的。我想知道如何在 Keras 这样的库中实现这一点。那我等你的帖子吧 🙂
我有一篇关于这个的帖子已安排。它也将出现在我关于这个主题的新书中。
杰森——新书是什么 🙂 主题是什么?
我的新书是关于自然语言处理的深度学习。目前正在编辑,很快就会发布。
你能详细解释一下如何将整个文档映射到嵌入向量吗?
当然,请看这个逐步教程:
https://machinelearning.org.cn/develop-word-embeddings-python-gensim/
在我看来,这篇文章是一个非常好的起点。然而,我不太明白的是,如何处理包含数百(或数千)个句子的大型文档。我们如何表示这样的大型文档呢?当然,理论上我们可以构建一个非常大的CNN,但实际上会存在内存问题。
那么,有没有更聪明的方法来做到这一点?我曾考虑过例如通过卷积层将每个句子压缩成特征,然后将这个特征用作整个文档的句子表示。然而,一个包含数千个句子的文档可能仍然太多而无法处理。应该如何做到这一点——或者有人能给我推荐一些文献吗?
您将在网络前端使用词嵌入,这意味着文档只需存储为长整数列表(例如,较小的)。此外,模型可以一次处理文档的子序列,例如LSTM在大约200-400个时间步长处达到上限。
但这难道不会生成另一个序列吗?如果任务是为整个文档分配多个标签,这种 LSTM 方法可能有助于将文档压缩到另一个低维特征空间(序列),但为了生成最终预测,可能仍然需要应用另一层“压缩”。
这看起来很有趣:http://www.aclweb.org/anthology/N16-1174
LSTM编码器-解码器架构可用于创建输入的压缩解释,然后输出不同长度的序列。我有很多关于这个主题的帖子。
注意力机制是编码器-解码器之上的一个很好的优化。我也有很多关于这个主题的帖子。请尝试博客搜索。
你好,
我发现RJ在文本分类方面也做了很好的研究。他们的论文
“用于文本分类的卷积神经网络:浅层词级与深层字符级”(https://arxiv.org/abs/1609.00718)在相同数据集上显示了良好的结果。
此后,他们在文本分类方面取得了良好进展,并于2017年ACL发表了论文“用于文本分类的深度金字塔卷积神经网络”(http://aclanthology.coli.uni-saarland.de/pdf/P/P17/P17-1052.pdf)。
太棒了,谢谢分享!
谢谢杰森的这篇有用的文章。我有一个关于CNN与LSTM结合用于情感分类的问题。是否可以将它们结合起来以提高性能?我该如何进行训练过程?
我很快就会有一些关于这个主题的教程,它们已经安排好了。
感谢Jason的这篇文章。您能否也提供一些关于如何使用CNN或RNN进行网络内容提取(主要是新闻文章)的指导。我认为它们也属于文档分类(内容或非内容分类),但不确定哪种类型的特征和深度架构效果最好。此外,我还在寻找一个适用于此类问题的好训练语料库。您能给我指明正确的方向,或者提供一个专门的教程会更好。谢谢。
内容提取是对数据中名词的总结。
我希望将来能涵盖这个话题。
CNN 在文档分类方面优于 LSTM 吗?
是的,实践中我认为是这样。我建议您尽可能地推进嵌入+CNN,只有当它们在您的特定数据上表现更好时才转向LSTM。
杰森,请帮帮我。
我尝试多次从卷积层而不是嵌入层开始我的网络。但每次都收到错误消息(输入形状)。
这是我的 pad_sequences
[7 5 4 3 0 0 0 0]
..
[1 5 8 9 11 5 3 6]
请告诉我如何配置我的 Conv1D?
具体错误是什么?
感谢反馈。昨天我再次尝试,我们能够将卷积层作为第一层而不是嵌入层进行开发。
关键在于输入的形状。我使用了 numpy.reshape 函数来准备数据。
不错,Alex!
未来关于重塑的更多帮助,请参阅此帖子。
https://machinelearning.org.cn/index-slice-reshape-numpy-arrays-machine-learning-python/
嗨 Jason,谢谢分享。很多次我在网上搜索我的问题,最后都找到了这里。你的文章总是很有帮助,而且写得很好。而且……一个有点琐碎的事情,关于字体。我知道这是主观的,但我发现它们太细太浅,不太容易阅读。我决定告诉你,因为将来我可能会阅读更多你的有益文章。😉
感谢您的建议。
我的CNN模型对每个输入都预测相同的类别。你能帮我吗?
这里有一些想法
https://machinelearning.org.cn/improve-deep-learning-performance/
嗨 Jason,这是一篇很好的文章。那么,如果文档是图像(tiff)并且包含文本,CNN能否用于分类?另外,假设文档是发票,我如何使用CNN提取信息?
当然,我不明白为什么你不能在这些情况下训练模型。
谢谢,但这篇帖子根本没有提到标题所说的文档分类。
我相信它有。你到底是什么意思?
你需要什么帮助?
您有什么关于如何整合文档级元数据以帮助改进分类的想法吗?例如,文档类型、文档检索位置、检索日期或描述文档的额外文本数据等信息。提前感谢!
是的,在文档旁边放置一个包含这些数据的向量,并根据文档和向量对模型进行条件化。也许可以使用多头模型。
这里有一些例子
https://machinelearning.org.cn/keras-functional-api-deep-learning/
你好,Jason,谢谢你的回复!
你说的“根据文档和向量来调整模型”是什么意思?你引用的链接中介绍的多输入模型是否包含了这个过程?你觉得在许多问答模型中使用的注意力机制在实现“调整”方面效果如何?再次感谢你的见解!
是的,一个多头输入模型。
尝试注意力机制,看看它是否能提升模型技能,超越没有注意力机制的模型。
嗨,Jason,
我将如何使用深度学习方法对文本数据(句子)进行有监督多类别分类?
这是一个例子
https://machinelearning.org.cn/develop-word-embedding-model-predicting-movie-review-sentiment/
嗨,Jason,
目前我正在使用一个包含输入句子和对应标签的数据集(这是一个JSON文件)。这基本上是一个文本分类问题。首先,我预处理数据集并将其转换为词袋以训练DNN。现在,我想使用Doc2Vec而不是词袋方法。你能分享一些链接吗?如何将为每个句子生成的向量用作训练样本。
是的,请看这篇文章
https://machinelearning.org.cn/use-word-embedding-layers-deep-learning-keras/
嗨 Jason,我们能否建立一个基于语言对文档进行分类的模型?
我觉得没问题。听起来是个有趣的项目!
谷歌翻译就是这样做的——检测语言。
嗨 Jason,我是深度学习新手,我想问的是,为什么我们在嵌入层之后使用CNN而不是RNN?
两者都可以使用。在某些问题上,CNN的性能可能优于LSTM。我们必须发现哪种方法最适合我们特定的数据集。
您好,关于第6天,我找到了以下文章,它们可能为CNN模型+嵌入的超参数提供一些提示
涉及各种基于CNN的文本分类方法和其他NLP任务。
1) “CNN和RNN在自然语言处理中的比较研究” (https://arxiv.org/pdf/1702.01923.pdf) 比较了CNN和RNN (GRU, LSTM) 在一系列NLP任务中的应用以及获得的结果。它还提供了模型和使用的超参数的描述。
2) “自然语言处理中深度学习的超参数调整” (http://ceur-ws.org/Vol-2458/paper5.pdf) 提供了CNN和双向LMST模型中超参数调整的方法和值。
3) “基于词嵌入的卷积神经网络用于中文分词” (https://www.aclweb.org/anthology/I17-1017.pdf) 描述了该任务的模型,并提供了采用的超参数表。
其他基于CNN的模型在以下论文中进行了讨论和描述(并详细说明了超参数)
4) 在“用于自然语言处理的非常深的卷积网络” (https://arxiv.org/pdf/1606.01781.pdf) 中,他们指出堆叠的LSTM网络不能做得更深,而CNN(尽管它不是一个真正的序列到序列网络)可以在层次结构中获取语义。然而,更深入需要特定的网络解决方案,包括超参数设置和结构安排(例如inception层)。允许深度CNN的安排在“Squeezed Very Deep Convolutional Neural
Networks for Text Classification” (https://arxiv.org/pdf/1901.09821.pdf),以及“基于多块卷积高速公路的文本分类” (https://arxiv.org/ftp/arxiv/papers/1807/1807.09602.pdf) 中提出。
5) “一种用于句子分类的注意力门控卷积神经网络” (https://arxiv.org/ftp/arxiv/papers/1808/1808.07325.pdf) 中提出了基于注意力的CNN用于文本分类,以便在池化之前为特征图分配基于上下文的权重,从而在更高的抽象级别也保持局部语义。这对于多标签分类等更精细粒度的任务很有用,并且在“卷积和循环神经网络的集成应用用于多标签文本分类” (https://sentic.net/convolutional-and-recurrent-neural-networks-for-text-categorization.pdf) 中使用了相同目标的另一种方法。
此致
Paolo Bussotti
干得好!
一如既往地非常有帮助的文章
我有一个问题
我们可以将word2vec与n-gram一起使用吗?我的意思是,不是构建和转换每个单词到嵌入向量,我们可以这样做,但对于二元组,我的意思是嵌入向量将代表二元组(bi gram)而不是只有一个单词(unigram)?
或许可以,抱歉我没有这方面的教程。
谢谢你的回复
不客气。
这真的是一个很棒的文本分类教程。我非常感谢作者提供了这样一个信息丰富且有用的教程。谢谢您,先生。
不客气!
你好 jason!
关于NLP文本分类概念的优秀教程!
关于此ML/DL CNN文本分类模型架构教程的两个理论问题
1º) 为了在ML/DL中将Conv1D卷积层应用于文本分类,我们是否必须有一个之前的嵌入层?我猜是这样,因为它们需要一个3D输入张量,对吗?
2º) 是否有任何文本分类方法,类似于计算机视觉中的VGG16,其中可以将几个卷积层和池化层的多个块顺序应用?
此致,
JG
嵌入通常是个好主意,但并非必需。如果你愿意,你可以直接将整数编码的词输入CNN或LSTM。
以前没有,但现在可能有。例如,Transformer/BERT在语言模型中占据主导地位。
喜欢这个总结。你有一个小小的笔误
“Kernel sizes: 2, 4, 5.” 在第2章中应该是“Kernel sizes: 3, 4, 5.”,根据原始论文的第1748页,第3.1章:https://www.aclweb.org/anthology/D14-1181.pdf。
谢谢!已修复。
嗨 Jason,我可以问你对这个有什么看法吗?
https://datascience.stackexchange.com/questions/87222/problem-of-multi-class-classification-sklearn-tfidfvectorizer-and-sgdclassifier
谢谢你
这是我在这里回答的一个常见问题
https://machinelearning.org.cn/faq/single-faq/can-you-comment-on-my-stackoverflow-question
嗨,谢谢你的这篇文章!在情感问题中,是否可以找出哪些词对给定的标签有贡献?还是这个过程太像黑盒了?
大多是黑盒。很不幸,深度学习使得理解网络给出特定答案的原因变得相当困难。
嗨,Jason,
处理超过512个字符的文本的最佳方法是什么?BERT支持那么长的文本吗?或者还有其他什么库最适合处理这种情况?
512个字符不算长。BERT可以处理。
尊敬的先生,
哪种深度学习方法更适合文本分类,CNN还是RNN?您有相关的链接吗?
嗨 Sheetal…这两种方法都是很好的选择。以下资源可能对您有所帮助
https://towardsdatascience.com/model-selection-in-text-classification-ac13eedf6146