• [其他] 自然语言
           自然语言(Natural language)通常是指一种自然地随文化演化的语言。例如,汉语、英语、日语都是自然语言的例子,这一种用法可见于自然语言处理一词中。自然语言是人类交流和思维的主要工具。 自然语言是人类智慧的结晶,自然语言处理是人工智能中最为困难的问题之一,而对自然语言处理的研究也是充满魅力和挑战的,也是各国人表达的方法其中之一。       与自然语言相对的是逻辑语言。自然语言是人脑与人脑的交际工具 ,逻辑语言是人脑与电脑的交际工具。认知科学认为,思维和认知是知识的逻辑运算,任何计算化的自然语言分析都主要依赖逻辑语言对这种分析的表述。研究心智表现及其运算的认知科学理论追求的是心智研究的物质体现,这最终将导致语言学研究进入自然科学研究。自然语言的高度形式化描写对计算机程序的机械模仿至关重要,但理解力模仿不同于机械模仿,它们之间的区别非常类似自然语言中形式操作与意义操作之间的不同。机械模仿涉及的是形式性质,而理解力模仿涉及的却是准语义性质。现阶段计算机以机械模仿为主并通过逻辑语言与人类的自然语言对话       自然语言处理( Natural Language Processing, NLP)是计算机科学领域与人工智能领域中的一个重要方向。它研究能实现人与计算机之间用自然语言进行有效通信的各种理论和方法。自然语言处理是一门融语言学、计算机科学、数学于一体的科学。因此,这一领域的研究将涉及自然语言,即人们日常使用的语言,所以它与语言学的研究有着密切的联系,但又有重要的区别。自然语言处理并不是一般地研究自然语言,而在于研制能有效地实现自然语言通信的计算机系统,特别是其中的软件系统。因而它是计算机科学的一部分  。       自然语言处理主要应用于机器翻译、舆情监测、自动摘要、观点提取、文本分类、问题回答、文本语义对比、语音识别、中文OCR等方面 。
  • [技术干货] EMNLP 2021 | 罗氏和博阿齐奇大学研究合作团队提出:多标签文本分类中长尾分布的平衡策略
    作者简介:黄毅,本文一作,目前为罗氏集团的数据科学家,研究领域为自然语言处理的生物医学应用。 论文链接:https://arxiv.org/pdf/2109.04712.pdf 文章源码:https://github.com/Roche/BalancedLossNLP 1.摘要 多标签文本分类是自然语言处理中的一类经典任务,训练模型为给定文本标记上不定数目的类别标签。然而实际应用时,各类别标签的训练数据量往往差异较大(不平衡分类问题),甚至是长尾分布,影响了所获得模型的效果。重采样(Resampling)和重加权(Reweighting)常用于应对不平衡分类问题,但由于多标签文本分类的场景下类别标签间存在关联,现有方法会导致对高频标签的过采样。本项工作中,我们探讨了优化损失函数的策略,尤其是平衡损失函数在多标签文本分类中的应用。基于通用数据集 (Reuters-21578,90 个标签) 和生物医学领域数据集(PubMed,18211 个标签)的多组实验,我们发现一类分布平衡损失函数的表现整体优于常用损失函数。研究人员近期发现该类损失函数对图像识别模型的效果提升,而我们的工作进一步证明其在自然语言处理中的有效性。2.引言多标签文本分类是自然语言处理(NLP)的核心任务之一,旨在为给定文本从标签库中找到多个相关标签,可应用于搜索(Prabhu et al., 2018)和产品分类(Agrawal et al., 2013)等诸多场景。图 1 展示了通用多标签文本分类数据集 Reuters-21578 的样例数据(Hayes and Weinstein, 1990)。                                                                  图1 Reuters-21578 的样例数据(仅展示文章标题)。标签后面的数字代表数据集中带有该标签的数据实例个数。 当标签数据存在长尾分布(不平衡分类)和标签连锁(类别共现)时,多标签文本分类会变得更加复杂(图2)。长尾分布,指的是一小部分标签(即头部标签)有很多数据实例,而大多数标签(即尾部标签)只有很少数据实例的不平衡分类情况。标签连锁,指的是头部标签与尾部标签共同出现导致模型对头部标签的权重倾斜。现有的 NLP 解决方案包括但不限于:在分类中对尾部标签重采样(Estabrooks et al., 2004; Charte et al., 2015),模型初始化时将类别共现信息纳入考虑(Kurata et al., 2016),以及将头尾部标签混合的多任务架构方案 (Yang et al., 2020) 。但这些方案依赖于模型架构的专门设计,或不适用于长尾分布数据。 近年来,计算机视觉(CV)领域也有不少关于多标签分类的研究。其中,优化损失函数的策略已被用于多种 CV 任务,如对象识别(Durand et al., 2019; Milletari et al., 2016)、语义分割(Ge et al., 2018)与医学影像(Li et al., 2020a)等。平衡损失函数,如 Focal loss (Lin et al., 2017)、Class-balanced loss (Cui et al., 2019) 和 Distribution-balanced loss (Wu et al., 2020) 等,提供了针对多标签图像分类的长尾分布和标签连锁问题的解决方案。由于损失函数的调整可以独立于模型架构地灵活嵌入常见模型,NLP 中也逐步有类似的优化损失函数的策略探索(Li et al., 2020b; Cohan et al., 2020)。例如,(Li et al., 2020b) 将医学图像分割任务中的 Dice loss (Milletari et al., 2016) 引入 NLP,显著改善了多种任务的模型效果。 本项工作中,我们将一类新的平衡损失函数引入 NLP,用于多标签文本分类任务,并使用 Reuters-21578(一个通用的小型数据集)和 PubMed(一个生物医学领域的大型数据集)数据集进行了实验。对于这两个数据集,分布平衡损失函数在总指标上优于其他损失函数,并且显著改善了尾部标签的模型表现。我们认为,平衡损失函数为多标签文本分类的应用提供了一个有效策略。 3.方法介绍 损失函数 多标签文本分类中,二值交叉熵(Binary Cross Entropy, BCE)是较常用的损失函数 (Bengio et al., 2013)。原始的 BCE 容易被大量头部标签或负样本干扰。近年来,一些新的损失函数通过调节 BCE 的权重,实现了模型训练过程的相对平衡。我们在此回顾了三类损失函数设计。 Focal loss (FL)通过模型对数据实例标记标签的“难易程度”为 BCE 设计权重 (Lin et al., 2017)。对于同一数据实例,相比可轻松分类(p值接近真实值)的标签,难以标记(p值远离真实值)的标签将获得比 BCE 更高的权重。由于 FL 在模型训练过程中良好的自适应效果,下述两类损失函数也采用了这一组件。 Class-balanced focal loss(CB)通过估计数据采样的有效数量,将每个标签增量训练数据的边际效用纳入考虑,在不同训练数据支持的标签间调节权重 (Cui et al., 2019)。 Distribution-balanced loss(DB,分布平衡损失函数)则是在 FL 基础上添加了两部分组件 (Wu et al., 2020)。其一为 Rebalancing 组件,减少了标签连锁带来的冗余信息,其二为 Negative Tolerant Regularization (NTR)组件,在不同正负样本数目的标签间调节权重,降低尾部标签的阈值。 上述损失函数的具体设计如图3所示(简单起见已略去求和平均项)。 数据集 本项工作中,我们使用了两个不同数据量和领域的多标签文本分类数据集(表 1)。Reuters-21578 数据集包含1987 年刊登在路透社的一万多份新闻文章(Hayes and Weinstein, 1990)。我们按照(Yang and Liu, 1999)使用的训练-测试分割数据,并将 90 个标签平均分为头部(30 个标签,各含 ≥35 个实例)、中部(31 个标签,各含 8-35 个实例)和尾部(30 个标签,各含 ≤8 个实例)标签的子集。PubMed 数据集则来自 BioASQ 竞赛(Licence:8283NLM123),包含PubMed 文章的标题、摘要及对应的生物医学主题词标记 (MeSH)(Tsatsaronis et al.,2015; Coordinators, 2017)。类似地,18211个标签按分位数分为头部(6018 个标签,各含≥50 个实例)、中部(5581 个标签,各含 15-50 个实例)和尾部(6612 个标签,各含 ≤15 个实例)标签的子集。 4.实验 我们比较了不同损失函数与经典 SVM one-vs-rest 模型的表现。对于各个数据集和模型,我们计算了标签集整体以及头部、中部、尾部标签子集的micro-F1 和 macro-F1 得分(Wu et al., 2019;Lipton et al., 2014 )。表 2 汇总了不同损失函数的实验结果。Reuters-21578 结果中,BCE 的表现最差。依次对比 micro-F1 和 macro-F1之间、及不同组间的得分可以看出长尾分布的影响。PubMed 数据由于不平衡更明显,长尾分布的影响更大。 对于 Reuters-21578 数据集,损失函数 FL、CB、R-FL 和 NTR-FL 在头部标签中的表现与 BCE 相似,但在中部和尾部标签中的表现优于 BCE,说明它们对于不平衡问题的改进。DB 在尾部标签改进最明显,整体表现也优于先前使用相同数据集的解决方案,例如 Binary Relevance、EncDec、CNN、CNN-RNN、Optimal Completion Distillation和 GNN 等(Nam et al., 2017 ; Pal et al., 2020;Tsai and Lee et al., 2020)。对于PubMed 数据集,由于BCE 中部和尾部标签已失效,我们使用 FL 作为更强的基线。其他损失函数在中部和尾部标签中的表现均优于 FL。DB 再次证明了其在整体、中部和尾部标签的良好效果。 我们进一步尝试从 DB 中去除一个组件,即移除 NTR 组件得到 R-FL、移除 Rebalancing 组件得到 NTR-FL,移除 FL 组件得到 DB-0FL,通过比较三个残缺模型探索对应三个组件的效果。如表 2 所示,对于两个数据集,移除 NTR 组件 (R-FL) 或 FL 组件 (DB-0FL) 会降低所有亚组的模型效果。移除 Rebalancing 组件 (NTR-FL) 产生相似的整体 micro-F1,但整体 macro-F1 及中部和尾部标签 F1 得分不如 DB,显示增加Rebalancing 组件的作用。最终,我们还尝试将 NTR-FL 与 CB 集成,从而得到一个全新的损失函数 CB-NTR,它在两个数据集上得到的所有 F1 值均优于 CB。CB-NTR 和 DB 间的唯一区别是使用 CB 权重替换了 Rebalancing 权重,而 DB 在中部和尾部标签中的表现优于或非常接近 CB-NTR,可能来自于通过 Rebalancing 权重处理标签连锁对模型效果的提升。 5.结语 针对多标签文本分类中的不平衡分类问题,我们研究了优化损失函数的策略,并系统比较了各种平衡损失函数的效果。我们首次将 DB 引入 NLP,并设计了全新的平衡损失函数 CB-NTR。在开放数据集 Reuters-21578(90 类标签,通用领域)和 PubMed(18211 类标签,生物医学领域)的实验表明,DB 的模型效果优于其他损失函数。这项研究证明,优化损失函数的策略可以有效解决多标签文本分类时不平衡分类的问题。该策略由于仅需调整损失函数,可以灵活兼容各种基于神经网络的模型框架,也适用于其他受到长尾分布影响的 NLP 任务。罗氏集团制药部门中国 CIO 施涪军:该工作来自于合作团队在生物医学领域的深度学习应用探索。相比于日常文本,生物医学领域的语料往往更专业,而标注更稀疏,导致 AI 应用面临“最后一公里”的落地挑战。本论文从稀疏标注的长尾分布等问题入手,由 CV 前沿研究引入损失函数并优化,使得既有 NLP 模型可以在框架不变的情况下将训练资源向实例较少的类别平衡,进而实现整体的模型效果提升。很高兴看到此策略在面临类似问题的日常文本上同样有效,希望继续与院校、企业在前沿技术的研究与应用上扎实共创。来源“雷锋网”本文作者:我在思考中原文链接 | https://www.leiphone.com/category/academic/QEkiGHqkbtib0XBN.html
  • [MindX SDK] 基于Pipeline的流程开发中对于NLP类模型输入构建的数据类型错误问题
    【功能模块】最近在做nlp方面的模型转化,参考官网提供的bert模型的开发方式。现在需要将一个1*500的词向量作为模型输入没办法直接调用send_data函数。参照bert中的构建protobuf_vec向量。然后调用SendPortobuf函数进行模型输入。此时会报错,而打印protobuf_vec的类型信息显示为:前面多了个roxy of <Swig Object of type (不知道是什么原因) 相关代码L是一个长度为500的int类型的listtensor = np.array(L)tensor = np.expand_dims(tensor, 0)tensor_package_list = MxpiDataType.MxpiTensorPackageList()tensor_package = tensor_package_list.tensorPackageVec.add()array_bytes = tensor.tobytes()data_input = MxDataInput()data_input.data = array_bytestensor_vec = tensor_package.tensorVec.add()tensor_vec.deviceId = 0tensor_vec.memType = 0for i in tensor.shape: tensor_vec.tensorShape.append(i)tensor_vec.dataStr = data_input.datatensor_vec.tensorDataSize = len(array_bytes)key = "appsrc{}".format(appsrc_id).encode('utf-8')print('key='+str(key))protobuf_vec = InProtobufVector()protobuf = MxProtobufIn()protobuf.key = keyprotobuf.type = b'MxTools.MxpiTensorPackageList'protobuf.protobuf = tensor_package_list.SerializeToString()protobuf_vec.push_back(protobuf)print("发送数据流表为")print(protobuf_vec)ret = stream_manager.SendProtobuf(stream_name, appsrc_id, protobuf_vec)
  • [其他] 自然语言处理一些应用场景
    机器翻译机器翻译因其效率高、成本低满足了全球各国多语言信息快速翻译的需求。机器翻译属于自然语言信息处理的一个分支,能够将一种自然语言自动生成另一种自然语言又无需人类帮助的计算机系统。目前,谷歌翻译、百度翻译、搜狗翻译等人工智能行业巨头推出的翻译平台逐渐凭借其翻译过程的高效性和准确性占据了翻译行业的主导地位。自动问答传统的搜索引擎技术已经不能满足人们越来越高的需求,而自动问答技术成为了解决这一问题的有效手段。自动问答是指利用计算机自动回答用户所提出的问题以满足用户知识需求的任务,在回答用户问题时,首先要正确理解用户所提出的问题,抽取其中关键的信息,在已有的语料库或者知识库中进行检索、匹配,将获取的答案反馈给用户。打击垃圾邮件当前,垃圾邮件过滤器已成为抵御垃圾邮件问题的第一道防线。不过,有许多人在使用电子邮件时遇到过这些问题:不需要的电子邮件仍然被接收,或者重要的电子邮件被过滤掉。事实上,判断一封邮件是否是垃圾邮件,首先用到的方法是“关键词过滤”,如果邮件存在常见的垃圾邮件关键词,就判定为垃圾邮件。但这种方法效果很不理想,一是正常邮件中也可能有这些关键词,非常容易误判,二是将关键词进行变形,就很容易规避关键词过滤。自然语言处理通过分析邮件中的文本内容,能够相对准确地判断邮件是否为垃圾邮件。目前,贝叶斯(Bayesian)垃圾邮件过滤是备受关注的技术之一,它通过学习大量的垃圾邮件和非垃圾邮件,收集邮件中的特征词生成垃圾词库和非垃圾词库,然后根据这些词库的统计频数计算邮件属于垃圾邮件的概率,以此来进行判定。文本情感分析情感分析作为一种常见的自然语言处理方法的应用,可以让我们能够从大量数据中识别和吸收相关信息,而且还可以理解更深层次的含义。比如,企业分析消费者对产品的反馈信息,或者检测在线评论中的差评信息等。信息提取金融市场中的许多重要决策正日益脱离人类的监督和控制。算法交易正变得越来越流行,这是一种完全由技术控制的金融投资形式。但是,这些财务决策中的许多都受到新闻的影响。因此,自然语言处理的一个主要任务是获取这些明文公告,并以一种可被纳入算法交易决策的格式提取相关信息。例如,公司之间合并的消息可能会对交易决策产生重大影响,将合并细节(包括参与者、收购价格)纳入到交易算法中,这或将带来数百万美元的利润影响。
  • [其他] 自然语言处理--展望
    从历史角度来讲,模型越来越大。GPT-3已经这么大了,我们还能做得更大吗?当然如果未来计算设备的硬件的问题解决了,可以更大,但是近期内呢?更大的模型应该是什么样子?我设想的一种方式就是分布式,把模型分布到很多机器上计算,就像搜索引擎一样。像BERT这一类模型如何再把它训练的更大?现在最大的几个预训练语言模型都是GPT类的,BERT这一类模型很难做得更大,一些工程上的问题目前还是很难解决的。那么未来我们是否可能训练更大的BERT类的模型?小模型相反, BERT这类模型可以压缩的很小,GPT模型就很难压缩。BERT这个模型的压缩是不是还有潜力可以挖掘?另外知识融入是一个很有意思的问题。知识融入人们做了很多工作,实际上我是不太满意的。因为很多工作只是在解决知识类的问题效果比较好, 一般的 NLP的问题,知识融入的作用并不是那么大,所以希望知识融入能够解决一般的 NLP的问题。还有就是知识应该如何表示?现在大部分人认为知识都是三元组,我觉得这个是存在争议的,三元组实际上能够表达的知识其实非常有限。比如序列关系、空间关系、集合关系、数值关系等等关系知识都是很难学到的。关于搜索引擎,我希望以后预训练语言模型可以和搜索引擎结合起来,预训练语言模型就是个能够回答任何问题的搜索引擎。最后就是多模态预训练,希望将来它能带来无限的想象空间。
  • [其他] 自然语言处理--知识蒸馏
    TinyBERT知识蒸馏的基本流程包括两步,第一步叫做general distillation,即使用一个大的预训练语言模型,训练一个小的预训练语言模型。第二步叫做task-specific distillation,即使用一个大的预训练语言模型,去对一个小的预训练语言模型进行微调。在这里我们引入了一个新的技术,叫做数据增强,这个技术非常重要,如果没有这个技术的话,整个模型的性能会下降很多。TinyBERT知识蒸馏的损失函数中一个比较重要的就是,让中间层去学习隐藏状态和attention向量。TinyBERT知识蒸馏的选层策略就是,我们用4层或者6层的学生模型,去学习12层的教师模型。但是让哪一层去学习哪一层,这就是一个有关映射的策略的问题了。我们最早提出的是一个均匀映射模型,即用小模型的1,2,3,4层,去依次学习大模型的3,6,9,12层。后来我们就在想,是否可以让每一层都自动去搜索一个最合适的层次学习?我们就引入了进化学习算法。然后我们发现,对小模型来说,最好的学习层次是0,0,5,10。即小模型的第一层,第二层不要去学习,最好直接使用自动反向传播去调。用第3层去学大模型的第5层,第4层去学大模型的第10层,这样效果最好。6层的学生模型我们学到的是0,5,0,0,0,10。通过选层策略可以发现,选择好的层次的话就可以提高整体的效果。TinyBERT知识蒸馏数据增强是一个非常有效的技术。因为下游任务一般数据都比较少,那么我们在蒸馏小模型的时候,数据的数量经常是不足的。我们采取的办法,就是把用于下游任务的数据进行增强。数据增强实际上就是利用了BERT本身的特点,它的每个词都是可以替换成别的词的。我们采用一种替换策略,就是把每个词都去做一些替换,这样的话就会生成很多的跟原来的句子很相似的句子,比如10个词的句子换掉2个或者3个词,去生成增强的语料。最后,我们发现大概增强20倍的时候,即将原来的一个句子替换生成20个左右相似的句子,用来做下游任务的蒸馏的效果最好。这是我们的实验结果,我们看到在4层的模型,在GLUE上面,总的分数大概降低了2.5,从79.5降到77。6层的TinyBERT基本上是跟12层的没有什么变化。在参数量方面,BERT-base有109M,而4层的模型只有14.5M,只有原模型的13.3%。6层的模型只降到了原来的一半。在速度方面,我们也可以看到4层的模型提速了9.4倍,提速非常高。并且我们现在模型空间非常小,参数量是14.5M的模型大小只有50M左右,完全可以放入手机之中,并且它的推理速度比原来快将近快10倍。目前我们这个模型已经大量的运用在华为的设备与应用之中。我们还做了一个工作,在华为自研的BOLT深度学习加速库下,利用了底层的硬件再一次进行压缩和加速,使得TinyBERT最终的推理速度,可以达到1.3毫秒。我们的TinyBERT在中文的CLUE小模型排行榜上一直是第一名。然后我们参加了 NLPCC的小模型评测比赛,也是获得了第一名。
  • [其他] 自然语言处理技术难点
    内容的有效界定日常生活中句子间的词汇通常是不会孤立存在的,需要将话语中的所有词语进行相互关联才能够表达出相应的含义,一旦形成特定的句子,词语间就会形成相应的界定关系。如果缺少有效的界定,内容就会变得模棱两可,无法进行有效的理解。例如他背着母亲和姐姐悄悄的出去玩了。这句话中如果不对介词“和”作出界定,就很容易形成母亲和姐姐两个人不知道他出去玩,或者是母亲不知道他和姐姐出去玩。消歧和模糊性词语和句子在不同情况下的运用往往具备多个含义,很容易产生模糊的概念或者是不同的想法,例如高山流水这个词具备多重含义,既可以表示自然环境,也能表达两者间的关系,甚至是形容乐曲的美妙,所以自然语言处理需要根据前后的内容进行界定,从中消除歧义和模糊性,表达出真正的意义。有瑕疵的或不规范的输入例如语音处理时遇到外国口音或地方口音,或者在文本的处理中处理拼写,语法或者光学字符识别(OCR)的错误。语言行为与计划句子常常并不只是字面上的意思;例如,“你能把盐递过来吗”,一个好的回答应当是把盐递过去;在大多数上下文环境中,“能”将是糟糕的回答,虽说回答“不”或者“太远了我拿不到”也是可以接受的。
  • [其他] 自然语言处理概念和技术
    信息抽取(IE)信息抽取是将嵌入在文本中的非结构化信息提取并转换为结构化数据的过程,从自然语言构成的语料中提取出命名实体之间的关系,是一种基于命名实体识别更深层次的研究。信息抽取的主要过程有三步:首先对非结构化的数据进行自动化处理,其次是针对性的抽取文本信息,最后对抽取的信息进行结构化表示。信息抽取最基本的工作是命名实体识别,而核心在于对实体关系的抽取。自动文摘自动文摘是利用计算机按照某一规则自动地对文本信息进行提取、集合成简短摘要的一种信息压缩技术,旨在实现两个目标:首先使语言的简短,其次要保留重要信息。语音识别技术语音识别技术就是让机器通过识别和理解过程把语音信号转变为相应的文本或命令的技术,也就是让机器听懂人类的语音,其目标是将人类语音中的词汇内容转化为计算机可读的数据。要做到这些,首先必须将连续的讲话分解为词、音素等单位,还需要建立一套理解语义的规则。语音识别技术从流程上讲有前端降噪、语音切割分帧、特征提取、状态匹配几个部分。而其框架可分成声学模型、语言模型和解码三个部分。Transformer 模型Transformer 模型在2017 年,由Google 团队中首次提出。Transformer 是一种基于注意力机制来加速深度学习算法的模型,模型由一组编码器和一组解码器组成,编码器负责处理任意长度的输入并生成其表达,解码器负责把新表达转换为目的词。Transformer 模型利用注意力机制获取所有其他单词之间的关系,生成每个单词的新表示。Transformer 的优点是注意力机制能够在不考虑单词位置的情况下,直接捕捉句子中所有单词之间的关系。模型抛弃之前传统的encoder-decoder 模型必须结合RNN 或者CNN(Convolutional Neural Networks, CNN)的固有模式,使用全Attention 的结构代替了LSTM,减少计算量和提高并行效率的同时不损害最终的实验结果。但是此模型也存在缺陷。首先此模型计算量太大,其次还存在位置信息利用不明显的问题,无法捕获长距离的信息。 基于传统机器学习的自然语言处理技术自然语言处理可将处理任务进行分类,形成多个子任务,传统的机械学习方法可利用SVM(支持向量机模型)、Markov(马尔科夫模型)、CRF(条件随机场模型)等方法对自然语言中多个子任务进行处理,进一步提高处理结果的精度。但是,从实际应用效果上来看,仍存在着以下不足:(1)传统机器学习训练模型的性能过于依赖训练集的质量,需要人工标注训练集,降低了训练效率。(2)传统机器学习模型中的训练集在不同领域应用会出现差异较大的应用效果,削弱了训练的适用性,暴露出学习方法单一的弊端。若想让训练数据集适用于多个不同领域,则要耗费大量人力资源进行人工标注。(3)在处理更高阶、更抽象的自然语言时,机器学习无法人工标注出来这些自然语言特征,使得传统机器学习只能学习预先制定的规则,而不能学规则之外的复杂语言特征。 基于深度学习的自然语言处理技术深度学习是机器学习的一大分支,在自然语言处理中需应用深度学习模型,如卷积神经网络、循环神经网络等,通过对生成的词向量进行学习,以完成自然语言分类、理解的过程。与传统的机器学习相比,基于深度学习的自然语言处理技术具备以下优势:(1)深度学习能够以词或句子的向量化为前提,不断学习语言特征,掌握更高层次、更加抽象的语言特征,满足大量特征工程的自然语言处理要求。(2)深度学习无需专家人工定义训练集,可通过神经网络自动学习高层次特征。 
  • [其他] 自然语言处理的发展史
    最早的自然语言理解方面的研究工作是机器翻译  。1949年,美国人威弗首先提出了机器翻译设计方案  。其发展主要分为三个阶段。早期自然语言处理第一阶段(60~80年代):基于规则来建立词汇、句法语义分析、问答、聊天和机器翻译系统。好处是规则可以利用人类的内省知识,不依赖数据,可以快速起步;问题是覆盖面不足,像个玩具系统,规则管理和可扩展一直没有解决。统计自然语言处理第二阶段(90年代开始):基于统计的机器学习(ML)开始流行,很多NLP开始用基于统计的方法来做。主要思路是利用带标注的数据,基于人工定义的特征建立机器学习系统,并利用数据经过学习确定机器学习系统的参数。运行时利用这些学习得到的参数,对输入数据进行解码,得到输出。机器翻译、搜索引擎都是利用统计方法获得了成功。神经网络自然语言处理第三阶段(2008年之后):深度学习开始在语音和图像发挥威力。随之,NLP研究者开始把目光转向深度学习。先是把深度学习用于特征计算或者建立一个新的特征,然后在原有的统计学习框架下体验效果。比如,搜索引擎加入了深度学习的检索词和文档的相似度计算,以提升搜索的相关度。自2014年以来,人们尝试直接通过深度学习建模,进行端对端的训练。目前已在机器翻译、问答、阅读理解等领域取得了进展,出现了深度学习的热潮。
  • [其他] 预训练模型的思路是否可以推广到自然语言处理之外的领域?
    目前在预训练语言模型中,有很多想法都非常好,而且在自然语言处理方面取得了成功。因此很多人都在想,能不能将这种思路应用到别的领域?这个想法很好,做起来很困难,但最终也取得了一些喜人的成果。比如说在语音识别领域, Facebook提出了 wave2vec,它就是通过使用大量没有标注的、纯语音的数据,去预训练一个模型,然后利用这个模型,在一个少量文本标注的语料上进行语音识别,最终取得了非常好的效果。那么最近在图像上面,包括图像分类、目标检测等任务,都有一些预训练的相关研究。其中,DETR是用了transformer模型,但不算预训练。信息检索也已经开始用预训练语言模型,并取得了非常好的效果。在这方面目前大概有两类模型,一类采用sparse索引,它是使用传统的搜索引擎的前提下,去改进传统倒排表的方法。另一类采用dense索引,这种方法不需要建立传统的倒排表,而是直接用dense向量去对文本进行信息检索。
  • [其他] 自然语言处理--预训练语言模型压缩和加速
    如果希望将模型用到小设备上,我们就面临将模型进行加速和压缩的问题。预训练语言模型就形成了这两种趋势。一方面是人们把模型越做越大,去探索模型能力的边界。另外一方面就是模型越做越小,让它在各种下游任务上形成生产力,即在手机端等各种小设备上能够单独运行。目前模型压缩这一方面研究也非常多,主要包括三大类技术,一类是基于知识蒸馏的预训练语言模型压缩,另一类是基于剪枝的预训练语言模型压缩,还有一类是基于量化的预训练语言模型压缩。基于剪枝的预训练语言模型压缩,就是基于一定的准则,去除掉参数矩阵的冗余部分。比如在神经网络模型中,我们可以去掉一些冗余的神经元节点,和神经元连接,使得模型变小一点。基于量化的预训练语言模型压缩,就是减少数值表示所需要的比特值。目前我们使用的GPU都是用32位的浮点数计算,计算代价非常高。我们可以将它量化为8位的浮点数,甚至4位的浮点数、2位的浮点数,这样运算过程就得到了简化。还有一些别的压缩技术,比如矩阵参数分解、参数共享、模型架构设计与搜索。矩阵参数分解就是将一个大矩阵,分解成两个小矩阵的乘积。参数共享有很多方式,比如Transformer有很多层,各层之间可以共享其中一些参数。而ALBERT,就是所有的层共享其中一层的参数。共享参数的好处就是参数量大大减少,但实际上在推理时间上并不能大幅度减少,所以它能带来的好处还是有限。模型架构设计与搜索这方面的发展,其实跟近年来自动机器学习的发展有关系,我们希望通过自动机器学习,能够去搜索出更好的、更精简的架构。
  • [其他] 自然语言处理--GPT-3的冲击
    GPT-3有一个非常吸引人的地方,就是它几乎无需做微调,并且它的演示效果也很好。GPT-3给我们带来了非常大的冲击。这个模型有着极高的训练成本,使得实际上绝大部分的企业和科研机构都无力承担。它的1750亿参数比BERT-base模型大了100倍,比 GPT-2大了10倍。它单次训练需要1万亿单词的训练数据,以及1200万美元的训练成本,能够承担这种训练成本的企业在世界范围内也非常少。虽然它的训练成本如此之高,但是它的效果非常令人吃惊。以前我们解决特定的问题,都需要专门去找语料,做专门的训练才能做。现在这个模型,只要是需要的功能都可以直接实现,基本不用训练。还有一些我们原来觉得很难做到的事情,GPT-3也能做到,例如算术计算、写代码等等。它还能够很细致的区分56和49这两个词,甚至在数量上都能区分出来,如此的细腻度令人吃惊,这也给它的商业价值也带来巨大的想象空间。
  • [其他] 自然语言处理--预训练语言模型的做大
    预训练语言模型的做大不仅仅是带来量的提高,更带来了模型使用性质的变化。最早在词向量模型时期,整个自然语言处理就被带入了神经网络时代。在神经网络时代,单一的CPU已经不能满足需求了。可以通过GPU,在不需要进行过多额外计算的情况下,做到在整个词表上进行词的选择,这在以前的SMT上是不可想象的。正是有了GPU,我们才可以通过词向量模型这类神经语言模型来完成这类工作。如果没有GPU支持,或者用以前的统计方法,是难以想象的。预训练语言模型通过使用更大的GPU,更多的数据,也带来了更大的变化,即微调的模式。微调为下游任务大致规定了几种固定的模式,包括句子分类、句子关系的分类、词语序列标注,以及QA任务中常见的句子片段的提取等。以前解决每个NLP问题,都要先设计模型。现在通过微调这一简单的模式,我们不再需要去为每个任务去设计特定的NLP模型,而可以将所有的NLP任务都纳入几个模式。--固定模式 > 微调   这样将任务简单化了~
  • [其他] 自然语言处理--预训练的思想
    不管是统计方法还是神经网络方法,都是一种基于数据的方法。如果数据不够的话,模型就无法有效建立。但是现实生活中,数据永远是一个很大的问题。在实际应用场景中,我们得到的很多数据都是无标注的,在这种情况下传统模型就无法解决实际问题。预训练的思想是,在利用标注数据之前,先利用无标注的数据(也就是纯文本数据),去训练一个模型,这个模型能够学到一些潜在的跟标注无关的知识。然后在具体的任务上,预训练模型就可以利用大量的无标注数据训练所得到的知识。--到底是什么知识呢?第一代自然语言处理预训练模型是词向量模型。词向量模型是把大量的无标注的文本送到一个比较简单的神经网络里面,经过训练,每个词都会被赋予一个静态的向量。词的静态向量在空间分布上有一个非常好的特点,即相似的词会聚在一起。词与词之间的关系也会以一种向量的形式得到体现,从而实现了符号空间到向量空间的映射。
  • [调优经验] MindSpore进行NLP模型开发的常见问题与调优经验分享
    本文分享我在参与ms的nlp模型开发的过程中,遇到的一些“杂症”,大家如果有遇到类似的问题,或者有更好的解决办法,欢迎一起交流。1、dataset的batch问题当数据集进行batch划分后,最后一个batch小于batch_size时,模型训练加载数据时将会出现异常报错内容如下:epoch: 0, current epoch percent: 0.987, step: 154, outputs are (Tensor(shape=[], dtype=Float32, value= 0.15773), Tensor(shape=[], dtype=Bool, value= False))epoch: 0, current epoch percent: 0.994, step: 155, outputs are (Tensor(shape=[], dtype=Float32, value= 0.016068), Tensor(shape=[], dtype=Bool, value= False))[ERROR] RUNTIME(3547)kernel task happen error, retCode=0x26, [aicore exception].[ERROR] RUNTIME(3547)aicore kernel execute failed, device_id=0, stream_id=512, task_id=16182, fault kernel_name=Gather_16602455126779674102_0__kernel0, func_name=Gather_16602455126779674102_0__kernel0[ERROR] DEVICE(3537,python3):2021-03-09-06:21:49.246.617 [mindspore/ccsrc/runtime/device/ascend/ascend_kernel_runtime.cc:717] SyncStream] Call runtime rtStreamSynchronize error.[ERROR] DEVICE(3537,python3):2021-03-09-06:21:49.246.670 [mindspore/ccsrc/runtime/device/ascend/ascend_device_address.cc:279] SyncStream] Sync stream error!Traceback (most recent call last):File “main.py”, line 220, inFile “main.py”, line 187, in maindo_train(ds, netwithloss, load_pretrain_checkpoint_path, save_finetune_checkpoint_path, epoch_num)File “main.py”, line 138, in do_trainmodel.train(epoch_num, dataset, callbacks=callbacks)File “/home/ma-user/miniconda3/envs/Mindspore-1.1.1-python3.7-aarch64/lib/python3.7/site-packages/mindspore/train/model.py”, line 592, in trainsink_size=sink_size)File “/home/ma-user/miniconda3/envs/Mindspore-1.1.1-python3.7-aarch64/lib/python3.7/site-packages/mindspore/train/model.py”, line 391, in _trainself._train_dataset_sink_process(epoch, train_dataset, list_callback, cb_params, sink_size)File “/home/ma-user/miniconda3/envs/Mindspore-1.1.1-python3.7-aarch64/lib/python3.7/site-packages/mindspore/train/model.py”, line 452, in _train_dataset_sink_processoutputs = self._train_network(*inputs)File “/home/ma-user/miniconda3/envs/Mindspore-1.1.1-python3.7-aarch64/lib/python3.7/site-packages/mindspore/nn/cell.py”, line 351, in calloutput = self.construct(*cast_inputs, **kwargs)File “/home/ma-user/miniconda3/envs/Mindspore-1.1.1-python3.7-aarch64/lib/python3.7/site-packages/mindspore/train/dataset_helper.py”, line 87, in constructreturn self.network(*outputs)File “/home/ma-user/miniconda3/envs/Mindspore-1.1.1-python3.7-aarch64/lib/python3.7/site-packages/mindspore/nn/cell.py”, line 351, in calloutput = self.construct(*cast_inputs, **kwargs)File “/home/ma-user/work/bert_for_finetune.py”, line 117, in constructlabel_ids)File “/home/ma-user/miniconda3/envs/Mindspore-1.1.1-python3.7-aarch64/lib/python3.7/site-packages/mindspore/nn/cell.py”, line 351, in calloutput = self.construct(*cast_inputs, **kwargs)File “/home/ma-user/work/bert_for_finetune.py”, line 269, in constructlogits = self.bert(input_ids, input_mask, token_type_id)File “/home/ma-user/miniconda3/envs/Mindspore-1.1.1-python3.7-aarch64/lib/python3.7/site-packages/mindspore/nn/cell.py”, line 351, in calloutput = self.construct(*cast_inputs, **kwargs)File “/home/ma-user/work/finetune_eval_model.py”, line 50, in constructself.bert(input_ids, token_type_id, input_mask)File “/home/ma-user/miniconda3/envs/Mindspore-1.1.1-python3.7-aarch64/lib/python3.7/site-packages/mindspore/nn/cell.py”, line 351, in calloutput = self.construct(*cast_inputs, **kwargs)File “/home/ma-user/work/bert_model.py”, line 852, in constructword_embeddings)File “/home/ma-user/miniconda3/envs/Mindspore-1.1.1-python3.7-aarch64/lib/python3.7/site-packages/mindspore/nn/cell.py”, line 351, in calloutput = self.construct(*cast_inputs, **kwargs)File “/home/ma-user/work/bert_model.py”, line 203, in constructoutput = self.dropout(output)File “/home/ma-user/miniconda3/envs/Mindspore-1.1.1-python3.7-aarch64/lib/python3.7/site-packages/mindspore/nn/cell.py”, line 351, in calloutput = self.construct(*cast_inputs, **kwargs)File “/home/ma-user/miniconda3/envs/Mindspore-1.1.1-python3.7-aarch64/lib/python3.7/site-packages/mindspore/nn/layer/basic.py”, line 157, in constructout, _ = self.dropout(x)File “/home/ma-user/miniconda3/envs/Mindspore-1.1.1-python3.7-aarch64/lib/python3.7/site-packages/mindspore/ops/primitive.py”, line 186, in callreturn _run_op(self, self.name, args)File “/home/ma-user/miniconda3/envs/Mindspore-1.1.1-python3.7-aarch64/lib/python3.7/site-packages/mindspore/common/api.py”, line 75, in wrapperresults = fn(*arg, **kwargs)File “/home/ma-user/miniconda3/envs/Mindspore-1.1.1-python3.7-aarch64/lib/python3.7/site-packages/mindspore/ops/primitive.py”, line 525, in _run_opoutput = real_run_op(obj, op_name, args)RuntimeError: mindspore/ccsrc/runtime/device/ascend/ascend_device_address.cc:279 SyncStream] Sync stream error! 未能定位异常的原因,目前的解决办法是drop掉不足batch_size大小的batch,即令drop_remainder为True。data_set.batch(batch_size, drop_remainder=True)  2、由于Ascend芯片矩阵运算的设计,需要和16对齐的问题我开发的模型主要是对BERT进行微调,去完成分类任务,其中有一个数据集为udc数据集,原论文提供的max_seq_len为210,考虑到Ascend对16对齐有要求,于是作了udc数据集使用不同max_seq_len在Ascend910芯片上进行训练推理的对比,如表所示 结果表明,224和256都是16的倍数,而210不是,从训练性能和推理性能的对比可以看出,使用16对齐的max_seq_len在Ascend 910芯片上无论是训练还是推理,相比不对齐的情况,性能有很大的提升,因此大家如果有相似的情况,可以考虑是否与16对齐有关。 224的性能与精度表现都较好,因此采用224作为训练用的max_seq_len,并且在Ascend910上使用MindSpore进行模型开发,与论文基准精度(paddle实现)相比,性能、精度均有提高。3、使用FileWriter保存的mindrecord文件重命名后报错无法使用重现问题的步骤使用FileWriter保存mindrecord文件重命名mindrecord文件训练模型时读取重命名后的mindrecord文件报错信息[ERROR] MD(151,python):2021-03-24-22:41:54.507.733 [mindspore/ccsrc/minddata/mindrecord/io/shard_reader.cc:126] Init] Invalid file, DB file can not match file: /cache/data/udc/udc_train.mindrecord[ERROR] CORE(151,python):2021-03-24-22:41:54.507.824 [mindspore/core/utils/status.cc:43] Status] Thread ID 281473654276112 Unexpected error. Invalid data, MindRecordOp failed to count total rows.Line of code : 455File : /home/jenkins/agent-working-dir/workspace/Compile_Ascend_ARM_EulerOS/mindspore/mindspore/ccsrc/minddata/dataset/engine/datasetops/source/mindrecord_op.ccTraceback (most recent call last):File "/home/work/user-job-dir/push/run_dgu.py", line 233, inrun_dgu(args_opt)File "/home/work/user-job-dir/push/run_dgu.py", line 154, in run_dgudo_train(train_ds, netwithloss, load_pretrain_checkpoint_path, save_finetune_checkpoint_path, epoch_num)File "/home/work/user-job-dir/push/run_dgu.py", line 54, in do_trainnum_examples = dataset.get_dataset_size() * args_opt.train_batch_sizeFile "/usr/local/ma/python3.7/lib/python3.7/site-packages/mindspore/dataset/engine/datasets.py", line 1456, in get_dataset_sizeself.dataset_size = runtime_getter[0].GetDatasetSize(False)RuntimeError: Thread ID 281473654276112 Unexpected error. Invalid data, MindRecordOp failed to count total rows.提了issue后得到的反馈如下:这个是因为MindRecord设计的时候:其内部保存了包含文件名在内的元数据(如:文件名、Schema、Page大小等)信息,训练样本保存在数据文件中(如:train.mindrecord),另一个*.db(如:train.mindrecord.db)是其索引文件,两者有一一对应的关系,如果改动了文件名,会导致这中间的对应关系丢失/找到不索引文件。train.mindrecord train.mindrecord.db且支持用户通过FileWriter指定shard_num=N来自动将用户的数据集分成多个文件,如分成4个mindrecord文件;train0.mindrecord train0.mindrecord.db train1.mindrecord train1.mindrecord.dbtrain2.mindrecord train2.mindrecord.db train3.mindrecord train3.mindrecord.db其中 train0.mindrecord, train1.mindrecord, train2.mindrecord, train3.mindrecord文件名会存储在元数据中,表名这4个文件属于同一个数据集,在用MindDataset加载其中一个的时候,会把4个同时加载进来,如果改动了文件名,那么这4个mindrecord文件的对应关系就丢失了,也会导致加载失败。issue地址:https://gitee.com/mindspore/mindspore/issues/I3D4BQ