原文:zh.annas-archive.org/md5/9aaa43d610032843316e1bd6be920e64

译者:飞龙

协议:CC BY-NC-SA 4.0

第五章:激活文本分类:利用传统机器学习技术

在本章中,我们将深入探讨文本分类的迷人世界,这是自然语言处理(NLP)和机器学习(ML)的基础任务,涉及将文本文档分类到预定义的类别中。随着数字文本数据量的指数级增长,准确且高效地分类文本的能力对于广泛的应用变得越来越重要,例如情感分析、垃圾邮件检测和文档组织。本章为来自不同背景和技能水平的读者提供了一个关于文本分类中使用的核心概念、方法和技术的全面概述。

我们将首先探讨各种文本分类任务的类型及其独特特征,提供对每种类型所面临的挑战和机遇的见解。接下来,我们将介绍N-gram的概念,并讨论它们如何作为文本分类的特征被利用,不仅捕捉单个单词,还捕捉文本中的局部上下文和单词序列。然后,我们将研究广泛使用的词频-逆文档频率TF-IDF)方法,该方法根据单词在文档中的频率和在整个语料库中的频率分配权重,展示了其在区分分类任务中相关单词方面的有效性。

随后,我们将深入研究强大的Word2Vec算法及其在文本分类中的应用。我们将讨论Word2Vec如何创建捕获语义意义和关系的密集向量表示,以及这些嵌入如何作为特征来提高分类性能。此外,我们还将介绍如连续词袋模型CBOW)和 Skip-Gram 等流行架构,提供对它们内部工作原理的更深入理解。

最后,我们将探讨主题建模的概念,这是一种在文档集合中揭示隐藏主题结构的技巧。我们将研究如潜在狄利克雷分配LDA)等流行算法,并描述主题建模如何应用于文本分类,从而发现文档之间的语义关系并提高分类性能。

在本章中,我们旨在提供对文本分类中使用的潜在概念和技术的深入理解,为您提供解决现实世界文本分类问题的知识和技能。

本章将涵盖以下主题:

  • 文本分类的类型

  • 基于 N-gram 的文本分类

  • 基于 TF-IDF 的文本分类

  • Word2Vec 及其在文本分类中的应用

  • 主题建模

  • 回顾我们的用例 - 在 Jupyter 笔记本中为 NLP 分类设计的机器学习系统

技术要求

为了有效地阅读和理解这一章,对各种技术领域的坚实基础是必不可少的。对NLP、ML和线性代数的基本概念有深刻的理解至关重要。熟悉文本预处理技术,如分词、停用词去除以及词干提取或词形还原,对于理解数据准备阶段是必要的。

此外,理解基本的ML算法,如逻辑回归和支持向量机SVMs),对于实现文本分类模型至关重要。最后,熟悉评估指标,如准确率、精确率、召回率和F1分数,以及过拟合、欠拟合和超参数调整等概念,将有助于更深入地理解文本分类中的挑战和最佳实践。

文本分类的类型

文本分类是一个NLP任务,其中ML算法根据文本的内容将其分配到预定义的类别或标签。它涉及在标记数据集上训练一个模型,以便它能够准确预测未见或新的文本输入的类别。文本分类方法可以分为三种主要类型——监督学习无监督学习半监督学习

  • 监督学习:这种文本分类涉及在标记数据上训练模型,其中每个数据点都与一个目标标签或类别相关联。然后,该模型使用这些标记数据来学习输入文本和目标标签之间的模式和关系。文本分类的监督学习算法示例包括朴素贝叶斯、SVMs以及卷积神经网络(CNNs)和循环神经网络(RNNs)等神经网络。

  • 无监督学习:这种文本分类涉及将文本文档聚类或分组到类别或主题中,而不需要任何关于类别或标签的先验知识。当没有可用的标记数据或当类别或主题的数量未知时,无监督学习非常有用。文本分类的无监督学习算法示例包括K-means聚类、LDA和层次狄利克雷过程HDP)。

  • 半监督学习:这种文本分类结合了监督学习和无监督学习的方法。它涉及使用少量标记数据来训练模型,然后使用该模型来分类剩余的无标签数据。然后,该模型使用无标签数据来提高其分类性能。当标记数据稀缺或难以获得时,半监督学习非常有用。文本分类的半监督学习算法示例包括自训练协同训练多视角学习

这些文本分类类型各有其优势和劣势,适用于不同类型的应用。了解这些类型有助于为特定问题选择适当的方法。在以下小节中,我们将详细解释这些方法。

监督学习

监督学习是一种机器学习类型,其中算法从标注数据中学习以预测新、未见数据的标签。

在文本分类的背景下,监督学习涉及在标注数据集上训练模型,其中每个文档或文本样本都被标注为相应的类别或类别。然后,该模型使用这些训练数据来学习文本特征与其相关标签之间的模式和关系:

  1. 在监督文本分类任务中,第一步是获取一个标注数据集,其中每个文本样本都被标注为相应的类别或类别。

    标注数据集被认为具有最高可靠性。通常,它是通过让主题专家手动审查文本并为每个项目分配适当的类别来获得的。在其他情况下,可能存在用于生成标签的自动化方法。例如,在网络安全领域,你可能收集历史数据然后分配标签,这些标签可能收集每个项目之后的成果——也就是说,该操作是否合法。由于大多数领域都存在此类历史数据,因此这些数据也可以作为可靠的标注集。

  2. 下一步是对文本数据进行预处理,以准备建模。这可能包括诸如分词、词干提取或词形还原、去除停用词以及其他文本预处理技术。

  3. 在预处理之后,文本数据被转换为数值特征,通常使用诸如词袋模型或TF-IDF编码等技术。

  4. 然后,使用这些数值特征在标注数据集上训练监督学习算法,如逻辑回归、SVM或神经网络。

一旦模型被训练,就可以使用它来根据学习到的文本特征与其相关标签之间的模式和关系来预测新、未见文本数据的类别或类别。

监督学习算法通常用于文本分类任务。让我们看看一些常用的用于文本分类的监督学习算法。

朴素贝叶斯

朴素贝叶斯是一种概率算法,常用于文本分类。它基于贝叶斯定理,该定理表明,给定一些观察到的证据(在这种情况下,文档中的单词),假设(在这种情况下,文档属于特定类别)的概率与证据在假设下给出的概率成正比,乘以假设的先验概率。朴素贝叶斯假设在类别标签给定的情况下,特征(单词)之间是相互独立的,这也是其名称中“朴素”部分的原因。

逻辑回归

逻辑回归是一种用于二元分类问题(即只有两个可能类别的問題)的统计方法。它使用逻辑函数来模拟文档属于特定类别的概率,该函数将任何实值输入映射到0到1之间的值。

SVM

SVM是一种强大的分类算法,在各种应用中使用,包括文本分类。SVM通过找到最佳分离数据的超平面来工作。在文本分类中,特征通常是文档中的词语,而超平面用于将所有可能的文档空间划分为对应不同类别的不同区域。

所有这些算法都可以使用标记数据进行训练,其中训练集中的每个文档的类别标签都是已知的。一旦训练完成,该模型就可以用来预测新、未标记文档的类别标签。模型的性能通常使用准确率、精确率、召回率和F1分数等指标进行评估。

无监督学习

无监督学习是一种机器学习类型,其中数据未标记,算法被留给自行寻找模式和结构。在文本分类的背景下,当没有标记数据可用或目标是发现文本数据中的隐藏模式时,可以使用无监督学习方法。

一种常见的用于文本分类的无监督学习方法是聚类。聚类算法根据文档的内容将相似的文档分组在一起,而不需要任何关于每个文档内容的先验知识。聚类可以用来识别文档集合中的主题,或将相似的文档分组在一起进行进一步分析。

另一种流行的用于文本分类的无监督学习算法是LDA。LDA是一种概率生成模型,假设语料库中的每个文档都是主题的混合,每个主题是词语的概率分布。LDA可以用来发现文档集合中的潜在主题,即使主题没有明确标记。

最后,词嵌入是一种流行的无监督学习技术,用于文本分类。词嵌入是词语的密集向量表示,根据它们出现的上下文捕获其语义意义。它们可以用来识别相似词语,并找出词语之间的关系,这对于文本相似性和推荐系统等任务可能很有用。常见的词嵌入模型包括Word2Vec和GloVe。

Word2Vec是一种流行的算法,用于生成词嵌入,即在高维空间中词语的向量表示。该算法由Google的研究团队在2013年开发,由Tomas Mikolov领导。Word2Vec背后的主要思想是,在相似上下文中出现的词语往往具有相似的意义。

该算法以大量文本语料库作为输入,并为词汇表中的每个单词生成一个向量表示。这些向量通常是高维的(例如,100或300维),可用于执行各种NLP任务,如情感分析、文本分类和机器翻译。

Word2Vec使用了两种主要架构:CBOWskip-gram。在CBOW架构中,算法试图根据上下文单词的窗口预测目标词。在skip-gram架构中,算法试图根据目标词预测上下文词。训练目标是最大化目标词或上下文词在给定输入下的可能性。

Word2Vec在NLP社区中得到广泛应用,并在各种基准测试中显示出最先进的性能。它也被用于许多实际应用中,如推荐系统、搜索引擎和聊天机器人。

半监督学习

半监督学习是介于监督学习和无监督学习之间的机器学习范式。它利用标记数据和未标记数据的组合进行训练,这在底层模型需要昂贵或耗时的标记数据时特别有用。这种方法允许模型利用未标记数据中的信息来提高其在分类任务上的性能。

在文本分类的背景下,当我们拥有有限的标记文档但大量未标记文档时,半监督学习可以是有益的。目标是利用未标记数据中包含的信息来提高分类器的性能。

有几种常见的半监督学习算法,包括标签传播和Co-training。我们将在下一节中更详细地讨论这些算法。

Label propagation

Label propagation是一种基于图的半监督学习算法。它使用标记和未标记数据点构建一个图,每个数据点表示为一个节点,边表示节点之间的相似性。该算法通过根据它们的相似性从标记节点传播标签到未标记节点来工作。

关键思想是相似的数据点应该有相似的标签。算法首先为未标记的节点分配初始标签概率,通常基于它们与标记节点的相似性。然后,一个迭代过程将把这些概率传播到整个图中,直到收敛。最终的标签概率用于对未标记的数据点进行分类。

Co-training

Co-training 是另一种半监督学习技术,它在数据的不同视角上训练多个分类器。视角是特征的一个子集,对于学习任务来说是足够的,并且给定类别标签时是条件独立的。基本思想是使用一个分类器的预测来标记一些未标记的数据,然后使用这些新标记的数据来训练另一个分类器。这个过程是迭代进行的,每个分类器通过改进另一个分类器来提高性能,直到满足停止条件。

要在特定领域应用半监督学习,让我们考虑一个医学领域,我们希望将科学文章分类到不同的类别中,例如心脏病学神经病学肿瘤学。假设我们有一小部分标记的文章和一大群未标记的文章。

一种可能的方法是创建一个文章图,其中节点代表文章,边代表文章之间的相似性。相似性可以基于各种因素,例如使用的单词、覆盖的主题或文章之间的引用网络。在传播标签后,我们可以根据最终的标签概率对未标记的文章进行分类。

或者,我们可以通过将特征分为两个视角来使用 co-training,例如文章的摘要和全文。我们将训练两个分类器,每个视角一个,并迭代地使用另一个分类器在未标记数据上的预测来更新分类器。

在这两种情况下,目标都是利用未标记数据中的信息来提高特定领域的分类器性能。

在本章中,我们将详细阐述监督文本分类和主题建模。

使用 one-hot 编码向量表示进行句子分类

One-hot 编码向量表示是一种表示分类数据(如单词)为二进制向量的方法。在文本分类的上下文中,one-hot 编码可以用来将文本数据表示为分类模型的数值输入特征。以下是使用 one-hot 编码向量进行文本分类的详细解释。

文本预处理

第一步是预处理文本数据,如前一章所述。预处理的主要目标是将原始文本转换为更结构化和一致的格式,以便机器学习算法可以轻松理解和处理。以下是文本预处理对于 one-hot 编码向量分类的几个原因:

  • 噪声减少:原始文本数据通常包含噪声,例如拼写错误、拼写错误、特殊字符和格式不一致。预处理有助于清理文本,减少可能对分类模型性能产生负面影响的噪声。

  • 降维:one-hot 编码向量表示具有高维度,因为数据集中每个唯一的单词对应一个单独的特征。预处理技术,如停用词去除、词干提取或词形还原,可以帮助减少词汇表的大小,从而降低特征空间的维度。这可以提高分类算法的效率并降低过拟合的风险。

  • 一致的表示:将所有文本转换为小写并应用词干提取或词形还原确保具有相同意义或词根形式的单词在 one-hot 编码向量中保持一致表示。这可以帮助分类模型从数据中学习到更有意义的模式,因为它不会将同一单词的不同形式视为不同的特征。

  • 处理无关信息:预处理可以帮助移除无关信息,如 URL、电子邮件地址或数字,这些信息可能不会对分类任务做出贡献。移除此类信息可以提高模型专注于文本中有意义单词和模式的能力。

  • 提高模型性能:预处理文本数据可以提高分类模型的表现,因为模型将从更干净、更有结构的数据集中学习。这可能导致准确率的提高以及对新、未见文本数据的泛化能力。

一旦我们预处理完文本,我们就可以开始提取文本中的单词了。我们称这个任务为词汇构建。

词汇构建

构建一个包含预处理文本中所有唯一单词的词汇表。为词汇表中的每个单词分配一个唯一的索引。

词汇构建是准备文本数据以进行 one-hot 编码向量分类的一个关键步骤。词汇是预处理文本数据中所有唯一单词(标记)的集合。它作为创建每个文档的 one-hot 编码特征向量的基础。以下是 one-hot 编码向量分类的词汇构建过程的详细说明:

  1. 创建一组唯一单词:在预处理文本数据后,从所有文档中收集所有单词并创建一组唯一单词。这个集合将代表词汇表。词汇表中单词的顺序不重要,但必须跟踪分配给每个单词的索引,因为它们将用于稍后创建 one-hot 编码向量。

    例如,考虑以下预处理数据集由两个文档组成:

    • 文档 1: “apple banana orange”

    • 文档 2: “banana grape apple”

    该数据集的词汇表将是 {“apple”, “banana”, “orange”, “grape”}。

  2. 为单词分配索引:一旦你有了唯一单词的集合,为词汇表中的每个单词分配一个唯一的索引。这些索引将用于创建每个文档的 one-hot 编码向量。

    使用前面的示例,你可能分配以下索引:

    • “apple”:0

    • “banana”:1

    • “orange”:2

    • “grape”:3

One-hot 编码

使用构建的词汇表和分配的索引,你现在可以为数据集中的每个文档创建独热编码的向量。创建独热编码向量的一个简单方法就是使用词袋模型。对于文档中的每个单词,找到它在词汇表中的对应索引,并在独热编码向量中设置该索引的值为 1。如果一个单词在文档中多次出现,其在独热编码向量中的对应值仍然为 1。向量中的所有其他值都将为 0。

例如,使用之前提到的词汇表和索引,文档的独热编码向量如下所示:

  • 文档 1: [1, 1, 1, 0](存在苹果、香蕉和橙子)

  • 文档 2: [1, 1, 0, 1](存在苹果、香蕉和葡萄)

一旦我们得到了每个文档对应的值,我们就可以创建一个特征矩阵,其中以独热编码的向量作为行,每一行代表一个文档,每一列代表词汇表中的一个单词。这个矩阵将被用作文本分类模型的输入。例如,在之前的例子中,两个文档的特征向量如下所示:

苹果 香蕉 橙子 葡萄
文档 1 1 1 1 0
文档 2 1 1 0 1

表 5.1 – 两个文档的样本独热编码向量

请注意,通过文本预处理,拥有一个更小的词汇表有助于提高模型性能。此外,如果需要,我们可以在提取的特征向量上执行特征选择方法(如本书之前所述),以提高我们的模型性能。

虽然从单词创建独热编码向量很有用,但有时我们需要考虑两个单词相邻的存在。例如,“非常好”和“不好”可能有不同的含义。为了达到这个目标,我们可以使用 N-grams。

N-grams

N-grams 是 bag-of-words 模型的一种推广,它通过考虑连续的 n 个单词的顺序来考虑单词的顺序。N-gram 是从给定文本中连续的 n 个项目(通常是单词)的序列。例如,在句子“The cat is on the mat”中,2-grams(双词)将是“The cat”,“cat is”,“is on”,“on the”,和“the mat”。

使用 N-grams 可以帮助捕捉局部上下文和单词关系,这可能会提高分类器的性能。然而,它也增加了特征空间的维度,这可能会在计算上变得昂贵。

模型训练

在特征矩阵上训练一个机器学习模型,如逻辑回归、SVM 或神经网络,以学习独热编码文本特征与目标标签之间的关系。该模型将学会根据文档中特定单词的存在与否来预测类别标签。一旦我们决定了训练过程,我们需要执行以下任务:

  • 模型评估:使用适当的评估指标评估模型性能,例如准确率、精确率、召回率、F1分数或混淆矩阵,并使用交叉验证等技术来获得模型在未见数据上的可靠性能估计。

  • 模型应用:将训练好的模型应用于新的、未见过的文本数据。使用相同的词汇表对新的文本数据进行预处理和独热编码,然后使用模型预测类别标签。

使用独热编码向量进行文本分类的一个潜在局限性是它们没有捕捉到单词顺序、上下文或单词之间的语义关系。这可能导致性能不佳,尤其是在更复杂的分类任务中。在这种情况下,更高级的技术,如词嵌入(例如Word2Vec或GloVe)或深度学习模型(例如CNNs或RNNs),可以提供更好的文本数据表示。

总结来说,使用独热编码向量进行文本分类涉及预处理文本数据、构建词汇表、将文本数据表示为独热编码特征向量、在特征向量上训练机器学习模型,以及评估和应用模型到新的文本数据。独热编码向量表示是一种简单但有时有限的文本分类方法,对于复杂任务可能需要更高级的技术。

到目前为止,我们已经学习了使用N-gram对文档进行分类。然而,这种方法有一个缺点。文档中频繁出现的大量单词并不增加我们模型的价值。为了改进模型,已经提出了使用TF-IDF进行文本分类的方法。

使用TF-IDF进行文本分类

独热编码向量是进行分类的好方法。然而,它的一个弱点是它没有考虑不同文档中不同单词的重要性。为了解决这个问题,使用TF-IDF可能会有所帮助。

TF-IDF是一种数值统计量,用于衡量一个词在文档集合中相对于整个文档集合的重要性。它有助于反映文档中单词的相关性,不仅考虑了单词在文档中的频率,还考虑了单词在整个文档集合中的稀有度。一个词的TF-IDF值与其在文档中的频率成正比,但会因该词在整个文档集合中的频率而抵消。

下面是计算TF-IDF所涉及的数学公式的详细解释:

  • 词频(TF):一个词t在文档d中的TF表示该词在文档中出现的次数,除以文档中单词的总数。TF可以使用以下公式计算:

https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/259.png

TF 衡量一个单词在特定文档中的重要性。

  • 逆文档频率(IDF):单词 t 的 IDF 反映了该单词在整个文档集合中的稀有度。IDF 可以使用以下公式计算:

    IDF(t) = log ((集合中文档的总数) / (包含单词′t′的文档数))

    对数用于减弱 IDF 成分的效应。如果一个单词在许多文档中出现,其 IDF 值将更接近 0,而如果一个单词在较少的文档中出现,其 IDF 值将更高。

  • TF-IDF 计算:文档中单词 t 的 TF-IDF 值可以通过将文档中该单词的 TF 与整个文档集合中该单词的 IDF 相乘来计算:

https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/260.png

结果的 TF-IDF 值表示一个单词在文档中的重要性,同时考虑其在文档中的频率和在整个文档集合中的稀有度。高 TF-IDF 值表示在特定文档中更重要的单词,而低 TF-IDF 值表示在所有文档中都很常见或在特定文档中很罕见的单词。

让我们考虑一个简单的例子,将电影评论分为两类:正面和负面。我们有一个包含三个电影评论及其相应标签的小数据集,如下所示:

  • 文档 1(正面):“我喜欢这部电影。表演很棒,故事很吸引人。”

  • 文档 2(负面):“这部电影很无聊。我不喜欢这个故事,表演也很糟糕。”

  • 文档 3(正面): “一部令人惊叹的电影,拥有精彩的故事和出色的表演。”

现在,我们将使用TF-IDF对一篇新的、未见过的电影评论进行分类:

  • 文档 4(未知): “故事很有趣,表演也很出色。”

这里是我们需要执行的步骤,以便让分类器预测我们文档的类别:

  1. 步骤 1 – 预处理文本数据:对所有文档中的单词进行分词、转换为小写、去除停用词,并应用词干提取或词形还原:

    • 文档 1: “love movi act great stori captiv”

    • 文档 2: “movi bore not like stori act terribl”

    • 文档 3: “amaz movi wonder stori brilliant act”

    • 文档 4: “stori interest act good”

  2. 步骤 2 – 创建词汇表:将预处理文档中的所有唯一单词合并:

    词汇表:{“love”, “movi”, “act”, “great”, “stori”, “captiv”, “bore”, “not”, “like”, “terribl”, “amaz”, “wonder”, “brilliant”, “interest”, “good”}

  3. 步骤 3 – 计算TF和IDF值:计算每个文档中每个单词的TF和IDF。

    例如,对于文档 4 中的单词“stori”,我们有以下内容:

https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/261.png

https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/262.png

  1. 步骤 4 – 计算TF-IDF值:计算每个文档中每个单词的TF-IDF值。

https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/263.png

对所有文档中的所有单词重复此过程,并创建一个包含TF-IDF值的特征矩阵。

  1. 步骤 5 – 训练分类器:将数据集分为训练集(文档 1 到 3)和测试集(文档 4)。使用训练集的TF-IDF特征矩阵及其相应的标签(正面或负面)来训练一个分类器,例如逻辑回归或SVM。

  2. 步骤 6 – 预测类别标签:使用相同的词汇对新的电影评论(文档 4)进行预处理和计算 TF-IDF 值。使用训练好的分类器根据文档 4 的 TF-IDF 特征向量预测其类别标签。

例如,如果分类器预测文档 4 为正面标签,分类结果如下:

  • 文档 4(预测:“正面”

通过遵循这些步骤,您可以使用 TF-IDF 表示来根据文档中相对于整个文档集合的词的重要性对文本文档进行分类。

总结来说,TF-IDF 值是通过 TF 和 IDF 的数学公式计算得出的。它作为衡量一个词在文档中相对于整个文档集合重要性的指标,同时考虑了该词在文档中的频率以及在整个文档中的稀有度。

使用 Word2Vec 进行文本分类

执行文本分类的一种方法是将词转换为嵌入向量,以便可以使用这些向量进行分类。Word2Vec 是执行此任务的一种知名方法。

Word2Vec

Word2Vec 是一组基于神经网络的模型,用于创建词嵌入,这些嵌入是词在连续向量空间中的密集向量表示。这些嵌入根据词在文本中出现的上下文捕获词的语义意义和关系。Word2Vec 有两种主要架构。如前所述,设计用来学习词嵌入的两种主要架构是 CBOWskip-gram。两种架构都是通过预测周围上下文中的词来学习词嵌入的:

  • CBOW:CBOW 架构旨在根据周围上下文词预测目标词。它以上下文词嵌入的平均值作为输入,并预测目标词。CBOW 训练速度快,适用于小型数据集,但对于不常见的词可能不够准确。

    在 CBOW 模型中,目标是最大化观察目标词给定上下文词的平均对数概率:

https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/264.png

这里,T 是文本中的总词数,P(target | context) 是在给定上下文词的情况下观察目标词的概率,它使用 softmax 函数计算:

https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/265.png

这里,https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/266.png 是目标词的输出向量(词嵌入),https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/267.png 是上下文词的平均输入向量(上下文词嵌入),分母中的求和遍历了词汇表中的所有词。

  • Skip-gram:skip-gram 架构旨在根据目标词预测周围的上下文词。它以目标词嵌入作为输入并预测上下文词。Skip-gram 在大型数据集上表现良好,并能更准确地捕捉不常见词的意义,但与 CBOW 相比,它可能训练速度较慢。

    在 skip-gram 模型中,目标是最大化在给定目标词的情况下观察上下文词的平均对数概率:

https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/268.png

在这里,T 是文本中的总单词数,P(context | target) 是在给定目标词的情况下观察上下文词的概率,该概率使用 softmax 函数计算:

https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/269.png

在这里,https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/270.png是上下文词的输出向量(上下文词嵌入),https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/271.png是目标词的输入向量(词嵌入),分母中的求和遍历词汇表中的所有词。

CBOW和skip-gram的训练过程都涉及遍历文本,并使用随机梯度下降SGD)和反向传播来更新输入和输出权重矩阵,以最小化预测词和实际词之间的差异。学习到的输入权重矩阵包含词汇表中每个词的词嵌入。

使用Word2Vec进行文本分类

使用Word2Vec进行文本分类涉及使用Word2Vec算法创建词嵌入,然后训练一个机器学习模型来根据这些嵌入对文本进行分类。以下步骤详细概述了该过程,包括数学方面:

  1. 文本预处理:通过分词、小写化、去除停用词以及词干提取或词形还原来清洁和预处理文本数据。

  2. 训练Word2Vec模型:在预处理后的文本数据上训练一个Word2Vec模型(无论是CBOW还是Skip-Gram),以创建词嵌入。Word2Vec算法学习根据上下文(CBOW)预测目标词,或者根据目标词预测上下文词(skip-gram)。训练目标是最大化在给定目标词的情况下观察上下文词的平均对数概率:

https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/272.png

在这里,T 是文本中的总单词数,P(context | target) 是在给定目标词的情况下观察上下文词的概率,这使用softmax函数来计算:

https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/273.png

在这里,https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/274.png是上下文词的输出向量(上下文词嵌入),https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/275.png是目标词的输入向量(词嵌入),分母中的求和遍历了词汇表中的所有单词。

  1. 创建文档嵌入:对于数据集中的每个文档,通过计算文档中单词的词嵌入的平均值来计算文档嵌入:

https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/276.png

在这里,N是文档中的单词数量,求和遍历文档中的所有单词。请注意,根据我们的经验,使用Word2Vec进行文本分类的方法仅在文档长度较短时才有效。如果你有较长的文档或文档中有相反的词语,这种方法表现不佳。一个替代方案是将Word2Vec和CNN结合使用来获取词嵌入,然后将这些嵌入作为CNN的输入。

  1. 模型训练:使用文档嵌入作为特征来训练一个机器学习模型,如逻辑回归、SVM或神经网络,用于文本分类。该模型学习根据文档嵌入预测类别标签。

  2. 模型评估:使用适当的评估指标(如准确率、精确率、召回率、F1分数或混淆矩阵)评估模型的性能,并使用交叉验证等技术来获得模型在未见数据上的可靠性能估计。

  3. 模型应用:将训练好的模型应用于新的、未见过的文本数据。使用相同的Word2Vec模型和词汇表对新的文本数据进行预处理和计算文档嵌入,并使用该模型预测类别标签。

总结来说,使用Word2Vec进行文本分类涉及使用Word2Vec算法创建词嵌入,平均这些嵌入以创建文档嵌入,并训练一个机器学习模型根据这些文档嵌入对文本进行分类。Word2Vec算法通过最大化观察给定目标词的上下文词的平均对数概率来学习词嵌入,在这个过程中捕捉词语之间的语义关系。

模型评估

评估文本分类模型的性能对于确保它们达到期望的准确性和泛化水平至关重要。通常使用多种指标和技术来评估文本分类模型,包括准确率、精确率、召回率、F1分数和混淆矩阵。让我们更详细地讨论这些指标:

  • 准确性:准确性是分类任务中最直接的指标。它衡量所有分类记录中正确分类的记录数量。它被定义为如下:

https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/277.png

虽然准确性容易理解,但它可能不是不平衡数据集的最佳指标,因为在不平衡数据集中,多数类可以主导指标的值。

  • 精确度:精确度衡量正确识别的正例与模型预测为正的总实例的比例。它也被称为阳性预测值PPV)。在关联到错误正例成本较高的场景中,精确度非常有价值。精确度被定义为如下:

[[OMML-EQ-21D]]

  • 召回率:召回率,也称为灵敏度或真正例率TPR),评估正确识别的正例与总实际正例的比例。当错误负例的成本很高时,召回率非常有用。数学上,它被定义为如下:

[[OMML-EQ-22D]]

  • F1 分数:F1 分数是精确度和召回率的调和平均值,将这两个指标整合为一个统一的价值。在不平衡数据集的上下文中,它是一个重要的指标,因为它考虑了错误正例和错误负例。F1 分数从 0 到 1 变化,1 代表最佳结果,F1 分数的数学表达式如下:

https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/278.png

当处理多类分类问题时,我们有F1微平均和F1宏平均。F1微平均和F1宏平均是计算多类或多标签分类问题F1分数的两种方法。它们以不同的方式聚合精确度和召回率,导致对分类器性能的不同解释。让我们更详细地讨论每种方法:

  • F1宏平均:F1宏平均独立计算每个类的F1分数,然后取这些值的平均值。这种方法将每个类视为同等重要,不考虑类不平衡。从数学上讲,F1宏平均定义为以下:

https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/279.png

在这里,n 是类的数量,而 https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/280.png 是第i个类的F1分数。

F1宏平均特别适用于当你想要评估分类器在所有类上的性能而不给多数类赋予更多权重时。然而,当类分布高度不平衡时,它可能不适用,因为它可能会提供一个过于乐观的模型性能估计。

https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/282.png

https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/283.png

F1 微型评估器在您希望评估分类器的整体性能并考虑类别分布时非常有用,尤其是在处理不平衡数据集时。

总结来说,F1宏平均和F1微平均是计算多类或多标签分类问题F1分数的两种方法。F1宏平均将每个类别视为同等重要,不考虑类别分布,而F1微平均通过考虑每个类别的实例数量来考虑类别不平衡。F1宏平均和F1微平均的选择取决于具体问题以及是否将类别不平衡视为一个重要的考虑因素。

混淆矩阵

混淆矩阵作为一种表格形式的表示,展示了分类模型做出的真实阳性、真实阴性、假阳性和假阴性预测的数量。这个矩阵提供了对模型有效性的细致视角,使得可以全面理解其优势和劣势。

对于二元分类问题,混淆矩阵的排列如下:

实际/预测 (预测) 阳性 (预测) 阴性
(实际) 阳性 真阳性 假阴性
(实际) 阴性 假阳性 真阴性

表5.2 – 混淆矩阵 – 通用视图

对于多类分类问题,混淆矩阵扩展到包括每个类别的真实和预测计数。对角线元素代表正确分类的实例,而偏对角线元素代表错误分类。

总结来说,评估文本分类模型涉及使用各种指标和技术,如准确率、精确率、召回率、F1分数和混淆矩阵。选择适当的评估指标取决于具体问题、数据集特征以及假阳性和假阴性之间的权衡。使用多个指标评估模型可以提供对其性能的更全面理解,并有助于指导进一步的改进。

过拟合和欠拟合

过拟合和欠拟合是机器学习模型训练过程中,包括文本分类模型训练中常见的两个问题。它们都与模型对新、未见数据的泛化能力有关。本节将解释过拟合和欠拟合的发生情况以及如何防止它们。

过拟合

过拟合发生在模型过度适应训练数据的复杂性时。在这种情况下,模型捕捉到噪声和随机波动,而不是辨别基本模式。因此,尽管模型可能在训练数据上表现出高性能,但当应用于未见数据(如验证集或测试集)时,其有效性会降低。

为了避免文本分类中的过拟合,可以考虑以下策略:

  • 正则化:引入正则化技术,例如 https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/284.pnghttps://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/285.pngL2正则化,这会在损失函数中添加惩罚,从而阻止模型过于复杂。

  • 早停法:在此方法中,我们监控模型在验证集上的性能,一旦验证集上的性能开始变差,即使训练集上的模型性能在提高,我们也停止训练过程。这有助于我们防止过拟合。

  • 特征选择:通过选择最有信息量的特征或使用PCA或LSA等降维技术来减少用于分类的特征数量。

  • 集成方法:通过结合多个模型,例如袋装法或提升法,通过平均它们的预测来减少过拟合。

  • 交叉验证:使用k折交叉验证来获得对未见数据上模型性能的更可靠估计,并相应地微调模型超参数。

接下来,我们将介绍欠拟合问题。

欠拟合

当模型过于简单且无法捕捉数据中的潜在模式时,就会发生欠拟合。因此,模型在训练和测试数据上的性能都较低。模型过于简单,无法表示数据的复杂性,并且无法很好地泛化。

为了避免在文本分类中发生欠拟合,可以考虑以下策略:

  • 增加模型复杂性:使用更复杂的模型,例如更深的神经网络,以捕捉数据中的更复杂模式。

  • 特征工程:创建新的、有信息量的特征,帮助模型更好地理解文本数据中的潜在模式,例如添加N-gram或使用词嵌入。

  • 超参数调整:优化模型超参数,例如学习率、层数或隐藏单元数,以提高模型从数据中学习的能力。我们将在下一节中解释超参数调整以及执行此任务的不同方法。

  • 增加训练数据:如果可能,收集更多标记数据用于训练,因为更多的例子可以帮助模型更好地学习潜在模式。

  • 减少正则化:如果模型过度正则化,考虑减少正则化强度,使模型变得更加复杂,更好地拟合数据。

总结来说,过拟合和欠拟合是文本分类中常见的两个问题,它们会影响模型泛化到新数据的能力。避免这些问题涉及平衡模型复杂性、使用适当的特征、调整超参数、应用正则化和监控模型在验证集上的性能。通过解决过拟合和欠拟合问题,可以提高文本分类模型的表现和泛化能力。

超参数调整

构建一个有效的分类模型的一个重要步骤是超参数调整。超参数是在训练之前定义的模型参数;它们在训练过程中不会改变。这些参数决定了模型架构和行为。可以使用的某些超参数包括学习率和迭代次数。它们可以显著影响模型的表现和泛化能力。

文本分类中超参数调整的过程涉及以下步骤:

  1. 定义超参数及其搜索空间:确定您想要优化的超参数,并指定每个超参数的可能值范围。文本分类中常见的超参数包括学习率、层数、隐藏单元数量、dropout率、正则化强度以及特征提取参数,如N-gram或词汇大小。

  2. 选择搜索策略:选择一种探索超参数搜索空间的方法,例如网格搜索、随机搜索或贝叶斯优化。网格搜索系统地评估所有超参数值的组合,而随机搜索在搜索空间内随机采样组合。贝叶斯优化使用概率模型来指导搜索,根据模型的预测平衡探索和利用。

  3. 选择评估指标和方法:选择一个最能代表您文本分类任务目标的性能指标,例如准确率、精确率、召回率、F1分数或ROC曲线下的面积。同时,选择一个评估方法,如k折交叉验证,以获得模型在未见数据上的性能的可靠估计。

  4. 执行搜索:对于每个超参数值的组合,在训练数据上训练一个模型,并使用所选的指标和评估方法评估其性能。记录最佳性能的超参数组合。

  5. 选择最佳超参数:搜索完成后,选择在评估指标上产生最佳性能的超参数组合。使用这些超参数在整个训练集上重新训练模型。

  6. 在测试集上评估:使用保留的测试集评估最终模型在优化超参数下的性能,以获得其泛化能力的无偏估计。

超参数调整通过找到在所选评估指标上产生最佳模型性能的参数组合来影响模型的性能。调整超参数可以帮助解决诸如过拟合和欠拟合等问题,平衡模型复杂性,并提高模型对新数据的泛化能力。

超参数调整是文本分类中的一个关键过程,涉及在选择的评估指标上搜索最优模型参数组合以最大化性能。通过仔细调整超参数,你可以提高文本分类模型的性能和泛化能力。

应用文本分类的附加主题

在现实世界中,应用文本分类涉及各种实际考虑和挑战,这些挑战源于现实世界数据的性质和问题要求。一些常见问题包括处理不平衡数据集、处理噪声数据和选择合适的评估指标。

让我们更详细地讨论这些内容。

处理不平衡数据集

文本分类任务经常遇到不平衡数据集的问题,其中某些类别的实例数量明显多于其他类别。这种不平衡可能导致模型偏向,擅长预测多数类,但在准确分类少数类方面表现不佳。为了处理不平衡数据集,可以考虑以下策略:

  • 重采样:你可以对少数类进行过采样,对多数类进行欠采样,或者使用两者的组合来平衡类别分布。

  • 加权损失函数:在损失函数中为少数类分配更高的权重,使模型对少数类的误分类更加敏感。

  • 集成方法:使用关注少数类的集成技术,如袋装或提升。例如,你可以使用带有袋装的随机欠采样或成本敏感的提升算法。

  • 评估指标:选择对类别不平衡不那么敏感的评估指标,如精确度、召回率、F1分数或ROC曲线下的面积,而不是准确度。

  • 处理噪声数据:现实世界的文本数据通常很嘈杂,包含拼写错误、语法错误或不相关信息。噪声数据可能会对文本分类模型的性能产生负面影响。

为了处理噪声数据,可以考虑以下策略:

  • 预处理:通过纠正拼写错误、删除特殊字符、扩展缩写词和将文本转换为小写来清洗文本数据。

  • 停用词去除:移除没有太多意义的常见词,例如“the”、“is”、“and”等。

  • 词干提取或词形还原:将单词还原为其基本形式,以最小化形态变化的影响。

  • 特征选择:使用如卡方检验或互信息等技术来选择最有信息量的特征,减少噪声或不相关特征的影响

无论我们是否在处理不平衡数据,我们都需要评估我们的模型,选择合适的指标来评估我们的模型非常重要。接下来,我们将解释如何选择最佳的指标来评估我们的模型。

选择合适的评估指标

选择合适的评估指标对于衡量您的文本分类模型性能和指导模型改进至关重要。

选择评估指标时考虑以下因素:

  • 问题要求:选择与您的文本分类任务具体目标一致的指标,例如最小化误报或误判

  • 类别不平衡:对于不平衡的数据集,使用考虑类别不平衡的指标,如精确率、召回率、F1分数或ROC曲线下的面积,而不是准确率

  • 多类或多标签问题:对于多类或多标签分类任务,使用如微平均和宏平均F1分数等指标,这些指标根据问题的要求以不同的方式聚合精确率和召回率

总结来说,文本分类中的实际考虑因素包括处理不平衡数据集、处理噪声数据以及选择合适的评估指标。解决这些问题可以帮助提高文本分类模型的表现力和泛化能力,并确保它们满足问题的具体要求。

主题建模——无监督文本分类的一个特定用例

主题建模是一种无监督机器学习技术,用于在大量文档集中发现抽象主题或主题。它假设每个文档可以表示为多个主题的混合,每个主题表示为词分布。主题建模的目的是找到潜在的主题及其词分布,以及每个文档的主题比例。

有几种主题建模算法,但其中最受欢迎和最广泛使用的是LDA。我们将详细讨论LDA,包括其数学公式。

LDA

LDA是一种生成概率模型,它假设每个文档的以下生成过程:

  1. 选择文档中的词数。

  2. 从参数α的Dirichlet分布中选择文档的主题分布(θ)。

  3. 对于文档中的每个词,执行以下操作:

    1. 从主题分布(θ)中选择一个主题(z)。

    2. 从所选主题(φ)的词分布中选择一个词(w),该词分布是该主题的词分布,由参数β的Dirichlet分布抽取。

生成过程是LDA(Latent Dirichlet Allocation)用来从假设的主题中逆向工程原始文档的理论模型。

LDA 的目标是找到最佳解释观察到的文档的主题-单词分布 (φ) 和文档-主题分布 (θ)。

从数学上讲,LDA 可以用以下符号描述:

  • M: 文档数量

  • N: 文档中的单词数量

  • K: 主题数量

  • α: 文档-主题分布的 Dirichlet 先验,它影响文档内主题的稀疏性

  • β: 主题-单词分布的 Dirichlet 先验,它影响主题内单词的稀疏性

  • θ: 文档-主题分布(M × K 矩阵)

  • φ: 主题-单词分布(K × V 矩阵,其中 V 是词汇量)

  • z: 每个文档中每个单词的主题分配(M × N 矩阵)

  • w: 文档中观察到的单词(M × N 矩阵)

在给定主题-单词分布 (φ) 和文档-主题分布 (θ) 的情况下,文档中主题分配 (z) 和单词 (w) 的联合概率可以表示如下:

https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/286.png

LDA 的目标是最大化在 Dirichlet 先验 α 和 β 下观察到的单词的概率:

https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/287.png

然而,由于对潜在变量 θ 和 φ 的积分,直接计算似然是不切实际的。因此,LDA 使用近似推理算法,如吉布斯采样或变分推理,来估计后验分布 P(θ | w, α, β) 和 P(φ | w, α, β)。

一旦估计了后验分布,我们就可以获得文档-主题分布(θ)和主题-词分布(φ),这些可以用来分析发现的主题及其词分布,以及每个文档的主题比例。

让我们考虑一个简单的主题建模示例。

假设我们有一组三个文档:

  • 文档 1:“我喜欢和朋友们踢足球。”

  • 文档 2:“足球比赛激烈而兴奋。”

  • 文档 3:“我的新笔记本电脑电池寿命和性能惊人。”

我们希望在这个文档集中发现两个主题(K = 2)。以下是我们需要执行的步骤:

  1. 预处理:首先,我们需要预处理文本数据,这通常涉及分词、停用词去除和词干提取/词形还原(这在本章前面已经解释过)。在这个例子中,为了简单起见,我们将跳过这些步骤,并假设我们的文档已经预处理过。

  2. 初始化:选择狄利克雷先验的初始值 α 和 β。例如,我们可以设置 α = [1, 1] 和 β = [0.1, 0.1, …, 0.1](假设一个 V 维向量,每个词汇的值为 0.1)。

  3. 随机主题分配:随机为每个文档中的每个词分配一个主题(1 或 2)。

  4. 迭代推理(例如,吉布斯采样或变分推理):迭代更新主题分配和主题-词分布以及文档-主题分布(φ 和 θ),直到收敛或达到固定的迭代次数。这个过程细化了分配和分布,最终揭示了潜在的主题结构。

  5. 解释:在算法收敛或达到最大迭代次数后,我们可以通过查看每个主题的最可能词和每个文档的最可能主题来解释发现的主题。

    对于我们的例子,LDA 可能会发现以下主题:

    • 主题 1:{“足球”, “踢球”, “朋友们”, “比赛”, “激烈”, “兴奋”}

    • 主题 2:{“笔记本电脑”, “电池”, “寿命”, “性能”}

    使用这些主题,文档-主题分布(θ)可能看起来像这样:

在这个例子中,主题1似乎与足球和体育相关,而主题2似乎与技术和小工具相关。每个文档的主题分布显示,文档1和2主要关于足球,而文档3是关于技术的。

请注意,这是一个简化的例子,现实世界的数据需要更复杂的预处理和更多的迭代次数以收敛。

我们现在可以讨论在工作和研究环境中构建完整项目的范式。

实际世界中的NLP文本分类机器学习系统设计

本节将专注于我们讨论的各种方法的实际实施。它将围绕Python代码展开,作为完整的管道。

为了提供一个全面的学习体验,我们将讨论典型机器学习项目的整个旅程。图5.1展示了机器学习项目的不同阶段:

https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/B18949_05_1.jpg

图5.1 – 典型机器学习项目的范式

让我们以类似行业典型项目的方式分解这个问题。

商业目标

无论是商业还是研究环境中的机器学习项目,都源于一个原始目标,这个目标通常是定性的而不是技术的。

这里有一个例子:

  1. “我们需要知道哪些患者处于更高的风险。”

  2. “我们希望最大化我们广告的参与度。”

  3. “我们需要自动驾驶汽车在有人走到它前面时发出警报。”

接下来是技术目标。

技术目标

原始目标需要被翻译成技术目标,如下所示:

  1. “我们将处理每位患者的医疗记录,并基于实现风险的历史构建一个风险估计器。”

  2. “我们将收集去年所有广告的数据,并构建一个回归器来根据广告的特征估计参与度水平。”

  3. “我们将收集由汽车前摄像头拍摄的一组图像,并将这些图像展示给访问我们网站的在线用户,告诉他们这是出于安全原因,并且他们需要点击显示人类的区域以证明他们不是机器人。然而,在实践中,我们将收集他们的自由标签用于训练,开发一个用于人类的计算机视觉分类器,而不会给他们任何信用。”

虽然原始的商业或研究目标是一个开放性问题,但技术目标反映了一个可执行的计划。然而,请注意,任何给定的技术目标只是与原始商业或研究目标一致的多项潜在解决方案之一。理解原始目标并将其转化为技术目标是技术权威(如CTO、ML经理或高级开发者)的责任。此外,技术目标可能会在后续阶段进行细化甚至替换。形成技术目标之后的下一步是为其制定计划。

初步的高级系统设计

为了实现技术目标,我们需要制定一个计划来决定哪些数据将被用于输入到ML系统中,以及ML系统的预期输出是什么。在项目的早期阶段,可能会有几个被认为是能够指示所需输出的潜在数据来源。

在前面提到的三个示例之后,以下是一些数据描述的示例:

  1. 输入数据将是patient_records SQL表的A、B和C列,风险将评估为1/N,其中N是从给定时刻到患者在急诊室出现所经过的天数。

  2. 输入数据将是广告的几何和颜色描述,参与度将是广告每天收到的点击次数。

  3. 输入数据是用于输入到计算机视觉神经网络分类器的汽车前摄像头图像,输出数据将是图像是否捕捉到人。

选择度量标准

在定义一个潜在的解决方案方法时,应额外注意确定最佳的度量标准来关注,也称为目标函数或误差函数。这是评估解决方案成功与否的度量标准。将此度量标准与原始的商业或研究目标联系起来是很重要的。

根据前面的示例,我们可能有以下内容:

  1. 最小化70百分位置信区间。

  2. 最小化平均绝对误差。

  3. 在固定召回率的情况下最大化精度。这个固定的召回率理想情况下将由业务领导或法律团队决定,形式为“系统必须至少捕获99.9%的人站在车前的案例。”

现在我们有一个初步的计划,我们可以探索数据并评估设计的可行性。

探索

探索分为两个部分——探索数据和探索设计的可行性。让我们更深入地了解一下。

数据探索

数据并不总是完美适合我们的目标。我们在前面的章节中讨论了一些数据不足之处。特别是,自由文本通常因存在许多异常现象而臭名昭著,如编码、特殊字符、拼写错误等。在探索我们的数据时,我们希望揭露所有这些现象,并确保数据可以被转换成服务于目标的形式。

可行性研究

在这里,我们希望前瞻性地识别计划设计预期成功的代理。虽然对于某些问题有已知的预期成功的代理,但在商业和特别是研究环境中,大多数问题需要大量的经验和独创性来提出初步的成功代理。

一个非常简单的案例是一个只有一个输入变量和一个输出变量的简单回归问题。比如说,自变量是你流媒体服务目前拥有的活跃观众数量,因变量是公司服务器达到最大容量的风险。初步的设计计划将是构建一个估算任何给定时刻风险的回归器。一个成功的回归器可行性的强大代理可能是计算历史数据点的线性相关性。基于样本数据计算线性相关性既简单又快捷,如果其结果接近1(或在我们的业务问题不同的情况下为-1),那么这意味着线性回归器肯定能成功,因此,它是一个很好的代理。然而,请注意,如果线性相关性接近0,这并不一定意味着回归器会失败,只是线性回归会失败。在这种情况下,应该推迟到不同的代理。

回顾我们的用例 - 在Jupyter Notebook中进行NLP分类的机器学习系统设计部分,我们将回顾我们的代码解决方案。我们还将提出一种评估文本分类器可行性的方法。该方法旨在模拟输入文本与输出类别之间的关系。但由于我们希望该方法适用于文本变量而不是数值变量,我们将回到原点,计算输入文本与输出类别之间的统计依赖性度量。统计依赖性是变量之间关系的最基本度量,因此不需要它们中的任何一个必须是数值的。

假设可行性研究成功,我们可以继续实施机器学习解决方案。

实施机器学习解决方案

这部分是机器学习开发者的专业知识发挥作用的环节。对于这一过程有不同的步骤,开发者会根据问题选择哪些步骤是相关的——无论是数据清洗、文本分割、特征设计、模型比较还是指标选择。

我们将在回顾我们已解决的特定用例时详细阐述这一点。

评估结果

我们根据选择的指标来评估解决方案。这部分需要一些经验,因为机器学习开发者通常会随着时间的推移而变得更好。这项任务的主要陷阱是设置结果客观评估的能力。这种客观评估是通过将完成的模型应用于它之前从未“见过”的数据来完成的。但往往那些刚开始应用机器学习的人会发现,在看到保留集的结果后,他们的设计得到了改进。这导致了一个反馈循环,其中设计实际上被调整以适应不再保留的集。虽然这确实可以改进模型和设计,但它削弱了提供模型在现实世界中实施时表现客观预测的能力。在现实世界中,它将看到真正保留且未进行过拟合的数据。

已完成并交付

通常情况下,当设计完成、实施完成,并且结果令人满意时,工作就会呈现在商业实施中,或者在研究环境中,用于发表。在商业环境中,实施可以采取不同的形式。

其中一种最简单的形式是,输出被用来提供业务洞察。其目的是展示。例如,当评估营销活动对销售增长贡献了多少时,机器学习团队可能会计算该贡献度量的估计值,并将其呈现给管理层。

另一种实施形式是在实时仪表板中。例如,模型计算患者进入急诊室的预测风险,并且它每天都会这样做。结果被汇总,并在医院仪表板上展示一个图表,以显示未来30天内每天预计进入急诊室的人数。

一种更高级且更常见的形式是,当数据输出被引导以便可以输入到下游任务中时。然后,模型将在生产中实施,成为更大生产管道中的一个微服务。一个例子是,当分类器评估你公司Facebook页面上每篇帖子时。当它识别出冒犯性语言时,它会输出一个检测信号,然后将其传递到管道中的另一个系统,该系统会删除该帖子并可能阻止该用户。

代码设计

代码的设计应在工作完成后符合代码的目的。根据之前提到的不同实施形式,某些实施要求特定的代码结构。例如,当完成的代码在更大的、已经存在的管道中交付给生产时,生产工程师将决定对机器学习团队的限制。这些限制可能涉及计算和时序资源,但也会涉及代码设计。通常,基本的代码文件,如.py文件,是必要的。

就像代码用于展示的情况一样,例如在展示营销活动贡献性的例子中,Jupyter Notebook 可能是更好的选择。

Jupyter Notebook 可以提供非常丰富和有教育意义的信息。因此,许多机器学习开发者在探索阶段开始他们的项目时,会选择使用 Jupyter Notebook。

接下来,我们将在一个 Jupyter Notebook 中回顾我们的设计。这将使我们能够将整个流程封装在一个单一的连贯文件中,该文件旨在向读者展示。

在 Jupyter Notebook 中回顾我们的用例 – NLP 分类机器学习系统设计

在本节中,我们将通过一个动手示例进行操作。我们将遵循之前提出的步骤来阐述问题、设计解决方案和评估结果。本节描绘了机器学习开发者在行业中的典型项目中所经历的过程。有关更多信息,请参阅笔记本 https://colab.research.google.com/drive/1ZG4xN665le7X_HPcs52XSFbcd1OVaI9R?usp=sharing

商业目标

在这个场景中,我们为一家金融新闻机构工作。我们的目标是实时发布有关公司和产品的新闻。

技术目标

CTO 从商业目标中推导出几个技术目标。其中一个目标是针对机器学习团队的:在实时金融推文流中,检测讨论公司或产品信息的推文。

流程

让我们回顾流程的不同部分,如图 图 5*.2* 所示:

https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/B18949_05_2.jpg

图 5.2 – 典型机器学习流程的结构

注意

图 5*.2* 中的流程阶段将在以下小节中探讨

代码设置

在这部分代码中,我们设置了关键参数。我们选择将它们作为代码的一部分,因为这是一段用于展示的指导性代码。在代码预期用于生产的情况中,可能更好的做法是将参数托管在一个单独的 .yaml 文件中。这也会适应开发阶段的重度迭代,因为它将允许你在不改变代码的情况下迭代不同的代码参数,这通常是期望的。

关于这些值的选择,应该强调的是,其中一些值应该优化以适应解决方案的优化。我们在这里选择了固定度量值以简化过程。例如,用于分类的特征数量在这里是一个固定数量,但它也应该优化以适应训练集。

数据收集

这一部分加载数据集。在我们的案例中,加载函数很简单。在其他商业案例中,这部分可能相当大,因为它可能包括一系列被调用的SQL查询。在这种情况下,可能最好在单独的.py文件中编写一个专用函数,并通过导入部分调用它。

数据处理

在这里,我们以适合我们工作方式格式化数据。我们也首次观察了一些数据。这使我们能够了解其性质和质量。

我们在这里采取的一个关键行动是定义我们关心的类别。

预处理

正如我们在第4章中讨论的那样,预处理是管道的关键部分。例如,我们注意到许多推文中都包含URL,我们选择将其删除。

初步数据探索

在这一点上,我们已经观察了文本的质量和类别的分布。这就是我们探索数据可能的其他特征的地方,这些特征可能意味着其质量或其指示所需类别的能力。

特征工程

接下来,我们开始处理文本。我们试图将每个观察到的文本表示为一组数值特征。这样做的主要原因是因为传统的机器学习模型是设计用来接受数字作为输入,而不是文本。例如,一个常见的线性回归或逻辑回归模型是应用于数字,而不是单词、类别或图像像素。因此,我们需要为文本提供一个数值表示。当与语言模型BERTGPT一起工作时,这种设计限制被解除。我们将在接下来的章节中看到这一点。

我们将文本分割成N-gram,其中N是代码的一个参数。在这个代码中N是固定的,但应该优化以最好地适应训练集。

一旦文本被分割成N-gram,它们就被建模为数值。当选择二进制(即独热编码)方法时,代表某些N-gram的数值特征,如果观察到的文本包含该N-gram,则得到“1”,否则得到“0”。请参见图5.3以获取示例。如果选择BOW方法,则特征值是N-gram在观察到的文本中出现的次数。这里没有实现的一种常见特征工程方法是TF-IDF

仅使用单语词我们可以得到以下结果:

输入句子:“filing submitted。”

N-gram “report” “filing” “submitted” “product” “quarterly” 其他单语词
特征值 0 1 1 0 0 (0的)

图5.3 – 通过单语词编码将输入文本句子转换为数值表示

以下图显示了使用单语词和双语词得到的结果:

N-gram “report” “filing” “filing submitted” “report news” “submitted” 其他N-gram
特征值 0 1 1 0 1 (0的)

图5.4 – 通过将输入文本句子划分为单词和双词并通过独热编码进行转换,将其转换为数值表示

注意,在代码的这个阶段,数据集还没有被划分为训练集和测试集,预留集(也称为测试集)尚未排除。这是因为二进制和BOW特征工程方法不依赖于底层观察之外的数据。对于TF-IDF来说,情况则不同。每个特征值都是使用整个数据集的文档频率来计算的。

探索新的数值特征

现在我们已经将文本表示为特征,我们可以对其进行数值探索。我们可以查看其频率和统计信息,并了解其分布情况。

划分训练/测试集

这是我们必须暂停并划分预留集(也称为测试集,有时也称为验证集)的部分。由于这些术语在不同的来源中有不同的用法,重要的是要解释一下,我们所说的测试集实际上是一个预留集。预留集是我们专门用于评估解决方案性能的数据子集。它被预留出来以模拟当系统在实际世界中实施并遇到新数据样本时预期的结果。

我们如何知道何时划分预留集?

如果我们“过早”地划分它,例如在加载数据后立即进行,那么我们保证将其保留为预留集,但可能错过数据中的差异,因为它不会参与初步探索。如果我们“过晚”地划分它,我们的设计决策可能会因为它们而变得有偏见。例如,如果我们根据包括将要预留的集的结果选择一个机器学习模型而不是另一个,那么我们的设计就会针对那个集,从而阻止我们对该模型进行客观评估。

然后,我们需要在第一个将输入到设计决策中的动作之前执行测试集。在下文中,我们将进行统计分析,然后我们可以将其输入到特征选择中。由于该选择应该与预留集无关,因此我们将从这部分开始排除该集。

初步统计分析与可行性研究

这是我们在几页前讨论的探索阶段的第二部分。第一部分是数据探索,我们在代码的前几部分实现了它。现在我们已经将文本表示为数值特征,我们可以进行可行性研究。

我们试图衡量文本输入和类别值之间的统计依赖性。同样,动机是模仿线性相关在回归问题中提供的代理。

我们知道,对于两个随机变量,XY,如果它们在统计上独立,那么我们得到以下结果:

https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/291.png

或者,我们得到以下结果:

https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/292.png

这发生在每个产生非零概率的 x, y 值上。

相反,我们可以使用贝叶斯定理:

https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/293.png

https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/294.png

现在,让我们考虑任意两个不一定相互独立的随机变量。我们想要评估这两个变量之间是否存在统计关系。

让一个随机变量代表我们的任何数值特征,另一个随机变量代表输出类别,取值为0或1。假设特征工程方法是二元的,因此特征也取值为0或1。

观察最后一个等式,左侧的表达式展示了 XY 之间关系能力的非常强大的度量:

https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/295.png

它之所以强大,是因为如果特征对类别值完全没有指示性,那么在统计上,我们说这两个是统计独立的,因此这个度量将等于 1。

相反,这个度量与 1 之间的差异越大,这个特征与这个类别之间的关系就越强。当我们对我们设计的可行性研究进行评估时,我们希望看到数据中存在与输出类别有统计关系的特征。

因此,我们计算每个特征和每个类别的每一对特征的表达式的值。

我们展示了类别“0”的最具指示性的术语,类别“0”是指不表明公司或产品信息的推文类别,我们还展示了类别“1”中最具指示性的术语,这意味着当一条推文讨论公司或产品信息时。

这证明给我们看,确实存在一些文本术语可以指示类别值。这是可行性研究的明确和清晰的成功。我们可以继续前进,并期待在实现分类模型时取得有成效的结果。

作为一个附带说明,请记住,与大多数评估一样,我们刚才提到的只是文本预测类别的潜在性的一个充分条件。如果它失败了,这并不一定意味着没有可行性。就像当 XY 之间的线性相关性接近 0 时,这并不意味着 X 不能推断 Y。这只意味着 X 不能通过线性模型推断 Y。线性是一个为了简化问题而做出的假设,如果它成立。

在我们提出的方法中,我们做出了两个关键假设。首先,我们假设特征设计非常特别的方式,对于 N-gram 分区是某个特定的 N,对于值的定量方法是二进制。第二个是,我们执行最简单的统计依赖性评估,即单变量统计依赖性。但可能只有更高阶的,比如单变量,才会对结果类别有统计依赖性。

在进行文本分类的可行性研究时,如果方法尽可能简单同时覆盖尽可能多的“信号”,那么这是理想的。我们在这个例子中设计的方法是在多年的不同集合和不同问题设置的经验基础上得出的。我们发现它非常准确地击中了目标。

特征选择

通过可行性研究,我们经常一石二鸟。因为一个成功的可行性研究不仅可以帮助我们确认计划,而且经常暗示我们应该采取的下一步。正如我们所看到的,一些特征是类别指示性的,我们学会了哪些是最重要的。这使我们能够减少分类模型需要划分的特征空间。我们通过保留每个类别中最具指示性的特征来实现这一点。我们选择保留的特征数量理想情况下应由计算约束(例如,过多的特征会导致模型计算时间过长)、模型能力(例如,由于共线性,过多的特征可能无法被模型很好地处理)以及训练结果的优化来决定。在我们的代码中,我们固定了这个数字,以使事情变得快速简单。

应该强调的是,在许多机器学习模型中,特征选择是模型设计的一个固有部分。例如,对于最小绝对收缩和选择算子LASSO),https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/296.png范数的超参数缩放器会影响哪些特征得到零系数,从而被“排除”。有时可能且建议跳过这一部分的特征选择过程,保留所有特征,并让模型自行进行特征选择。当所有被评估和比较的模型都具有这一特性时,建议这样做。

记住,在这个阶段,我们只是在观察训练集。既然我们已经决定保留哪些特征,我们就需要将这个选择应用到测试集上。

这样,我们的数据已经为机器学习建模做好了准备。

遍历机器学习模型

为了选择最适合这个问题的模型,我们必须训练几个模型,并查看哪一个表现最好。

我们应该强调,我们可以做很多事情来尝试确定给定问题的最佳模型选择。在我们的案例中,我们只选择评估少数几个模型。此外,为了使事情简单快捷,我们选择不使用综合交叉验证方法来优化每个模型的超参数。我们只是使用每个模型默认设置将其拟合到训练集。一旦我们确定了我们想使用的模型,我们就通过交叉验证优化其在训练集上的超参数。

通过这样做,我们确定了最佳模型。

生成所选模型

在这里,我们优化所选模型超参数,并将其拟合到我们的训练集。

生成训练结果 – 设计选择

在这个阶段,我们首次观察模型的性能结果。这个结果可以用来将洞察力反馈到设计选择和选择的参数中,例如特征工程方法、特征选择中保留的特征数量,甚至预处理方案。

重要注意事项

注意,当将训练集结果中的洞察力反馈到解决方案的设计中时,你冒着过度拟合训练集的风险。你可以通过训练集和测试集结果之间的差距来判断你是否这样做。

虽然预期这些结果之间存在差距,有利于训练结果,但较大的差距应被视为一个警报,表明设计不是最优的。在这种情况下,应使用基于代码的系统参数重新设计该设计,以确保做出公平的选择。甚至可以从训练集中划分出另一个半保留集,通常称为验证集。

生成测试结果 – 展示性能

就这些!

现在由于设计已经优化,并且我们对其满足我们的目标有信心,我们可以将其应用于我们的保留集并观察测试结果。这些结果是我们对系统在现实世界中表现如何的最客观预测。

如前所述,我们应该避免让这些结果影响我们的设计选择。

摘要

在本章中,我们开始对文本分类进行了全面的探索,这是自然语言处理(NLP)和机器学习(ML)不可或缺的方面。我们深入研究了各种文本分类任务,每个任务都提出了独特的挑战和机遇。这种基础理解为有效地解决广泛的应用奠定了基础,从情感分析到垃圾邮件检测。

我们探讨了N-gram在捕捉文本中的局部上下文和词序列中的作用,从而增强了用于分类任务的特性集。我们还阐明了TF-IDF方法的力量,Word2Vec在文本分类中的作用,以及CBOW和skip-gram等流行架构,为您提供了对这些机制的深入理解。

然后,我们介绍了主题建模,并探讨了如何将LDA等流行算法应用于文本分类。

最后,我们介绍了一种在商业或研究环境中领导NLP-ML项目的专业范式。我们讨论了项目目标和设计方面,然后深入到系统设计。我们通过代码实现了一个真实世界的示例,并对其进行了实验。

本质上,本章旨在通过涉及该领域的核心概念、方法和技术,使你对文本分类和主题建模有一个全面的理解。所传授的知识和技能将使你能够有效地处理和解决现实世界的文本分类问题。

在下一章中,我们将介绍文本分类的高级方法。我们将回顾深度学习方法,如语言模型,讨论其理论和设计,并展示代码中的实际系统设计。

第六章:重新构想文本分类:深入探索深度学习语言模型

本章深入探讨深度学习(DL)及其在自然语言处理(NLP)中的应用,特别是专注于基于转换器的突破性模型,如双向编码器表示从转换器BERT)和生成预训练转换器GPT)。我们首先介绍深度学习的基础知识,阐述其从大量数据中学习复杂模式的能力,使其成为最先进 NLP 系统的基石。

随后,我们深入探讨转换器,这是一种新颖的架构,它通过提供比传统的循环神经网络RNNs)和卷积神经网络CNNs)更有效的处理序列数据的方法,从而彻底改变了 NLP。我们剖析了转换器的独特特性,包括其注意力机制,这使得它能够关注输入序列的不同部分,从而更好地理解上下文。

然后,我们将注意力转向 BERT 和 GPT,这些基于转换器的语言模型利用这些优势来创建高度细腻的语言表示。我们详细分析了 BERT 架构,讨论了其创新性地使用双向训练来生成语境丰富的词嵌入。我们将揭示 BERT 的内部运作机制,并探索其预训练过程,该过程利用大量文本语料库来学习语言语义。

最后,我们讨论了如何针对特定任务(如文本分类)微调 BERT。我们将引导你通过数据预处理、模型配置、训练和评估的步骤,提供如何利用 BERT 的力量进行文本分类的动手理解。

本章全面探讨了自然语言处理(NLP)中的深度学习(DL),从基础概念到实际应用,使你具备利用 BERT 和转换器模型的能力,以应对你的文本分类任务。

本章涵盖了以下主题:

  • 理解深度学习基础知识

  • 不同神经网络的架构

  • 转换器

  • 语言模型

  • 训练神经网络的挑战

  • BERT

  • GPT

  • 如何使用语言模型进行分类

  • NLP-ML 系统设计示例

技术要求

为了成功阅读本章,以下技术先决条件是必要的:

  • 编程知识:对 Python 的深入了解是必不可少的,因为它是大多数深度学习和 NLP 库的主要语言。

  • 机器学习基础:对基本机器学习概念的良好掌握,如训练/测试数据、过拟合、欠拟合、准确率、精确率、召回率和 F1 分数,将非常有价值。

  • 深度学习基础知识:熟悉深度学习的概念和架构,包括神经网络、反向传播、激活函数和损失函数,将是必不可少的。了解RNN和CNN将是有益的,但不是严格必要的,因为我们将会更多地关注transformer架构。

  • NLP基础知识:对基本NLP概念如分词、词干提取、词形还原和词嵌入(例如Word2VecGloVe)的理解将大有裨益。

  • 库和框架:对于使用TensorFlowPyTorch构建和训练神经网络的经验至关重要。熟悉NLP库如NLTKSpaCy也可能有益。对于专门使用BERT,了解Hugging Facetransformers库将非常有帮助。

  • 硬件要求:深度学习模型,尤其是基于transformer的模型如BERT,计算密集,通常需要现代图形处理单元GPU)在合理的时间内进行训练。推荐使用具有GPU能力的性能计算机或基于云的解决方案。

  • 数学:对线性代数、微积分和概率的良好理解有助于理解这些模型的内部工作原理,但大多数章节可以在没有深入数学知识的情况下理解。

这些先决条件旨在为你提供理解和实现章节中讨论的概念所需的必要背景。有了这些,你应该为深入探索使用BERT进行文本分类的迷人的深度学习世界做好了充分的准备。

理解深度学习基础知识

在这部分,我们解释了神经网络和深度神经网络是什么,使用它们的动机,以及深度学习模型的不同类型(架构)。

什么是神经网络?

神经网络是人工智能(AI)和机器学习(ML)的一个子领域,它专注于受大脑结构和功能启发的算法。它也被称为“深度”学习,因为这些神经网络通常由许多重复的层组成,形成了一个深度架构。

这些深度学习模型能够从大量复杂、高维和无结构的数据中“学习”。术语“学习”指的是模型能够自动从经验中学习并改进,而无需为任何特定任务(或任务集)明确编程。

深度学习可以是监督的、半监督的或无监督的。它在众多应用中使用,包括自然语言处理(NLP)、语音识别、图像识别,甚至玩游戏。这些模型可以识别模式并做出基于数据的预测或决策。

深度学习(DL)的一个关键优势是它能够处理和建模各种类型的数据,包括文本、图像、声音等。这种多功能性导致了从自动驾驶汽车到复杂的网络搜索算法以及高度响应的语音识别系统等广泛的应用。

值得注意的是,尽管深度学习具有很高的潜力,但它也要求有显著的计算能力和大量高质量的数据来有效地训练,这可能是一个挑战。

从本质上讲,深度学习(DL)是一种强大且变革性的技术,它是许多当今技术进步的前沿。

使用神经网络的动机

在机器学习和人工智能领域,神经网络被用于各种原因。以下是一些关键动机:

  • 非线性:神经网络通过其复杂的结构和激活函数的使用,可以捕捉数据中的非线性关系。许多现实世界现象在本质上是非线性的,神经网络提供了一种建模这些复杂性的方法。

  • 通用逼近定理:这个定理表明,具有足够隐藏单元的神经网络可以以高精度逼近几乎任何函数。这使得它们非常灵活,能够适应广泛的任务。

  • 处理高维数据的能力:神经网络可以有效地处理具有大量特征或维度的数据,这使得它们在图像或语音识别等高度维度的任务中非常有用。

  • 模式识别和预测:神经网络在识别大型数据集中的模式和趋势方面表现出色,这使得它们在预测任务中特别有用,例如预测销售或预测股市趋势。

  • 并行处理:神经网络的结构允许它们同时执行许多操作,这使得它们在现代硬件上实现时效率非常高。

  • 从数据中学习:随着神经网络接触到更多的数据,它们可以提高自己的性能。这种从数据中学习的能力使它们在大量数据可用的任务中非常有效。

  • 鲁棒性:神经网络可以处理输入数据中的噪声,对输入的小幅变化具有鲁棒性。

此外,由于几个原因,神经网络在自然语言处理(NLP)任务中被广泛使用。以下是一些主要动机:

  • 处理序列数据:自然语言本质上是序列性的(单词依次排列以形成连贯的句子)。循环神经网络(RNN)及其高级版本,如长短期记忆LSTM)和门控循环单元GRUs),是能够通过保持关于序列中先前步骤的某种内部状态或记忆来处理序列数据的神经网络类型。

  • 上下文理解:神经网络,尤其是循环神经网络,能够通过考虑周围的词语甚至之前的句子来理解句子中的上下文,这在NLP任务中至关重要。

  • 语义哈希:神经网络通过使用词嵌入(如Word2Vec和GloVe)以保留其语义意义的方式对词语进行编码。具有相似意义的词语在向量空间中放置得更近,这对于许多NLP任务非常有价值。

  • 端到端学习:神经网络可以直接从原始数据中学习。例如,在图像分类中,神经网络可以从像素级别学习特征,而不需要任何手动特征提取步骤。这是一个显著的优势,因为特征提取过程可能耗时且需要领域专业知识。

    同样,神经网络可以学习从原始文本数据中执行NLP任务,而不需要手动特征提取。这在NLP中是一个很大的优势,因为创建手工特征可能既困难又耗时。

  • 性能:神经网络,特别是随着基于transformer架构的BERT、GPT等的出现,已经在许多NLP任务中实现了最先进的结果,包括但不限于机器翻译、文本摘要、情感分析和问答。

  • 处理大型词汇:神经网络可以有效地处理大型词汇和连续的文本流,这在许多NLP问题中很常见。

  • 学习层次特征:深度神经网络可以学习层次化的表示。在自然语言处理(NLP)的背景下,较低层通常学习表示简单的事物,例如n-gram,而较高层可以表示复杂的概念,例如情感。

尽管有这些优势,但值得注意的是,神经网络也面临挑战,包括其“黑盒”性质,这使得其决策过程难以解释,以及它们在训练过程中需要大量数据和计算资源。然而,它们在性能方面提供的优势以及从原始文本数据中学习并建模复杂关系的能力,使它们成为许多NLP任务的首选选择。

神经网络的基本设计

神经网络由多层相互连接的节点,或称为“神经元”组成,每个神经元对其接收到的数据进行简单的计算,并将输出传递给下一层的神经元。每个神经元之间的连接都有一个相关的权重,该权重在学习过程中进行调整。

基本神经网络的结构由三种类型的层组成,如图图6.1所示:

https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/B18949_06_001.jpg

图6.1 – 神经网络的基本架构

在以下列表中,我们将更详细地解释模型的每一层:

  • 输入层:这是网络接收输入的地方。例如,如果网络被设计为处理28x28像素的图像,那么输入层将有784个神经元,每个神经元代表一个像素的值。

  • 隐藏层(s):这些层位于输入层和输出层之间。隐藏层中的每个神经元都会接收来自前一层的神经元输出,将这些输出与各自连接的权重相乘,并将这些值相加。这个和随后通过一个“激活函数”传递,以向模型引入非线性,这有助于网络学习复杂的模式。神经网络中可以有任何数量的隐藏层,具有许多隐藏层的网络通常被称为“深度”神经网络。

  • 输出层:这是网络中的最后一层。该层的神经元产生网络的最终输出。例如,对于分类问题,你可能设计网络使其具有一个输出神经元对应于问题中的每个类别,每个神经元输出一个值,表示输入属于其相应类别的概率。

网络中的神经元是相互连接的。这些连接的权重最初设置为随机值,代表网络在训练数据上训练后所学习的内容。

在训练过程中,使用诸如反向传播之类的算法来调整网络中连接的权重,以响应网络输出与期望输出之间的差异。这个过程会重复多次,网络逐渐提高其在训练数据上的性能。

为了提供一个简单的视觉概念,想象有三组圆圈(代表神经元)排列成列(代表层)。第一列是输入层,最后一列是输出层,任何介于两者之间的列都是隐藏层。然后,想象连接每一列中每个圆圈到下一列中每个圆圈的线条,代表神经元之间的加权连接。这就是神经网络的基本视觉表示。

在下一部分,我们将描述与神经网络相关的常见术语。

神经网络常见术语

在以下小节中,我们将探讨神经网络中最常用的术语。

神经元(或节点)

这是神经网络中的基本计算单元;通常,简单的计算涉及输入、权重、偏差和激活函数。神经元,也称为节点或单元,是神经网络的基本元素。它从其他节点或外部源接收输入,如果神经元位于输入层,则从外部源接收。然后,神经元根据这个输入计算输出。

每个输入都有一个相关的权重(w),这个权重是根据其与其他输入的相对重要性分配的。神经元将权重应用于输入,将它们加起来,然后对总和加上偏置值(b)应用激活函数。

下面是逐步分解:

  1. 加权求和:每个输入(x)到神经元的乘以相应的权重(w)。这些加权输入然后与偏置项(b)相加。偏置项允许激活函数向左或向右移动,有助于神经元模拟更广泛的模式。从数学上讲,这一步可以表示如下:

    https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/297.png

  2. 激活函数:加权求和的结果随后通过激活函数。激活函数的目的是将非线性引入神经元的输出。这种非线性使得网络能够从错误中学习并做出调整,这对于执行复杂任务(如语言翻译或图像识别)至关重要。常见的激活函数选择包括 sigmoid 函数、双曲正切(tanh)和修正线性单元(ReLU)等。

    神经元的输出是激活函数的结果。它作为网络下一层神经元的输入。

    神经元中的权重和偏置是可学习的参数。换句话说,它们的值是在神经网络在数据上训练的过程中逐渐学习的:

    • 权重:两个神经元之间连接的强度或幅度。在训练阶段,神经网络学习正确的权重,以便更好地将输入映射到输出。权重在神经元中,如前所述使用。

    • 偏置:神经元中的一个附加参数,允许激活函数向左或向右移动,这对于成功学习至关重要(也用于神经元)。

激活函数

确定神经元应产生给定其输入的输出的函数(在每个神经元中)称为激活函数。常见的例子包括 sigmoid、ReLU 和 tanh。

这里是一些最常见的激活函数类型:

  • Sigmoid 函数:这里我们基本上是将输入分类为 0 或 1。Sigmoid 函数将实值输入压缩到 0 到 1 之间。它通常用于二元分类网络的输出层:

    https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/298.png

    然而,它有两个主要缺点:梯度消失问题(对于大的正或负输入,梯度非常小,这可能会在反向传播期间减慢学习速度)和输出不是 零中心

  • 双曲正切函数:tanh函数也接受实数值输入并将其压缩到-1和1之间。与sigmoid函数不同,其输出以零为中心,因为其范围在原点周围是对称的:

    https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/299.png

    它也受到梯度消失问题的影响,与sigmoid函数一样。

  • ReLU函数:ReLU函数在近年来变得非常流行。其计算方式如下:

    https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/300.png

    换句话说,如果输入是正的,激活就是输入本身;否则,它是零。

    它不会同时激活所有神经元,这意味着只有当线性变换的输出小于0时,神经元才会被关闭。这使得网络稀疏且高效。然而,ReLU单元在训练期间可能很脆弱,如果通过它们的大梯度流动,它们可能会“死亡”(完全停止学习)。

  • Leaky ReLU:Leaky ReLU是ReLU的一种变体,它解决了“dying ReLU”问题。我们不是将函数定义为负x0,而是将其定义为x的一个小的线性分量:

    https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/301.png

    这允许函数在输入为负时“泄露”一些信息,有助于缓解dying ReLU问题。

  • 指数线性单元(ELU):ELU也是ReLU的一种变体,它修改了函数,使其对于负x具有非零值,这有助于学习过程:

    f(x) = x if x > 0, else

    α(exp(x) − 1)

    在这里,alpha (α) 是一个常数,它定义了当输入为负时函数的平滑性。ELU倾向于更快地将成本收敛到零并产生更准确的结果。然而,由于使用了指数运算,它可能计算得较慢。

  • Softmax函数:softmax函数常用于分类器的输出层,其中我们试图将输入分配到几个可能的类别之一。它给出了任何给定输入属于每个可能类别的概率:

https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/302.png

分母将概率归一化,因此它们在所有类别中加起来等于1。softmax函数也用于多项式逻辑回归。

这些激活函数各有优缺点,激活函数的选择可能取决于具体的应用和问题的具体背景。

一组在同一抽象级别处理信号的神经元。第一层是输入层,最后一层是输出层,介于两者之间的所有层都称为隐藏层。

Epoch

在训练神经网络的背景下,epoch是一个术语,用来表示对整个训练数据集的一次完整遍历。在一个epoch期间,神经网络会更新其权重,试图最小化损失函数。

超参数“epoch”的数量决定了深度学习算法处理整个训练数据集的次数。epoch过多可能导致过拟合,即模型在训练数据上表现良好,但在新数据上表现较差。相反,epoch过少可能意味着模型欠拟合——它可能需要进一步训练来改进。

还需要注意的是,epoch的概念在批量和迷你批量的梯度下降变体中更为相关。在随机梯度下降中,模型在看到每个单独的例子后更新其权重,因此epoch的概念就不那么直接了。

批量大小

在一次迭代中使用的训练实例数量。批量大小指的是在一次迭代中使用的训练示例数量。

当你开始训练一个神经网络时,你有几种选择来决定如何将数据输入到模型中:

  • 批量梯度下降:在这里,整个训练数据集被用来计算优化器每个迭代的损失函数的梯度(就像梯度下降一样)。在这种情况下,批量大小等于训练数据集中示例的总数。

  • 随机梯度下降(SGD):SGD在每个优化器的迭代中使用单个例子。因此,SGD的批量大小为1

  • 小批量梯度下降法:这是批梯度下降法和随机梯度下降法之间的折中方案。在小批量梯度下降法中,批量大小通常在10到1,000之间,具体取决于你拥有的计算资源。

批量大小可以显著影响学习过程。较大的批量大小在训练中进展更快,但并不总是收敛得那么快。较小的批量大小频繁更新模型,但训练进展较慢。

此外,较小的批量大小具有正则化作用,可以帮助模型更好地泛化,从而在未见过的数据上获得更好的性能。然而,使用过小的批量大小可能导致训练不稳定,梯度估计不准确,最终导致模型性能更差。

选择合适的批量大小是一个试错的过程,并且取决于具体问题和可用的计算资源:

  • 迭代次数:算法看到的批量数据数量(或它在数据集上进行的遍历次数)。

  • 学习率:一个超参数,通过根据损失梯度调整权重更新率来控制学习算法的收敛速度。

  • 损失函数(代价函数):损失函数评估神经网络在数据集上的性能。预测值与实际结果之间的偏差越大,损失函数的输出就越大。目标是使这个输出最小化,这将使模型做出更准确的预测。

  • 反向传播:在神经网络上执行梯度下降的主要算法。它计算输出层的损失函数梯度,并将其分布回网络的各层,通过更新权重和偏置以最小化损失。

  • 过拟合:一种情况,其中模型学习训练数据中的细节和噪声,以至于它在新的、未见过的数据上的表现较差。

  • 欠拟合:一种情况,其中模型过于简单,无法学习数据的潜在结构,因此训练数据和新的数据上的表现都较差。

  • 正则化:一种通过向损失函数添加惩罚项来防止过拟合的技术,这反过来又限制了网络的权重。

  • Dropout:一种正则化技术,在训练期间忽略随机选择的神经元,这有助于防止过拟合。

  • CNN:一种非常适合图像处理和计算机视觉任务的神经网络类型。

  • RNN:一种旨在识别数据序列中模式(如时间序列或文本)的神经网络类型。

让我们继续探讨不同神经网络的架构。

不同神经网络的架构

神经网络有多种类型,每种类型都有适合不同任务的特定架构。以下列表包含了一些最常见类型的通用描述:

  • 前馈神经网络 (FNN): 这是最直接的一种神经网络。在这个网络中,信息仅沿一个方向移动,从输入层通过任何隐藏层到输出层。网络中没有循环或环路;它是一条直线,“前馈”路径。

https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/B18949_06_002.jpg

图6.2 – 前馈神经网络

  • 多层感知器 (MLP): MLP是一种前馈网络,除了其输入和输出层外,至少还有一个隐藏层。层之间是完全连接的,这意味着层中的每个神经元都与下一层的每个神经元相连。MLP可以模拟复杂模式,并被广泛用于图像识别、分类、语音识别和其他类型的机器学习任务。MLP是一种前馈网络,具有按顺序排列的神经元层。信息从输入层通过隐藏层流向输出层,方向单一:

https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/B18949_06_003.jpg

图6.3 – 多层感知器

  • CNN: CNN特别适合涉及空间数据的任务,如图像。其架构包括三种主要类型的层:卷积层、池化层和全连接层。卷积层对输入应用一系列过滤器,这使得网络能够自动和自适应地学习特征的空间层次结构。池化层减少表示的空间大小,从而减少网络中的参数和计算,以控制过拟合并降低后续层的计算成本。全连接层获取池化层的输出,并在输出上进行高级推理。

https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/B18949_06_004.jpg

图6.4 – 卷积神经网络

  • 循环神经网络 (RNN): 与前馈网络不同,RNNs具有形成有向循环的连接。这种架构允许它们使用先前输出的信息作为输入,这使得它们非常适合涉及序列数据的任务,例如时间序列预测或自然语言处理。RNNs的一个重要变体是LSTM网络,它除了标准单元外还使用特殊单元。RNN单元包括一个“记忆细胞”,可以在长时间内保持信息在内存中,这对于需要从数据中的长距离依赖关系学习的任务特别有用,例如手写识别或语音识别。

https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/B18949_06_005.jpg

图6.5 – 循环神经网络

  • 自动编码器 (AE): AE 是一种用于学习输入数据有效编码的神经网络。它具有对称架构,并设计用于应用反向传播,将目标值设置为等于输入。自动编码器通常用于特征提取、学习数据的表示和降维。它们还用于生成模型、噪声去除和推荐系统。

https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/B18949_06_006.jpg

图 6.6 – 自动编码器架构

  • 生成对抗网络 (GAN): GAN 由两部分组成,一个生成器和一个判别器,它们都是神经网络。生成器创建数据实例,旨在与训练数据集的分布相同。判别器的目标是区分来自真实分布的实例和来自生成器的实例。生成器和判别器一起训练,目标是随着训练的进行,生成器产生更好的实例,而判别器则变得更好地区分真实实例和生成实例。

https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/B18949_06_007.jpg

图 6.7 – 计算机视觉中的生成对抗网络

这些只是神经网络架构的几个例子,存在许多变体和组合。你为任务选择架构将取决于任务的具体要求和限制。

神经网络训练的挑战

训练神经网络是一项复杂的工作,在训练过程中会面临挑战,如局部最小值和梯度消失/爆炸,以及计算成本和可解释性。所有挑战都在以下各点中详细解释:

  • 局部最小值: 训练神经网络的目的是找到使损失函数最小化的权重集。这是一个高维优化问题,存在许多点(权重集)的损失函数具有局部最小值。次优局部最小值是损失低于附近点的点,但高于全局最小值,全局最小值是整体可能的最小损失。训练过程可能会陷入这种次优局部最小值。重要的是要记住,即使是在凸损失函数中,由于数字计算中的一部分离散表示,局部最小值问题也存在。

  • 梯度消失/爆炸:这是在训练深度神经网络时遇到的一个困难。在反向传播过程中,损失函数的梯度可能在网络的深层中变得非常小(消失)或非常大(爆炸)。梯度消失使得网络难以从数据中学习,因为权重更新变得非常小。梯度爆炸可能导致训练过程失败,因为权重更新变得过大,损失变得未定义(例如,NaN)。

  • 过拟合:在训练机器学习模型时,一个常见的问题是我们的模型过于复杂,训练过度。在这种情况下,模型甚至学习了训练数据中的噪声,在训练数据上表现良好,但在未见过的测试数据上表现不佳。

  • 欠拟合:相反,当模型过于简单,无法捕捉数据的潜在结构时,就会发生欠拟合。通过使用适当的模型复杂度、正则化技术和足够数量的训练数据,可以减轻过拟合和欠拟合。

  • 计算资源:训练神经网络,尤其是深度网络,需要大量的计算资源(CPU/GPU功率和内存)。它们通常还需要大量的训练数据才能表现良好,当这些数据不可用时,这可能成为一个问题。

  • 缺乏可解释性:虽然这不是一个严格意义上的训练问题,但神经网络缺乏可解释性是一个重大问题。它们通常被称为“黑盒”,因为很难理解它们为什么会做出这样的预测。

  • 选择适当架构和超参数的困难:有众多类型的神经网络架构可供选择(例如CNN和RNN),每种架构都有一组需要调整的超参数(例如学习率、批量大小、层数和每层的单元数)。为特定问题选择最佳架构并调整这些超参数可能是一个具有挑战性和耗时的工作。

  • 数据预处理:神经网络通常需要输入数据以特定格式。例如,数据可能需要归一化,分类变量可能需要独热编码,缺失值可能需要填充。这个预处理步骤可能既复杂又耗时。

这些挑战使得训练神经网络成为一个非平凡的任务,通常需要技术专长、计算资源和试错法的结合。

语言模型

语言模型是NLP中的一种统计模型,旨在学习和理解人类语言的结构。更具体地说,它是一种概率模型,经过训练可以估计在给定一个单词场景的情况下单词的可能性。例如,语言模型可以被训练来预测句子中的下一个单词,给定前面的单词。

语言模型是许多NLP任务的基础。它们被用于机器翻译、语音识别、词性标注和命名实体识别等任务。最近,它们还被用来创建对话式AI模型,如聊天机器人和个人助手,以及生成类似人类的文本。

传统的语言模型通常基于显式的统计方法,例如n-gram模型,这些模型在预测下一个词时只考虑前n个词,或者隐藏马尔可夫模型(HMMs)。

最近,神经网络在创建语言模型方面变得流行,导致了神经语言模型的兴起。这些模型利用神经网络的强大功能来考虑每个词的上下文,从而实现更高的准确性和流畅性。神经语言模型的例子包括RNN、Transformer模型以及各种基于Transformer的架构,如BERT和GPT。

语言模型在计算环境中理解、生成和解释人类语言是必不可少的,它们在许多自然语言处理(NLP)的应用中扮演着至关重要的角色。

这里是使用语言模型的一些动机:

  • 机器翻译:语言模型是翻译系统中的一个关键组件,它们可以评估翻译句子的流畅性,并帮助在多种可能的翻译中选择。

  • 语音识别:语言模型在语音识别系统中被用来帮助区分听起来相似的单词和短语。通过预测句子中可能出现的下一个词,它们可以提高转录的准确性。

  • 信息检索:当你在互联网上搜索某物时,语言模型有助于确定哪些文档与你的查询相关。它们可以理解你的搜索词与潜在结果之间的语义相似性。

  • 文本生成:语言模型可以生成类似人类的文本,这在聊天机器人、写作助手和内容创作工具等应用中非常有用。例如,聊天机器人可以使用语言模型来生成对用户查询的适当响应。

  • 情感分析:通过理解语言结构,语言模型可以帮助判断一段文本的情感是积极、消极还是中性。这在社交媒体监控、产品评论和客户反馈等领域非常有用。

  • 语法检查:语言模型可以预测句子中下一个词应该是什么,这有助于识别语法错误或表达不当。

  • 命名实体识别:语言模型可以帮助识别文本中的命名实体,如人名、组织、地点等。这对于信息提取和自动摘要等任务非常有用。

  • 理解上下文:语言模型,尤其是基于深度学习(DL)的最近模型,如transformers,在理解单词和句子的上下文方面非常出色。这种能力对于许多自然语言处理(NLP)任务至关重要,例如问答、摘要和对话系统。

所有这些动机都源于一个中心主题:语言模型帮助机器更有效地理解和生成人类语言,这在当今数据驱动的世界中对于许多应用至关重要。

在下一节中,我们将介绍不同类型的学习,然后解释如何使用自监督学习来训练语言模型。

半监督学习

半监督学习是一种机器学习方法,它利用标记数据和未标记数据来训练。当你只有少量标记数据而大量未标记数据时,这种方法特别有用。这里的策略是使用标记数据来训练一个初始模型,然后使用这个模型来预测未标记数据的标签。然后,使用新标记的数据重新训练模型,从而提高其准确性。

无监督学习

另一方面,无监督学习涉及完全基于未标记数据进行模型训练。这里的目的是在数据中找到潜在的规律或结构。无监督学习包括诸如聚类(目的是将相似实例分组在一起)和降维(目的是简化数据而不丢失太多信息)等技术。

使用自监督学习来训练语言模型

自监督学习是一种无监督学习形式,其中数据提供监督。换句话说,模型学会从同一输入数据的其他部分预测输入数据的一部分。它不需要人类提供的显式标签,因此称为“自监督”。

在语言模型的背景下,自监督通常通过预测句子的一部分来实现,当给出其他部分时。例如,给定句子“The cat is on the __”,模型将被训练来预测缺失的单词(在这种情况下是“mat”)。

接下来,让我们看看一些流行的自监督学习策略,用于训练语言模型。

掩码语言模型(MLM)

这种策略在BERT的训练中使用,随机掩盖输入标记的一部分,并要求模型根据未掩盖的词提供的上下文预测掩盖的单词。例如,在句子“The cat is on the mat”中,我们可以掩盖“cat”,而模型的任务就是预测这个单词。请注意,也可以掩盖多个单词。

从数学上讲,多标签学习(MLM)的目标是最大化以下似然函数:

https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/303.png

其中 wi 是一个掩码词,w{-i} 是非掩码词,而 θ 代表模型参数。

自回归语言模型

在自回归语言模型中,如 GPT 模型所使用的,模型根据句子中所有前面的词预测句子中的下一个词。它被训练以最大化给定句子中先前词的词的概率。

自回归语言模型的目标是最大化

https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/304.png

其中 *w_*i 是当前词,https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/305.png 是前面的词,而 θ 代表模型参数。

这些策略使语言模型能够直接从原始文本中获得对语言语法和语义的丰富理解,而无需显式标签。然后,这些模型可以通过各种任务进行微调,例如文本分类、情感分析等,利用从自监督预训练阶段获得的语言理解。

迁移学习

迁移学习是一种机器学习技术,其中预训练模型被重新用作不同但相关问题的起点。与传统机器学习方法相比,传统方法是从随机权重初始化模型开始,迁移学习有从相关任务学习到的模式中启动学习过程的优势,这既可以加快训练过程,也可以提高模型的性能,尤其是在你有有限的标记训练数据时。

在迁移学习中,一个模型通常是在一个大规模任务上训练的,然后使用模型的一部分作为另一个任务的起点。这个大规模任务通常选择得足够广泛,以至于学习到的表示对许多不同的任务都有用。当两个任务的输入数据类型相同且任务相关时,这个过程特别有效。

应用迁移学习有几种方法,最佳方法可能取决于你任务的数据量以及你的任务与模型训练的原任务相似程度。

特征提取

预训练模型充当特征提取器。你移除模型的最后一层或几层,保留网络的其他部分。然后,你将数据通过这个截断的模型传递,并使用输出作为训练用于你特定任务的新、更小模型输入。

微调

你使用预训练模型作为起点,并更新模型的所有或部分参数以适应你的新任务。换句话说,你继续从上次停止的地方训练,允许模型从通用的特征提取调整到更具体于你任务的特性。在微调期间,通常使用较低的学习率,以避免在训练过程中完全覆盖预学习的特征。

迁移学习是一种强大的技术,可以用来提高机器学习模型的性能。它在有少量标记数据可用的任务中特别有用。它通常在深度学习应用中使用。例如,在图像分类问题中,几乎已经成为标准,即使用在ImageNet(一个大规模标注图像数据集)上预训练的模型(ResNet、VGG、Inception等)作为起点。这些模型学习到的特征对图像分类来说是通用的,并且可以在包含更少数据的具体图像分类任务上进行微调。

这里有一些迁移学习应用的例子:

  • 一个用于分类猫和狗图像的模型可以被用来微调一个模型,以分类其他动物的图像,如鸟类或鱼类。

  • 一个用于将英语翻译成西班牙语的文本模型可以被用来微调一个模型,以将西班牙语翻译成法语。

  • 一个用于预测房价的模型可以被用来微调一个模型,以预测汽车的价格。

类似地,在自然语言处理中,大型预训练模型,如BERT或GPT,通常被用作广泛任务(如文本分类、情感分析、问答等)的起点。这些模型在大量文本语料库上预训练,并学习到丰富的语言表示,可以针对特定任务进行微调。

理解Transformer

Transformer是一种由Ashish Vaswani、Noam Shazeer、Niki Parmar、Jakob Uszkoreit、Llion Jones、Aidan N. Gomez、Łukasz Kaiser和Illia Polosukhin在论文《Attention is All You Need》中提出的神经网络架构(Advances in neural information processing systems 30 (2017), Harvard)。它们在NLP领域产生了深远的影响,并成为BERT和GPT等最先进模型的基础。

Transformer的关键创新是自注意力机制,它允许模型在生成输出时权衡输入中每个词的相关性,从而考虑每个词的上下文。这与之前的模型(如RNN或LSTM)不同,这些模型按顺序处理输入,因此更难捕捉词之间的长距离依赖关系。

Transformer的架构

Transformer由一个编码器和解码器组成,它们都由几个相同的层组成,如图图6.8所示。编码器中的每一层包含两个子层:一个自注意力机制和一个位置感知的全连接前馈网络。在每个子层周围都采用了残差连接,然后是层归一化:

https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/B18949_06_008.jpg

图6.8 – 自注意力机制

同样,解码器中的每一层也有三个子层。第一个是自注意力层,第二个是跨注意力层,它关注编码器堆栈的输出,第三个是位置感知的全连接前馈网络。与编码器一样,这些子层周围都有残差连接,然后是层归一化。请注意,在图中只显示了一个头,我们可以有多个头并行工作(N个头)。

自注意力机制

自注意力机制,或缩放点积注意力,计算序列中每个词对当前正在处理的词的相关性。自注意力层的输入是一个词嵌入序列,每个嵌入通过分别学习的线性变换被分割成一个查询Q)、一个K)和一个V)。

每个词的注意力分数计算如下:

https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/306.png

其中d_k是查询和键的维度,用于缩放点积以防止其变得过大。softmax操作确保注意力分数是归一化的并且总和为1。这些分数代表在产生当前单词的输出时,对每个单词值的赋予的权重。

自注意力层的输出是一个新的向量序列,其中每个单词的输出是所有输入值的加权总和,权重由注意力分数决定。

位置编码

由于自注意力机制没有考虑序列中单词的位置,因此Transformer在编码器和解码器堆栈的底部添加了位置编码到输入嵌入中。这种编码是位置的固定函数,允许模型学习使用单词的顺序。

在原始的Transformer论文中,位置编码是位置和维度的正弦函数,尽管也有效地使用了学习位置编码。

Transformer的应用

自从它们被引入以来,Transformer已被用于在包括机器翻译、文本摘要、情感分析等在内的广泛NLP任务上实现最先进的结果。它们也被应用于其他领域,如计算机视觉和强化学习。

Transformer的引入导致了NLP领域向在大型文本语料库上预训练大型Transformer模型,然后在特定任务上进行微调的转变,这是一种有效的迁移学习方法。这种方法已被用于BERT、GPT-2、GPT-3和GPT-4等模型。

了解更多关于大型语言模型

大型语言模型是一类在广泛互联网文本上训练的机器学习模型。

“大型语言模型”中的“大型”一词指的是这些模型所拥有的参数数量。例如,GPT-3有1750亿个参数。这些模型使用自监督学习在大量的文本语料库上进行训练,这意味着它们预测句子中的下一个单词(例如GPT)或基于周围单词的单词(例如BERT,它也被训练来预测一对句子是否连续)。由于它们接触到了如此大量的文本,这些模型学习了语法、关于世界的知识、推理能力,以及它们在训练数据中存在的偏见。

这些模型基于转换器架构,这意味着它们利用了转换器架构,该架构使用自注意力机制来衡量输入数据中单词的重要性。这种架构使得这些模型能够处理文本中的长距离依赖关系,使它们在广泛的自然语言处理任务中非常有效。

大型语言模型可以通过在特定任务上进行微调来实现高性能。微调涉及在较小的、特定任务的语料库上进行额外的训练,这使得模型能够将其通用的语言理解能力适应到任务的特定细节。这种方法已被用于在许多自然语言处理基准测试中实现最先进的结果。

尽管大型语言模型展示了令人印象深刻的能力,但它们也提出了重要的挑战。例如,由于它们是在互联网文本上训练的,它们可以复制和放大数据中存在的偏见。它们还可以生成有害或误导性的输出。此外,由于它们的规模,这些模型在训练和部署时需要大量的计算资源,这引发了成本和环境影响的问题。

尽管存在这些挑战,大型语言模型在人工智能领域代表了重大进步,并且是广泛应用于翻译、摘要、内容创作、问答等众多领域的强大工具。

训练语言模型的挑战

训练大型语言模型是一项复杂且资源密集型的工作,面临着诸多挑战。以下是其中一些关键问题:

  • 计算资源:大型语言模型的训练需要大量的计算资源。这些模型拥有数十亿个参数,需要在训练过程中进行更新,这涉及到在庞大的数据集上执行大量的计算。这种计算通常在高性能GPU或张量处理单元TPUs)上执行,相关的成本可能非常昂贵。

  • 内存限制:随着模型大小的增加,存储模型参数、训练过程中的中间激活和梯度的内存需求也增加。这可能导致即使在最先进的硬件上也会出现内存问题。可以使用模型并行化、梯度检查点和卸载等技术来减轻这些问题,但它们会增加训练过程的复杂性。

  • 数据集大小和质量:大型语言模型是在广泛的文本语料库上训练的。找到、清理和结构化组织如此庞大的数据集可能具有挑战性。此外,数据集的质量直接影响模型的表现。由于这些模型从它们训练的数据中学习,数据中的偏差或错误可能导致偏差或易出错的模型。

  • 过拟合:虽然大型模型具有学习复杂模式的高容量,但它们也可能过度拟合训练数据,尤其是在可用数据量与模型大小相比有限的情况下。过拟合会导致未见数据泛化能力差。可以使用正则化技术,如权重衰减、dropout和提前停止,来对抗过拟合。

  • 训练稳定性:随着模型变大,稳定训练它们变得更加困难。挑战包括管理学习率和批量大小,以及处理梯度消失或爆炸等问题。

  • 评估和微调:由于这些模型的大小,评估它们的性能也可能具有挑战性。此外,在特定任务上对这些模型进行微调可能很棘手,因为这可能导致“灾难性遗忘”,即模型忘记了预训练的知识。

  • 伦理和安全问题:大型语言模型可以生成有害或不适当的内容。它们还可以传播和放大训练数据中存在的偏见。这些问题需要开发强大的方法来控制模型的行为,无论是在训练期间还是在运行时。

尽管存在这些挑战,大型语言模型领域仍在继续取得进展。研究人员正在开发新的策略来减轻这些问题,并更有效地、负责任地训练大型模型。

语言模型的特定设计

在这里,我们将详细解释两种流行的语言模型架构,BERT和GPT。

BERT

我们之前提到的BERT,现在将进一步展开介绍,它是一种基于转换器的NLP任务机器学习技术。由谷歌开发,并在Jacob Devlin、Ming-Wei Chang、Kenton Lee和Kristina Toutanova合著的论文《Bert: Pre-training of deep bidirectional transformers for language understanding》,arXiv预印本arXiv:1810.04805(2018)中提出。

BERT的设计是为了通过在所有层中对左右上下文进行联合条件预训练,从未标记的文本中预训练深度双向表示。这与之前的方法,如GPT和ELMo,不同,它们只从左上下文或分别从左右上下文中预训练文本表示。这种双向性允许BERT更准确地理解上下文和单词的语义意义。

BERT的设计

BERT基于Transformer模型架构,如图6所示,最初由Vaswani等人发表在论文Attention is All You Need中提出。模型架构由堆叠的自注意力层和逐点全连接层组成。

BERT有两种大小:BERT BaseBERT Large。BERT Base由12个Transformer层组成,每个层有12个自注意力头,总共有1100万个参数。BERT Large更大,有24个Transformer层,每个层有16个自注意力头,总共有3400万个参数。

BERT的训练过程包括两个步骤:预训练微调

训练或使用语言模型的第一步是创建或加载其字典。我们通常使用分词器来实现这一目标。

分词器

为了高效地使用语言模型,我们需要使用一个分词器,将输入文本转换为有限数量的标记。子词分词算法,如字节对编码BPE)、一元语言模型ULM)和WordPiece,将单词分割成更小的子词单元。这对于处理词汇表外的单词很有用,并允许模型学习对子词部分的有意义表示,这些部分通常携带语义意义。

BERT分词器是BERT模型的一个关键组件,执行模型输入所需文本数据的初始预处理。BERT使用WordPiece分词,这是一种子词分词算法,将单词分解成更小的部分,允许BERT处理词汇表外的单词,减少词汇表的大小,并处理语言的丰富性和多样性。

下面是BERT分词器工作原理的详细分解:

  1. 基本分词:首先,BERT分词器执行基本分词,通过在空白和标点符号处分割文本来将文本分解成单个单词。这与其他分词方法中可能找到的方法类似。

  2. WordPiece分词:在基本分词之后,BERT分词器应用WordPiece分词。这一步将单词分解成更小的子词单元或“WordPieces”。如果一个单词不在BERT词汇表中,分词器将迭代地将单词分解成更小的子词,直到在词汇表中找到匹配项,或者直到不得不求助于字符级表示。

    例如,单词“unhappiness”可能被分解成两个WordPieces:“un”和“##happiness”。符号“##”用于表示是更大单词的一部分的子词,而不是一个完整的单词。

  3. 特殊标记添加:BERT分词器随后添加了必要的特殊标记,以支持特定的BERT功能。每个句子的开头都附加了[CLS]标记,作为分类任务的聚合表示。每个句子的结尾添加了[SEP]标记,以表示句子边界。如果输入了两个句子(对于需要句子对的任务),它们将通过这个[SEP]标记分开。

  4. 标记到ID的转换:最后,每个标记都被映射到一个整数ID,这个ID对应于它在BERT词汇表中的索引。这些ID是BERT模型实际使用的输入。

总结来说,BERT分词器的工作原理是首先将文本分词成单词,然后(如果需要)进一步将这些单词分解成WordPieces,添加特殊标记,最后将这些标记转换成ID。这个过程使得模型能够理解和生成对各种单词和子词的有意义的表现,从而有助于BERT在多种NLP任务上表现出强大的性能。

预训练

在预训练期间,BERT在大量的文本语料库上进行了训练(原始论文中使用了整个英文维基百科和BooksCorpus)。模型被训练去预测句子中的掩码单词(掩码语言模型),以及区分文本中两个句子是否按顺序出现(下一句预测),如这里所解释的:

  • 掩码语言模型:在这个任务中,一个句子中的15%的单词被一个[MASK]标记所替换,模型被训练去预测由非掩码单词提供的上下文中的原始单词。

  • 下一句预测:当模型被给出一对两个句子时,它也被训练去预测句子B是否是句子A之后的下一句。

微调

预训练后,BERT可以在具有显著较少训练数据的具体任务上进行微调。微调涉及向BERT添加一个额外的输出层,并在特定任务上端到端地训练整个模型。这种方法已经在包括问答、命名实体识别、情感分析等多种NLP任务上实现了最先进的结果。

BERT的设计及其预训练/微调方法彻底改变了NLP领域,并导致了在广泛的数据上训练大型模型,然后在特定任务上进行微调的趋势。

如何微调BERT进行文本分类

正如之前提到的,BERT已经在大量的文本数据集上进行了预训练,学习到的表示可以针对特定任务进行微调,包括文本分类。以下是如何逐步微调BERT进行文本分类的步骤:

  1. 预处理输入数据:BERT需要特定的输入数据格式。句子需要使用BERT自己的分词器将句子分词成子词,并添加特殊标记,如[CLS](分类)和[SEP](分隔)。[CLS]标记添加在每个示例的开头,用作分类任务的聚合序列表示。[SEP]标记添加在每个句子的末尾,以表示句子边界。然后,所有序列都填充到固定长度,以形成一个统一的输入。

  2. 加载预训练BERT模型:BERT有多个预训练模型,应根据任务选择正确的模型。这些模型在模型大小和预训练数据的语言方面有所不同。一旦加载预训练BERT模型,就可以用它为输入数据创建上下文化的词嵌入。

  3. 添加分类层:在预训练BERT模型之上添加一个分类层,也称为分类头。这个层将被训练以对文本分类任务进行预测。通常,这个层是一个全连接神经网络层,它以对应于[CLS]标记的表示作为输入,并输出类别的概率分布。

  4. 微调模型:微调涉及使用标记数据在特定任务(在这种情况下,文本分类)上训练模型。这个过程可以通过多种方式完成。更常见的方法是更新预训练BERT模型和新添加的分类层权重,以最小化损失函数,通常是分类任务的交叉熵损失。在微调期间使用较低的学习率很重要,因为较大的学习率可能会使预学习的权重不稳定。此外,建议的epoch数通常是两到四个,这样模型就能学习任务但不会过拟合。这种方法的好处是模型权重将被调整以在特定任务上表现良好。或者,我们可以冻结BERT层,只更新分类层权重。

  5. 评估模型:一旦模型经过微调,就可以在验证集上评估其性能,以评估其性能。这包括计算准确率、精确率、召回率和F1分数等指标。在训练和评估任务期间,与其他ML和DL模型类似,我们可以执行超参数调整。

  6. 应用模型:经过微调的模型现在可以用于对新、未见过的文本数据进行预测。与训练数据一样,这些新数据也需要预处理成BERT期望的格式。

重要注意事项

注意,与BERT一起工作需要相当的计算资源,因为该模型具有大量的参数。通常建议使用GPU进行微调和应用BERT模型。有一些模型比BERT轻量,性能略低,例如DistilBERT,在计算或内存资源受限的情况下可以使用。此外,BERT能够处理512个标记,这限制了我们的输入文本长度。如果我们想处理更长的文本,Longformer或BigBird是不错的选择。这里所解释的内容适用于类似的语言模型,如RoBERTa、XLNet等。

总结来说,对BERT进行文本分类的微调涉及预处理输入数据,加载预训练的BERT模型,添加分类层,在标记数据上微调模型,然后评估和应用模型。

我们将演示先前的BERT微调范式,然后在本章末尾应用它。您将有机会亲自使用它并调整以满足您的需求。

GPT-3

GPT-3,即生成****预训练Transformer 3,是由OpenAI开发的一种自回归语言模型,它使用深度学习技术生成类似人类的文本。它是GPT系列的第三个版本。GPT系列的后续版本,GPT-3.5和GPT-4,将在下一章中介绍,因为我们将扩展关于大型语言模型的内容。

GPT-3的设计和架构

GPT-3的架构扩展了其前辈使用的transformer模型架构。该架构基于一个使用Transformer块的Transformer模型,其中每个块由自注意力层和前馈神经网络层组成。

与之前的版本相比,GPT-3规模庞大。它由1750亿个ML参数组成。这些参数在训练阶段学习,模型学习预测一系列单词中的下一个单词。

GPT-3的Transformer模型旨在处理数据序列(在这种情况下,文本中的单词或标记序列),使其非常适合语言任务。它从左到右顺序处理输入数据,并为序列中的下一个项目生成预测。这是BERT和GPT之间的区别,在BERT中,使用两侧的单词来预测掩码词,但在GPT中,仅使用前面的单词进行预测,这使得它成为生成任务的不错选择。

预训练和微调

与BERT和其他基于Transformer的模型类似,GPT-3也涉及两个步骤的过程:预训练微调

预训练

在这个阶段,GPT-3在大量的文本数据语料库上进行训练。它学习预测句子中的下一个单词。然而,与BERT使用双向上下文进行预测不同,GPT-3仅使用左侧上下文(即句子中的前面的单词)。

微调

在预训练阶段之后,GPT-3 可以使用较少的任务特定训练数据在特定任务上进行微调。这可以是任何 NLP 任务,例如文本补全、翻译、摘要、问答等。

零样本、一样本和少样本学习

GPT-3 令人印象深刻的特点之一是其执行少样本学习的能力。当被赋予一个任务和该任务的几个示例时,GPT-3 通常能够准确地学习执行该任务。

在零样本设置中,模型被赋予一个任务而没有任何先前的示例。在一样本设置中,它被赋予一个示例,在少样本设置中,它被赋予几个示例来学习。

使用 GPT-3 的挑战

尽管GPT-3拥有令人印象深刻的性能,但也存在一些挑战。由于其规模庞大,它需要大量的计算资源来训练。它有时会生成不正确或无意义的响应,并且可能会反映训练数据中存在的偏差。它还难以处理需要深入理解世界或超越从文本中学习到的常识推理的任务。

回顾我们的用例 - 在 Jupyter Notebook 中为 NLP 分类设计的 ML/DL 系统设计

在本节中,我们将处理一个现实世界的问题,并看看我们如何可以使用 NLP 管道来解决它。这部分代码以 Google Colab 笔记本的形式共享,网址为 Ch6_Text_Classification_DL.ipynb

业务目标

在这种情况下,我们处于医疗保健行业。我们的目标是开发一个与医疗保健领域最新发现非常同步的通用医学知识引擎。

技术目标

技术总监从业务目标中推导出几个技术目标。其中一个目标是针对 ML 团队:鉴于与医学出版物相对应的结论集合不断增长,识别出代表建议的结论。这将使我们能够识别出源于基础研究的医学建议。

管道

让我们回顾一下管道的各个部分,如图 图 6*.9* 所示:

https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/B18949_06_009.jpg

图 6.9 – 典型探索和模型管道的结构

注意这个设计与我们在 图 5*.2* 中看到的设计有何不同。在那里,探索和评估部分利用了后来由 ML 模型使用的相同特征工程技术。在这里,使用 LMs,特征工程不是建模准备的一部分。预训练模型,特别是分词器,执行特征工程,这产生了与二进制、BoW 或 TF-IDF 特征非常不同且难以解释的特征。

注意

代码部分:从“设置”到“生成传统 ML 模型的结果”。

这些部分在本质上与第第5章中讨论的模拟部分相同。唯一的区别与数据的不同有关。

深度学习

在这段代码中,我们使用了一个深度学习语言模型。

当考虑通过LM应用迁移学习并针对我们的目标和数据进行微调时,有多个堆栈可供选择。最突出的是Google的TensorFlow和Meta的PyTorch。一个名为Transformers的包被构建为这些堆栈的包装器,以允许代码的更简单实现。在这个例子中,我们利用了transformers模型的简洁性和丰富性。

值得强调的是构建并支持Transformers包的公司:Hugging Face。Hugging Face承担起创建一个围绕免费、开源DL模型收集和共享的整个生态系统,这包括许多适应实现这些模型的组件。最实用的工具是Transformers包,这是一个Python包,致力于选择、导入、训练和部署一个庞大且不断增长的DL模型集合。

我们在这里审查的代码不仅提供了一个现实世界中的ML/DL系统设计的示例;还展示了Hugging Face的Transformers。

数据格式化

在这里,我们将数据设置成适合Transformers库的格式。列名必须非常具体。

评估指标

我们决定要优化的指标,并将其插入到训练过程中。对于这个二元分类问题,我们优化了准确率,并将我们的结果与数据集的基线准确率进行了比较,也称为先验。

训练器对象

这是用于在Transformers中训练LM的核心对象。它包含一组预定义的配置。一些关键的训练配置如下:

  • 神经网络的数学学习超参数,例如以下:

    • 学习率

    • 梯度下降设置

  • 训练轮数

  • 计算硬件使用情况

  • 训练过程中记录目标指标进度的日志设置

微调神经网络参数

关于微调语言模型的基本概念是迁移学习。神经网络非常适合迁移学习,因为可以从结构的末端简单地剥离任意数量的层,并用未训练的层替换它们,这些层将基于底层问题进行训练。未移除且未训练的其余层将继续以与语言模型最初训练时(当它最初构建时)完全相同的方式运行。如果我们替换最后一层但保留其余的原始层,那么我们可以将这些层视为监督特征工程,或者相反,作为嵌入机制。这种特性反映了迁移学习的概念。理想情况下,模型预计将很好地适应我们的底层问题,因此我们将选择保留绝大多数的原始层,只有一小部分会被替换并训练。这样,一个需要几周时间预训练的大型深度学习模型可以在几分钟内迁移和适应新的问题。

在我们的代码中,我们以这种方式设置模型,即我们确切地指定我们想要微调其哪些层。这是我们的设计选择,基于性能和计算资源。一个选择是微调紧接最终输出的最后一层,也称为分类头。另一种选择是微调所有层。在我们的代码中,我们明确调用模型的配置,该配置控制哪些层被微调,因此代码可以以任何适合设计的方式更改。

我们将训练器配置为实时记录训练性能。它将这些日志以表格形式打印出来,以便我们观察和监控。当训练完成后,我们绘制训练和评估的进度。这有助于我们了解训练结果和评估结果之间的关联。由于训练器使用的评估集可以被视为训练器上下文中的保留集,这个图表使我们能够研究欠拟合和过拟合。

生成训练结果——用于设计选择

我们回顾了训练集的结果,以及训练器打印出的日志。我们将它们与基线准确率进行了比较,并观察到准确率的提高。通过迭代多个不同的设计选择并进行比较,我们了解了我们设计的质量。将这个过程自动化为代码,以便对最佳设置进行系统评估。我们只是在笔记本中这样做,以保持示例的简单性。一旦我们相信我们已经找到了最佳设置,我们就可以说这个过程已经完成。

生成测试结果——用于展示性能

就像 第 5 章 中的代码一样,在这里,我们也以回顾测试结果结束。值得注意的是评估集和测试集之间的差异。有人可能会建议,由于训练者没有使用评估集进行训练,它可以作为一个保留的测试集,从而节省了从训练中排除许多观察结果的需要,并为模型提供更多标记数据。然而,尽管训练者没有使用评估集,我们确实使用了它来做出我们的设计决策。例如,我们观察了前一个部分的图表,并判断哪个数量的周期数是达到最佳拟合的最优选择。在 第 5 章 中也使用了评估集,但我们不需要明确定义它;它是作为 K 折交叉验证机制的一部分执行的。

摘要

在这一启发性的章节中,我们全面探索了深度学习及其在文本分类任务中通过语言模型应用的显著应用。我们从深度学习的概述开始,揭示了其从大量数据中学习复杂模式的能力,以及在推进最先进自然语言处理系统中的无可争议的作用。

然后,我们深入到变换器模型的变革性世界,这些模型通过提供传统 RNN 和 CNN 处理序列数据的有效替代方案,已经彻底改变了自然语言处理。通过解开注意力机制——变换器中的一个关键特性——我们突出了其专注于输入序列不同部分的能力,从而促进了上下文理解的更好。

我们的旅程继续深入探索 BERT 模型。我们详细介绍了其架构,强调其开创性地使用双向训练来生成语境丰富的词嵌入,并突出了其预训练过程,该过程从大量文本语料库中学习语言语义。

然而,我们的探索并未就此结束;我们还介绍了 GPT,另一个利用变换器能力以略有不同方式变革的模型——专注于生成类似人类的文本。通过比较 BERT 和 GPT,我们阐明了它们的独特优势和用例。

本章以一个关于如何使用这些高级模型设计和实现文本分类模型的实用指南结束。我们引导您经历了这个过程的各个阶段,从数据预处理和模型配置到训练、评估,最后是在未见过的数据上做出预测。

本质上,本章提供了对自然语言处理中深度学习的全面理解,从基本原理过渡到实际应用。凭借这些知识,您现在可以充分利用变压器模型、BERT和GPT的能力来处理您的文本分类任务。无论您是想进一步深入研究自然语言处理的世界,还是在实际环境中应用这些技能,本章都为您奠定了坚实的基础。

在本章中,我们向您介绍了大型语言模型。在下一章中,我们将更深入地探讨这些模型,以了解更多关于它们的信息。

第七章:揭秘大型语言模型:理论、设计和Langchain实现

在本章中,我们深入探讨了大型语言模型(LLMs)错综复杂的领域及其性能背后的数学概念。这些模型的出现彻底改变了自然语言处理(NLP)领域,提供了无与伦比的理解、生成和与人类语言互动的能力。

LLMs是人工智能(AI)模型的一个子集,可以理解和生成类似人类的文本。它们通过在多样化的互联网文本上进行训练来实现这一点,从而学习到关于世界的广泛事实。它们还学会了预测文本中的下一个内容,这使得它们能够生成富有创意、流畅且上下文一致的句子。

随着我们探索大型语言模型(LLMs)的操作,我们将介绍关键指标困惑度,这是衡量不确定性的一个关键指标,对于确定这些模型的性能至关重要。较低的困惑度表明语言模型(LM)在预测序列中的下一个单词时的信心,从而展示了其熟练程度。

本章借鉴了多篇深入探讨LLMs数学洞察力的有见地出版物。其中一些包括《神经概率语言模型》、《Attention is All You Need》和《PaLM:通过路径扩展语言建模》。这些资料将指导我们理解支撑LLMs及其卓越能力的稳健机制。

我们还将探讨在LMs背景下新兴的人类反馈强化学习(RLHF)领域。RLHF已被证明是微调LLMs性能的强大工具,从而导致了更准确和有意义的生成文本。

通过对LLMs数学基础的全面理解和对RLHF的深入研究,我们将获得这些先进AI系统的稳健知识,为该领域的未来创新和进步铺平道路。

最后,我们将讨论最近模型(如Pathways语言模型(PaLM)、大型语言模型Meta AI(LLaMA)和GPT-4)的详细架构和设计。

现在,让我们看看本章涵盖的主题:

  • 什么是LLMs,它们与LMs有何不同?

  • 开发和使用LLMs的动机

  • 开发LLMs的挑战

技术要求

对于本章,你应具备机器学习(ML)概念的坚实基础,特别是在Transformer强化学习领域。理解基于Transformer的模型至关重要,这些模型是许多当今LLMs的基础。这包括对诸如自注意力机制、位置编码和解码器架构结构等概念的了解。

理解强化学习原理也是必不可少的,因为我们将会深入探讨在LM微调中RLHF的应用。熟悉诸如策略梯度、奖励函数和Q学习等概念将大大提高你对这些内容的理解。

最后,编程能力,特别是Python,至关重要。这是因为许多概念将通过编程的角度进行演示和探索。熟悉PyTorch或TensorFlow等流行的机器学习库,以及Hugging Face的Transformers库(用于处理Transformer模型的关键资源)也将大有裨益。

然而,如果你觉得自己在某些领域有所欠缺,请不要气馁。本章旨在引导你了解这些主题的复杂性,并在过程中填补任何知识空白。因此,带着学习的心态做好准备,让我们深入探索LLMs的迷人世界!

LLM是什么?它们与LM有何不同?

LM是一种机器学习模型,它被训练来预测给定之前单词(或在某些模型中,周围单词)的序列中的下一个单词(或字符或子词,具体取决于模型的粒度)。它是一个概率模型,能够生成遵循某种语言风格或模式的文本。

在Transformer模型(如生成预训练Transformer(GPTs)和双向编码器表示来自Transformer(BERT))出现之前,NLP任务中广泛使用了其他几种类型的LM。以下小节将讨论其中的一些。

n-gram模型

这些是一些最简单的LM。一个n-gram模型使用前n-1个词来预测句子中的第n个词。例如,在二元(2-gram)模型中,我们会使用前一个词来预测下一个词。这些模型易于实现且计算效率高,但它们通常不如更复杂的模型表现得好,因为它们无法捕捉到词之间的长距离依赖关系。随着n的增加,它们的性能也会下降,因为它们受到数据稀疏性问题的影响(没有足够的数据来准确估计所有可能的n-gram的概率)。

隐藏马尔可夫模型(HMMs)

这些模型考虑了生成观察数据的“隐藏”状态。在语言建模的背景下,每个词都是一个观察状态,而“隐藏”状态则是一种某种类型的语言特征,它不是直接可观察的(例如,词的词性)。然而,与n-gram模型一样,HMMs也难以捕捉到词之间的长距离依赖关系。

循环神经网络(RNNs)

这些是一种神经网络,其中节点之间的连接形成了一个沿着时间序列的定向图。这使得它们能够使用它们的内部状态(记忆)来处理输入序列,使它们非常适合语言建模。它们可以捕捉单词之间的长距离依赖关系,但它们在所谓的梯度消失问题上挣扎,这使得在实践中学习这些依赖关系变得困难。

长短期记忆(LSTM)网络

LSTM网络是一种特殊的RNN,旨在学习长期依赖关系。它们通过使用一系列“门”来控制信息在网络记忆状态中的流入和流出。LSTMs在语言建模的先进技术中迈出了重要一步。

门控循环单元(GRU)网络

这些是LSTM的一种变体,它们的架构中使用了略微不同的门。它们通常比LSTMs更简单、训练更快,但它们是否比LSTMs表现更好或更差,往往取决于具体任务。

每个这些模型都有其自身的优点和缺点,并且它们之间没有一个是本质上比另一个更好或更差的——这完全取决于具体任务和数据集。然而,基于Transformer的模型在广泛的任务中通常优于所有这些模型,这导致了它们在NLP领域的当前流行。

LLMs如何脱颖而出

LLMs,例如GPT-3和GPT-4,仅仅是训练在大量文本上并且拥有大量参数的LMs。模型(就参数和训练数据而言)越大,它理解和生成复杂多变文本的能力就越强。以下是LLMs与较小LMs不同的几个关键方式:

  • 数据:LLMs在大量数据上训练。这使得它们能够从广泛的语用模式、风格和主题中学习。

  • 参数:LLMs拥有巨大的参数数量。ML模型中的参数是从训练数据中学习到的模型的部分。模型拥有的参数越多,它能够学习的复杂模式就越多。

  • 性能:由于它们在更多数据上训练并且拥有更多参数,LLMs通常比较小的LLMs表现更好。它们能够生成更连贯、多样化的文本,并且更好地理解上下文、进行推理,甚至能够在广泛的主题上回答问题或生成文本。

  • 计算资源:LLMs在训练过程中需要大量的计算资源,包括处理能力和内存。它们的训练时间也更长。

  • 存储和推理时间:大型模型也需要更多的存储空间,生成预测所需的时间更长(尽管在现代硬件上,这个推理时间通常仍然相当快)。

因此,我们可以这样说,LLMs实际上是小型LMs(语言模型)的扩展版本。它们在更多数据上进行训练,具有更多参数,并且通常能够产生更高品质的结果,但它们也需要更多资源来训练和使用。除此之外,LLM的一个重要优势是,我们可以在大量数据语料库上无监督地训练它们,然后使用有限的数据对不同的任务进行微调。

开发和使用LLMs的动机

开发和使用LLMs的动机源于与这些模型的能力相关的几个因素,以及它们在多样化应用中可能带来的潜在好处。以下小节详细介绍了这些关键动机之一。

性能提升

当LLMs(大型语言模型)在充足的数据上进行训练时,通常比小型模型表现出更好的性能。它们更擅长理解上下文,识别细微差别,并生成连贯且与上下文相关的响应。这种性能提升适用于NLP(自然语言处理)的广泛任务,包括文本分类、命名实体识别、情感分析、机器翻译、问答和文本生成。如表7.1所示,BERT(第一个广为人知的LLMs之一)和GPT的性能与之前的模型在通用语言理解评估GLUE)基准上进行了比较。GLUE基准是一系列多样化的自然语言理解NLU)任务集合,旨在评估模型在多个语言挑战中的性能。基准涵盖了诸如情感分析、问答和文本蕴涵等任务。它是NLU领域广泛认可的标准,为比较和改进语言理解模型提供了一个全面的套件。可以看出,它在所有任务中的表现都更好:

模型 所有任务平均( 情感分析 语法 相似度
BERT large 82.1 94.9 60.5 86.5
BERT base 79.6 93.5 52.1 85.8
OpenAI GPT 75.1 91.3 45.4 80.0
预开AI 艺术状态STOA 74.0 93.2 35.0 81.0
双向长短期记忆(BiLSTM)+ 语言模型(ELMo)嵌入 + 注意力 71.0 90.4 36.0 73.3

表7.1 – 比较不同模型在GLUE上的性能(此比较基于BERT和GPT发布时的2018年)

广泛泛化

在多样化数据集上训练的LLMs可以在不同的任务、领域或语言风格之间更好地泛化。它们可以从训练数据中有效地学习,以识别和理解广泛的语言模式、风格和主题。这种广泛的泛化能力使它们适用于各种应用,从聊天机器人到内容创作到信息检索。

当LM更大时,这意味着它有更多的参数。这些参数允许模型捕捉和编码数据中的更复杂关系和细微差别。换句话说,更大的模型可以从训练数据中学习并保留更多信息。因此,它在训练后能够更好地处理更广泛的任务和上下文。正是这种增加的复杂性和容量使得更大的LLM在不同任务上具有更强的泛化能力。正如我们在图7.1中可以看到的,更大的LLM在不同任务上的表现更好。

https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/B18949_07_1.jpg

图7.1 – 基于大小和训练的LLM性能

我们还可以在图7.2中看到过去三年LLM发展的进展。

https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/B18949_07_2.jpg

图7.2 – 2019年至2023年间发布的LLM(公开可用的模型已突出显示)

然而,需要注意的是,虽然较大的模型往往具有更强的泛化能力,但它们也带来了挑战,例如计算需求增加和过拟合的风险。同时,确保训练数据能够代表模型预期执行的任务和领域也是至关重要的,因为模型可能会继承训练数据中存在的任何偏差。

少样本学习

GPT-3、GPT-3.5和GPT-4等LLM展示了令人印象深刻的少样本学习能力。给定几个示例(“样本”),这些模型可以有效地泛化到完成类似任务。这使得在实际应用中调整和部署这些模型更加高效。提示可以设计为包含模型可以参考的信息,例如示例问题和相应的答案。

模型会从给定的示例中临时学习,并将给定信息作为额外来源。例如,当将LLM用作个人助理或顾问时,可以将有关用户背景的信息附加到提示中,使模型能够“了解你”,因为它使用你的个人信息提示作为参考。

理解复杂上下文

由于LLM在广泛的数据上进行大量训练,包括各种主题、文学风格和细微差别,以及其深度架构和大型参数空间,它们具有理解复杂上下文的优势。这种能力使它们即使在复杂或细微的情况下也能理解和生成适当的回应。

例如,考虑一个用户要求模型总结一篇复杂科学文章的场景。LLM可以理解文章的上下文和使用的专业技术语言,并生成连贯且简化的摘要。

多语言能力

LLM可以有效地处理多种语言,使其适用于全球应用。以下是一些著名的多语言LLM。

mBERT(多语言BERT)

mBERT(多语言BERT)是对BERT的一种扩展,它使用掩码语言模型目标在拥有最大维基百科的104种主要语言上进行预训练。

跨语言语言模型(XLM)

它在100种语言上进行训练。它将BERT模型扩展到包括几种跨语言模型训练方法。

XLM-RoBERTa

XLM-RoBERTa扩展了RoBERTa,而RoBERTa本身是BERT的一个优化版本,并在一个覆盖更多语言的更大多语言语料库上进行了训练。

MarianMT

Hugging Face的Transformers库的一部分,MarianMT是一个针对翻译任务优化的最先进的基于Transformer的模型。

DistilBERT 多语言

这是通过蒸馏过程实现的mBERT的一个较小且更快的版本。

T2T(T5)多语言

这是一种文本到文本迁移转换器T5)模型的变体,它针对翻译任务进行了微调。

这些模型在各种任务中取得了显著成果,例如翻译、命名实体识别、词性标注和多种语言中的情感分析。

人类似文本生成

LLMs在生成类似人类的文本方面表现出非凡的能力。它们可以在对话中创建上下文适当的回应,撰写文章,并生成诗歌和故事等创意内容。GPT-3、ChatGPT和GPT-4等模型在文本生成任务中取得了良好的结果。

虽然优势很多,但重要的是要注意,使用LLMs(大型语言模型)也存在挑战和潜在风险。它们需要大量的计算资源来训练和部署,并且持续存在有关它们可能生成有害或偏见内容、可解释性和环境影响的相关担忧。研究人员正在积极研究减轻这些问题同时利用这些模型强大功能的方法。

由于这些原因,公司正在尝试实施和训练更大的LMs(图7*.3*):

https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/B18949_07_3.jpg

图7.3 – 新的LMs及其大小,以及开发者

开发LLMs的挑战

开发LLMs带来了一系列独特的挑战,包括但不限于处理大量数据、需要巨大的计算资源以及引入或持续偏见的风险。以下小节概述了这些挑战的详细解释。

数据量

LLMs require enormous amounts of data for training. As the model size grows, so does the need for diverse, high-quality training data. However, collecting and curating such large datasets is a challenging task. It can be time-consuming and expensive. There’s also the risk of inadvertently including sensitive or inappropriate data in the training set. To have more of an idea, BERT has been trained using 3.3 billion words from Wikipedia and BookCorpus. GPT-2 has been trained on 40 GB of text data, and GPT-3 has been trained on 570 GB of text data. Table 7.2 shows the number of parameters and size of training data of a few recent LMs.

Model Parameters Size of training data
GPT-3.5 175 B 300 billion tokens
GPT-3 175 B 300 billion tokens
PaLM 540 B 780 billion tokens
LLaMA 65 B 1.4 trillion tokens
Bloom 176 B 366 billion tokens

表7.2 – 一些最近LM的参数数量和训练数据

计算资源

Training LLMs requires substantial computational resources. These models often have billions or even trillions of parameters and need to process vast amounts of data during training, which requires high-performance hardware (such as GPUs or TPUs) and a significant amount of time. This can be costly and could limit the accessibility of developing such models to only those who have these resources. For example, training GPT-3 took 1 million GPU hours, which cost around 4.6 million dollars (in 2020). Table 7.3 shows the computational resources and training time of a few recent LMs.

Model Hardware Training time
PaLM 6144 TPU v4 -
LLaMA 2048 80G A100 21 days
Bloom 384 80G A100 105 days
GPT-3 1024x A100 34 days
GPT-4 25000 A100 90–100 days

表7.3 – 一些最近LM的硬件和训练时间

偏差风险

LLMs can learn and perpetuate biases present in their training data. This could be explicit bias, such as racial or gender bias in the way language is used, or more subtle forms of bias, such as the underrepresentation of certain topics or perspectives. This issue can be challenging to address because bias in language is a deeply rooted societal issue, and it’s often not easy to even identify what might be considered bias in a given context.

模型鲁棒性

It’s challenging to ensure that LLMs will perform well in all possible scenarios, particularly on inputs that differ from their training data. This includes dealing with ambiguous queries, handling out-of-distribution data, and ensuring a level of consistency in the responses. Making sure that the model is not overtrained can help to have a more robust model, but much more is needed to have a robust model.

可解释性和调试

LLMs,就像大多数深度学习DL)模型一样,通常被描述为“黑盒”。理解它们为何做出特定的预测或如何得出结论并不容易。如果模型开始产生错误或不适当的输出,这会使调试变得具有挑战性。提高可解释性是一个活跃的研究领域。例如,一些库试图通过采用诸如特征重要性分析等技术来阐明LM的决策过程,这些技术涉及移除一些单词并分析梯度变化。

其中一种方法是输入扰动技术。在这种方法中,从输入文本中扰动或移除一个单词(或多个单词),并分析模型输出的变化。背后的原理是了解特定输入单词对模型输出预测的影响。如果移除某个单词显著改变了模型的预测,可以推断模型认为这个单词对其预测很重要。

分析梯度变化是另一种流行的方法。通过研究当移除某个单词时,输出相对于输入的梯度如何变化,可以深入了解模型决策过程如何受到该特定单词的影响。

这些解释技术为LLMs复杂的决策过程提供了更透明的视角,使研究人员能够更好地理解和改进他们的模型。LIME和SHAP等库提供了模型解释任务的工具,从而使这个过程对研究人员更加容易访问。

环境影响

训练LLMs所需的强大计算资源可能对环境产生重大影响。这些模型训练所需的能量可能有助于碳排放,这是一个从可持续性的角度来看的担忧。

此外,人们对LLMs中的隐私和安全问题表示担忧。例如,建议不要分享使用患者医疗信息训练的模型,或者不要将敏感信息输入到公开可用的LLMs,如ChatGPT,因为它可以将这些信息作为其他用户问题的答案返回。

不同类型的LLMs

LLMs通常是训练在大量文本数据上的神经网络架构。术语“大”指的是这些模型在参数数量和训练数据规模方面的规模。以下是一些LLMs的例子。

Transformer模型

Transformer模型在最近的LLMs浪潮中处于前沿。它们基于“Transformer”架构,该架构在Vaswani等人撰写的论文《Attention is All You Need》中引入,它使用自注意力机制在预测时权衡输入中不同单词的相关性。Transformers是一种神经网络架构,由Vaswani等人引入的论文《Attention is All You Need》中提出。它们的一个显著优势,尤其是对于LLMs的训练,是它们适合并行计算。

在传统的RNN模型中,例如LSTM和GRU,文本中的标记(单词、子词或字符)必须按顺序处理。这是因为每个标记的表示不仅取决于标记本身,还取决于序列中的前一个标记。这些模型的内在顺序性质使得它们的操作难以并行化,这可能会限制训练过程的速度和效率。

与之相反,Transformer通过使用称为自注意力的机制(或缩放点积注意力)消除了顺序处理的需要。在自注意力过程中,每个标记的表示被计算为序列中所有标记的加权总和,权重由注意力机制确定。重要的是,这些针对每个标记的计算与其他标记的计算是独立的,因此可以并行执行。

这种并行化能力为训练LLM带来了几个优势,我们将在下面讨论。

速度

通过并行计算,Transformers可以比RNN更快地处理大量数据。这种速度可以显著减少LLM的训练时间,因为LLM通常需要处理大量数据。

可扩展性

Transformer的并行化使得扩大模型规模和训练数据量变得更加容易。这种能力对于开发LLM至关重要,因为这些模型通常从在大数据集上训练和拥有更多参数中受益。

长距离依赖

Transformer能够更好地捕捉标记之间的长距离依赖关系,因为它们同时考虑序列中的所有标记,而不是逐个处理。这种能力在许多语言任务中非常有价值,可以提高LLM的性能。

这些模型各有其优势和劣势,最佳模型的选择可能取决于具体任务、可用训练数据量和计算资源。

最先进的LLM的示例设计

在本部分,我们将深入探讨在撰写本书时一些最新LLM的设计和架构。

GPT-3.5和ChatGPT

ChatGPT的核心是一个Transformer,这是一种使用自注意力机制来衡量输入中不同单词相关性的模型架构。它允许模型在生成响应时考虑输入的完整上下文。

GPT模型

ChatGPT基于Transformer的GPT版本。GPT模型被训练来预测给定所有先前单词的序列中的下一个单词。它们从左到右处理文本(单向上下文),这使得它们非常适合文本生成任务。例如,ChatGPT所基于的GPT版本之一,GPT-3,包含1750亿个参数。

两步训练过程

ChatGPT的训练过程分为两个步骤:预训练和微调。

预训练

在这一步,模型在互联网上公开可用的文本的大量语料库上进行训练。然而,值得注意的是,它并不知道其训练集中具体有哪些文档,也无法访问任何特定的文档或来源。

微调

在预训练之后,基础模型在OpenAI创建的定制数据集上进行进一步训练(微调),这些数据集包括正确行为的演示以及不同响应的排序比较。一些提示来自Playground和ChatGPT应用的用户,但它们被匿名化,并去除了个人身份信息。

RLHF

微调过程的一部分涉及RLHF,其中人类AI训练师对一系列示例输入的模型输出提供反馈,并将此反馈用于改进模型的响应。RLHF是用于训练ChatGPT的微调过程中的一个关键组件。这是一种通过学习来自人类评估者的反馈来细化模型性能的技术。在这里,我们首先解释RLHF的一般概念,在下一节中,我们将逐步解释。

RLHF的第一步是收集人类反馈。对于ChatGPT来说,这通常涉及让人类AI训练师参与对话,在其中他们扮演双方(用户和AI助手)。训练师还可以访问模型撰写的建议,以帮助他们撰写响应。这种对话,其中AI训练师实际上是在与自己进行对话,被添加到数据集以进行微调。

除了对话之外,还创建了比较数据,其中多个模型响应根据质量进行排序。这是通过采取一个对话轮次,生成几个不同的完成(响应),并让人类评估者对它们进行排序来完成的。评估者不仅对响应的事实正确性进行排序,还根据他们认为响应的有用性和安全性进行排序。

然后使用近端策略优化PPO)算法对模型进行微调,这是一种强化学习算法。PPO试图根据人类反馈改进模型的响应,通过对模型参数进行小幅度调整,增加获得好评响应的可能性,并减少获得差评响应的可能性。

RLHF是一个迭代过程。收集人类反馈、创建比较数据和使用PPO微调模型的过程重复多次,以逐步改进模型。接下来,我们将更详细地解释PPO的工作原理。

PPO是一种用于优化代理π策略的强化学习算法。策略定义了代理如何根据其当前状态选择动作。PPO旨在优化此策略,以最大化预期的累积奖励。

在深入研究PPO之前,定义奖励模型非常重要。在强化学习的背景下,奖励模型是一个R(s, a)函数,它为每个状态-动作对(s, a)分配一个奖励值。代理的目标是学习一个策略π,该策略最大化这些奖励的期望总和。

强化学习的目标可以从以下方面进行数学定义:

https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/307.png

在这个公式中,Eπ[.]是遵循策略π生成的轨迹(状态-动作对的序列)的期望,s_t是时间t的状态,a_t是时间t采取的动作,而R(s_t*, a*_t*)是时间t*收到的奖励。

PPO通过引入一个比率,r_t(θ),来修改这个目标,以鼓励策略空间的探索,同时防止在每次更新时策略发生太大变化。这个比率r_t(θ)表示当前策略π_θ与旧策略π_θ_old的概率比:

https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/308.png

PPO的目标随后定义为以下:

https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/309.png

在这里,A_t 是一个优势函数,它衡量采取行动 a_t 相比于状态 *s_*t 的平均行动有多好,而 clip(r_t(θ), 1 - ε, 1 + ε)r_t(θ) 的裁剪版本,旨在阻止策略更新过大。

算法随后使用随机梯度上升优化这个目标,调整策略参数 θ 以增加 J_PPO(π)

在 ChatGPT 和 RLHF 的背景下,状态对应于会话历史,动作对应于模型生成的消息,奖励对应于对这些消息的人类反馈。PPO 被用来调整模型参数,以提高人类反馈判断的生成消息质量。

人类排名被用来创建奖励模型,该模型量化了每个响应的好坏。奖励模型是一个函数,它接受一个状态和一个动作(在这种情况下,是会话上下文和模型生成的消息),并输出一个标量奖励。在训练过程中,模型试图最大化其期望累积奖励。

RLHF 的目标是使模型的行为与人类价值观保持一致,并提高其生成有用和安全响应的能力。通过学习人类反馈,ChatGPT 可以适应更广泛的会话上下文,并提供更合适、更有帮助的响应。值得注意的是,尽管有这些努力,系统仍然可能会犯错误,处理这些错误和改进 RLHF 流程是一个持续研究的领域。

生成响应

当生成响应时,ChatGPT 以会话历史为输入,包括会话中的先前消息以及最新的用户消息,并生成一个模型生成的消息作为输出。会话历史被标记化并输入到模型中,模型生成一系列标记作为响应,然后这些标记被反标记化以形成最终的输出文本。

系统级控制

OpenAI还实施了一些系统级控制,以减轻ChatGPT的有害或不真实输出。这包括一个 moderation API,它会警告或阻止某些类型的不安全内容。

ChatGPT中RLHF的逐步过程

由于RLHF是ChatGPT和其他许多最先进SOTA)模型的重要组成部分,更好地理解它对您是有用的。近年来,LM已经展示了非凡的能力,根据人类生成的提示创建出多样化和引人入胜的文本。尽管如此,由于它本质上是主观的并且取决于上下文,精确地定义“好的”文本仍然具有挑战性。例如,在创作故事时需要创造力,信息性文章需要准确性,而代码片段需要可执行性。

定义一个损失函数来封装这些属性似乎几乎是不可能的,因此大多数LM都是使用基本的下一个标记预测损失进行训练,例如交叉熵。为了克服损失函数的限制,个人已经开发了与人类偏好更好地对齐的指标,例如BLEU或ROUGEBLEU分数,或双语评估助手,是一个用于衡量机器翻译文本与一组参考翻译相比有多好的指标。尽管这些指标在评估性能方面更有效,但它们本质上是有局限性的,因为它们仅仅使用基本规则将生成的文本与参考进行比较。

如果我们能将人类对生成文本的反馈作为性能指标,甚至更好的是作为优化模型的损失,那将会产生变革性的影响吗?这就是RLHF背后的概念——利用强化学习技术直接使用人类反馈来优化LM。RLHF已经开始使LM能够将基于通用文本语料库训练的模型与复杂的人类价值观对齐。

RLHF最近在ChatGPT的开发中取得了成功应用。

RLHF的概念由于其多方面的模型训练过程和不同的部署阶段,提出了一个巨大的挑战。在这里,我们将训练过程分解为其三个基本组成部分:

  • LM的初始预训练

  • 数据收集和奖励模型训练

  • 使用强化学习精炼LM

我们将首先检查LM的预训练阶段。

LM预训练

作为基础,RLHF使用了一个已经使用传统预训练目标进行预训练的LM,这意味着我们根据训练数据创建分词器,设计模型架构,然后使用训练数据预训练模型。对于其最初受到好评的RLHF模型InstructGPT,OpenAI使用了GPT-3的小型版本。另一方面,Anthropic使用了从1000万到520亿参数的transformer模型进行这项任务,而DeepMind则使用了其2800亿参数的模型Gopher。

这个初步模型可以在额外的文本或特定条件下进一步细化,尽管这并不总是必要的。例如,OpenAI选择使用被标记为“更可取”的人类生成的文本来细化其模型。这个数据集被用来进一步微调模型,使用RLHF模型,基于人类提供的上下文提示来提炼原始LM模型。

通常来说,关于“哪种模型”作为RLHF的最佳起点的问题并没有一个确定的答案。可供RLHF训练的选项尚未得到充分探索。

接下来,一旦LLM就位,就需要生成数据来训练奖励模型。这一步对于将人类偏好整合到系统中至关重要。

https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/B18949_07_4.jpg

图7.4 – 预训练LM

训练奖励模型

在新提出的方法中,RLHF被用作RM,这同样被称为偏好模型。这里的核心理念是获取一段文本并返回一个反映人类偏好的标量奖励。这种方法可以有两种实现方式。首先,实现一个端到端的LLM,它给出我们想要的输出。这个过程可以通过微调一个LLM或从头开始训练一个LLM来完成。其次,有一个额外的组件,它对LLM的不同输出进行排序,并返回最佳输出。

用于训练RM的数据集是一组提示生成对。提示从预定的数据集(Anthropic的数据)中采样。这些提示通过初始LM进行处理,以生成新的文本。

人类标注员对LM生成的文本输出进行排名。直接为每个文本片段分配标量分数以生成奖励模型似乎很直观,但在现实中这很具挑战性。不同的价值观使得这些分数无法标准化且不可靠。因此,排名被用来比较多个模型输出,从而创建一个大大改善的正则化数据集。

文本排名有几种策略。一种成功的方法是让用户比较两个LLM在相同提示下产生的文本。通过直接比较模型输出,可以生成一个Elo评分系统,我们将在下面描述,它可以生成模型和输出之间的排名。然后,这些不同的排名方法被归一化成一个标量奖励信号用于训练。最初为国际象棋开发的Elo评分系统也适用于LM的RLHF。

在LM的背景下,每个模型或变体(例如,不同训练阶段的模型)可以被视为一个“玩家”。它的Elo评分反映了它在生成人类偏好输出方面的表现。

Elo评分系统的基本机制保持不变。以下是它如何适应LM中的RLHF:

  • 初始化:所有模型都以相同的Elo评分开始,通常是1,000或1,500。

  • 比较:对于给定的提示,两个模型(A和B)生成它们的输出。然后,人类评估者对这些输出进行排名。如果评估者认为模型A的输出更好,则模型A“赢得”比赛,而模型B“失败”。

每次评估后,Elo评分以这种方式更新。随着时间的推移,它们根据人类偏好提供模型的持续、动态排名。这对于跟踪训练过程中的进度以及比较不同的模型或模型变体非常有用。

成功的RLHF系统使用了不同大小的奖励语言模型相对于文本生成。例如,OpenAI使用了一个175B的语言模型和一个6B的奖励模型,Anthropic使用了从10B到52B的语言模型和奖励模型,而DeepMind为语言模型和奖励模型都使用了70B的Chinchilla模型。这是因为偏好模型必须与模型生成文本所需的容量相匹配。在RLHF的此阶段,我们拥有一个能够进行文本生成的初始语言模型和一个根据人类感知对任何文本进行评分的偏好模型。接下来,我们应用强化学习来优化原始语言模型以适应奖励模型。

https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/B18949_07_5.jpg

图7.5 – 强化学习的奖励模型

如何使用强化学习微调模型

在相当长的一段时间里,由于技术和算法上的挑战,使用强化学习训练语言模型被认为是不可能的。然而,一些组织已经通过策略梯度强化学习算法——即PPO,成功地对初始语言模型副本的一些或所有参数进行了微调。由于使用10B或100B+参数的整个模型进行微调的成本过高(更多细节请参阅针对语言模型的低秩自适应(LoRA)或DeepMind的Sparrow语言模型),因此语言模型的参数保持静态。PPO作为一种已经存在一段时间的方法,有大量的指南解释其工作原理。这种成熟度使其成为扩展到RLHF新型应用(分布式训练)的吸引人选择。似乎通过确定如何使用已知算法更新如此庞大的模型,RLHF已经取得了重大进展(更多内容将在后面介绍)。

我们可以将这个微调任务表述为一个强化学习问题。最初,策略是一个接受提示并生成一系列文本(或仅仅是文本的概率分布)的LM。这个策略的动作空间是与LM词汇表相匹配的所有标记(通常约为50 K个标记),而观察空间是可能的输入标记序列的分布,鉴于强化学习之前的用途(维度近似于输入标记序列词汇大小的幂(^)长度)。奖励函数将偏好模型与策略转移的约束结合起来。

奖励函数是系统将所有讨论过的模型整合到单个强化学习与人类反馈(RLHF)过程中的交汇点。给定数据集中的提示x,文本y由当前迭代的微调策略创建。这个文本与原始提示一起传递给偏好模型,该模型返回一个表示“偏好度”的标量度量https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/310.png

此外,强化学习策略的每个标记的概率分布与初始模型中的概率分布进行对比,以计算它们差异的惩罚。在OpenAI、Anthropic和DeepMind的几篇论文中,这个惩罚被构建为这些分布序列之间的Kullback–LeiblerKL)散度的缩放版本https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/311.png。KL散度项惩罚强化学习策略在每次训练批次中显著偏离初始预训练模型,确保生成合理连贯的文本片段。

没有这种惩罚,优化过程可能会开始生成一些胡言乱语,这些胡言乱语可能会以某种方式欺骗奖励模型,使其给予高奖励。在实践中,KL散度通过从两个分布中进行采样来近似。最终传递给强化学习更新规则的奖励如下:

https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/312.png

一些RLHF系统已经将额外的术语纳入奖励函数。例如,OpenAI的InstructGPT成功尝试将额外的预训练梯度(来自人类标注集)融合到PPO的更新规则中。预计随着RLHF的继续研究,这个奖励函数的公式将继续演变。

最后,更新规则是PPO从当前数据批次中优化奖励指标参数的更新(PPO是按策略的,意味着参数只更新当前批次的提示生成对)。PPO是一种信任域优化算法,它通过约束梯度来确保更新步骤不会破坏学习过程。DeepMind为Gopher采用了类似的奖励设置,但使用了同步优势演员。

https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/B18949_07_6.jpg

图7.6 – 使用强化学习微调模型

前面的图表可能表明,两个模型对相同的提示产生了不同的响应,但实际上,强化学习策略生成文本,然后将其提供给初始模型以推导其相对概率,用于KL惩罚。

可选地,RLHF可以通过周期性地更新奖励模型和政策来从这一阶段进一步发展。随着强化学习策略的演变,用户可以保持这些输出与模型先前版本的排名。然而,大多数论文尚未解决这一操作的实现,因为收集此类数据所需的部署模式仅适用于能够访问活跃用户基础的对话代理。Anthropic将这种替代方案称为迭代在线RLHF(如原文所述),其中策略的迭代被纳入模型之间的Elo排名系统。这带来了策略和奖励模型演变的复杂动态,代表了一个复杂且未解决的问题。在下一节中,我们将解释一些RLHF的知名开源工具。

GPT-4

在撰写本书时,我们对GPT-4模型设计所知甚少。由于OpenAI缓慢地透露信息,我们假设GPT-4不是一个单一模型,而是八个220亿参数模型的组合,这一假设得到了AI社区关键人物的证实。这一假设表明OpenAI使用了“专家混合”策略,这是一种ML设计策略,其历史甚至可以追溯到LLMs之前。然而,尽管我们,作为作者,支持这一假设,但它尚未得到OpenAI的官方确认。

尽管存在猜测,但GPT-4令人印象深刻的性能是无可否认的,无论其内部结构如何。它在写作和编码任务上的能力是显著的,而它是一个模型还是八个捆绑在一起,并不改变其影响。

一种常见的说法是,OpenAI巧妙地管理了人们对GPT-4的期望,专注于其能力,并因竞争压力而未披露规格。围绕GPT-4的保密性使许多人相信它是一个科学奇迹。

LLaMA

Meta 已公开发布 LLaMA,这是一个高性能的大型语言模型(LLM),旨在帮助 AI 研究人员。这一举措使得那些有限访问广泛基础设施的个人能够检查这些模型,从而扩大了在这个快速发展的领域的访问。

LLaMA 模型之所以吸引人,是因为它们需要的计算能力和资源显著减少,这使得探索新的方法和用例成为可能。这些模型有多种尺寸,旨在针对各种任务进行微调,并且是在负责任的 AI 实践中开发的。

尽管大型语言模型(LLMs)取得了进步,但由于训练和运行它们所需的资源有限,它们的研究可访问性有限。在更多标记上训练的较小模型,如 LLaMA,更容易重新训练和调整以适应特定用例。

与其他模型类似,LLaMA 以一系列单词作为输入来预测下一个单词并生成文本。尽管它具有强大的功能,但 LLaMA 在偏见、有害评论和幻觉方面与其他模型面临相同的挑战。通过共享 LLaMA 的代码,Meta 使研究人员能够测试在大型语言模型(LLMs)中解决这些问题的新的方法。

Meta 强调了在 AI 社区内部建立关于负责任 AI 和 LLMs 的指导方针的必要性。他们预计 LLaMA 将促进该领域的新的学习和开发。

PaLM

PaLM 是一个拥有 5400 亿参数、密集激活的 Transformer 语言模型(LM),它使用 Pathways 这个新的机器学习系统在 6144 个 TPU v4 芯片上进行了训练,该系统使得跨多个 TPU pod 的训练效率极高。

已有研究表明,PaLM 在各种自然语言任务上实现了突破性的性能,包括以下方面:

  • 多步骤推理任务

  • 最近发布的 超越模仿游戏 基准(BIG-bench

  • 多语言任务

  • 源代码生成

BIG-bench基准测试值得进一步探讨,因为它作为公认的基准测试集合,用于衡量各种性能。BIG-bench是一个专门为大规模语言模型设计的广泛评估机制。它是一个基于广泛、社区关注的基准,提供了各种任务来评估模型在不同学科中的性能,以及其在自然语言理解、问题解决和推理方面的能力。总共有来自132个机构的450位贡献者提交的204个任务,BIG-bench涵盖了包括语言学、儿童发展、数学、常识推理、生物学、物理学、软件开发甚至社会偏见在内的多种主题。它专注于被认为目前超出现有语言模型能力范围的问题。BIG-bench的主要目标超越了简单的模仿或图灵测试风格的评估,而是旨在对大型模型的能力和限制进行更深入、更细致的评价。这一倡议基于这样的信念:一种开放、协作的评估方法为更全面地理解这些语言模型及其潜在的社会影响铺平了道路。

PaLM 540B在多种多步推理任务上超越了经过微调的最先进状态,并在BIG-bench基准测试中超越了平均人类表现。随着PaLM扩展到其最大规模,许多BIG-bench任务在性能上实现了显著飞跃,显示出从模型规模到性能的连续改进。PaLM在多语言任务和源代码生成方面也具有强大的能力。例如,PaLM可以在50种语言之间进行翻译,并且可以生成多种编程语言的代码。

PaLM论文的作者还讨论了与大型语言模型相关的伦理考量,并讨论了潜在的缓解策略。例如,他们建议,了解大型语言模型中潜在的偏见是很重要的,并且开发检测和缓解偏见的技术的也很重要。

PaLM架构

PaLM采用传统的Transformer模型架构,在解码器专用设置中,允许每个时间步只关注自身和前一时间步。对此设置进行了以下几项修改:

  • SwiGLU激活函数:与标准的ReLU、GeLU或Swish激活函数不同,PaLM使用SwiGLU激活函数(Swish(xW) · xV)作为多层感知器MLP)的中间激活函数,因为它们在提升质量方面表现出更优越的性能。然而,这种方法在MLP中需要三个矩阵乘法,而传统方法只需要两个。

  • 并行层:不同于典型的“序列化”方法,PaLM为每个Transformer块使用“并行”公式。

    标准结构如下:

    https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/313.png

    并行结构如下:

    https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/314.png

    由于MLP和注意力输入矩阵乘法的融合,这在大规模上导致大约15%的训练速度提升。

  • 多查询注意力:在传统的Transformer公式中,使用k个注意力头。对于每个时间步,输入向量被线性投影到查询、键和值张量,这些张量的形状为[k, h],其中h*表示注意力头的大小。在新方法中,“键”和“值”的投影在所有头之间共享,这意味着“键”和“值”被投影到[1, h],而“查询”保持[k, h]的形状。作者声称,这种方法不会显著影响模型质量或训练速度,但在自回归解码期间它确实导致了显著的成本降低。原因在于标准多头注意力在加速器硬件上的低效,因为在自回归解码期间,键/值张量没有在示例之间共享,并且每次只解码一个标记。

  • 旋转位置嵌入(RoPE)嵌入:RoPE嵌入在较长的序列长度上表现出更好的性能,因此比绝对或相对位置嵌入更受欢迎。

  • 共享输入-输出嵌入:输入和输出嵌入矩阵是共享的,这种做法在先前的工作中很常见,尽管并非普遍存在。

  • 无偏差:该模型避免在任何密集核或层归一化中使用偏差,这增强了大型模型的训练稳定性。

  • 词汇表:PaLM使用256k-token SentencePiece词汇表,该词汇表专为训练语料库中的多种语言设计,确保高效训练而不会过度标记化。这保留了所有空白字符和词汇表外的Unicode字符,同时将数字拆分为单个数字标记以提高清晰度。

总体而言,PaLM是一个功能强大的LM,具有广泛应用的潜力。它仍在开发中,但已经证明了在多个任务上实现突破性性能的能力。

用于RLHF的开源工具

OpenAI在2019年发布了第一个用于执行RLHF的开源代码。他们已经实施了这种方法来改进GPT-2,用于不同的用例,如摘要。根据人类反馈,该模型经过优化,其输出与人类相似,例如复制笔记的部分内容。有关此项目的更多信息,请参阅以下链接:https://openai.com/research/fine-tuning-gpt-2.

代码也可以在以下链接找到:https://github.com/openai/lm-human-preferences.

Transformer强化学习TRL)是一个为在Hugging Face生态系统中使用PPO微调预训练LM的工具。由CarperAI开发的增强分支TRLX能够处理在线和离线训练的大规模模型。目前,TRLX配备了支持RLHF的PPO和隐式语言Q学习ILQL)的生产就绪API,可用于部署高达330亿参数的LLMs。TRLX的未来版本旨在适应高达2000亿参数的LLMs,使其成为在如此规模上工作的ML工程师的理想选择。

另一个很好的库是语言模型强化学习RL4LMs)。RL4LMs项目旨在解决训练LLMs以符合人类偏好指标所面临的挑战。它认识到许多NLP任务可以被视为序列学习问题,但由于强化学习训练不稳定、自动NLP指标的高方差和奖励黑客等问题,其应用受到限制。该项目通过以下方式提供解决方案:

  • 通过一个持续更新的基准GRUE提供关于何时使用强化学习的指南,并建议合适的NLP任务/指标

  • 引入一种新的强化学习算法,自然语言策略优化NLPO),旨在更好地处理大型语言动作空间和奖励方差

  • 提供高质量的实现和强化学习以及其他强化学习算法的超参数,用于在Hugging Face库中训练Transformers。

该项目的代码可以在以下链接找到:https://github.com/allenai/RL4LMs

摘要

在本章中,我们深入探讨了最先进语言模型的动态和复杂世界。我们讨论了它们的出色泛化能力,使它们成为广泛任务的通用工具。我们还强调了理解复杂背景的重要性,在这些模型中,它们通过掌握语言的细微差别和各种主题的复杂性而表现出色。

此外,我们还探讨了RLHF范式及其如何被用于增强语言模型。RLHF通过模拟人类判断来利用标量反馈改进语言模型,从而帮助减轻在NLP任务中遇到的常见陷阱。

我们讨论了与这些模型一起工作的技术要求,强调了在Transformers、强化学习和编码技能等领域拥有基础知识的重要性。

本章还涉及了一些突出的语言模型,如GPT-4和LLaMA,讨论了它们的架构、方法和性能。我们强调了某些库在解释语言模型预测时采用的策略,例如删除某些单词和分析梯度变化。

总结来说,本章全面概述了当前语言模型的状态,探讨了它们的性能、挑战、用于改进它们的方法,以及用于评估和解释它们的不断发展的工具和措施。

参考文献

第八章:访问大型语言模型的力量:高级设置和与RAG的集成

在这个充满活力的人工智能AI)和机器学习ML)时代,理解可用的各种资源并学习如何有效地利用它们至关重要。大型语言模型LLMs)如GPT-4通过在从内容生成到复杂问题解决的各种任务中展现出前所未有的性能,彻底改变了自然语言处理NLP)领域。它们的巨大潜力不仅体现在理解和生成类似人类的文本上,还体现在弥合机器与人类之间的差距,无论是在通信还是任务自动化方面。拥抱LLMs的实际应用能够赋予企业、研究人员和开发者创建更直观、智能和高效的系统,以满足广泛的业务需求。本章将为您提供一个指南,介绍如何设置访问LLMs,并指导您如何使用它们以及如何构建与它们相关的管道。

我们的旅程从深入研究使用应用程序编程接口APIs)的封闭源模型开始,以OpenAI的API作为一个典范示例。我们将通过一个实际场景向您展示,如何使用Python代码中的API密钥与该API交互,并展示此类模型在现实世界中的应用潜力。

随着我们不断前进,我们将把焦点转向开源工具的领域,向您介绍一些广泛使用的开源模型,这些模型可以通过Python进行操作。我们的目标是让您了解这些模型提供的力量和多功能性,强调开源开发的社区驱动优势。

随后,我们将向您介绍检索增强生成,特别是LangChain,这是一个专门为与LLMs交互而设计的强大工具。LangChain对于LLMs的实际应用至关重要,因为它提供了一个统一和抽象的接口,以及一系列工具和模块,这些工具和模块简化了LLM驱动应用程序的开发和部署。我们将引导您了解LangChain的基础概念,突出其独特的解决LLMs固有挑战的方法。

这种方法的基石是将数据转换为嵌入。我们将阐明语言模型LMs)和LLMs在这次转换中扮演的关键角色,展示它们如何参与创建这些嵌入。随后,我们将讨论建立本地向量数据库的过程,为您简要概述向量数据库及其在管理和检索这些嵌入中的关键作用。

然后,我们将讨论用于提示的LLM的配置,这可能与用于嵌入过程的LLM相同。我们将逐步引导您进行设置过程,详细说明这种策略的优势和潜在应用。

在最后一部分,我们将涉及将LLM部署到云的话题。云服务的可扩展性和成本效益导致了托管AI模型采用率的增加。我们将概述领先的云服务提供商,包括Microsoft AzureAmazon Web ServicesAWS)和Google Cloud PlatformGCP),并为您提供关于他们的服务提供方式和如何利用它们进行LLM部署的见解。

在我们开始探索LLM的过程中,承认这些模型运行在其内的数据景观的持续演变至关重要。数据的动态特性——其体积、多样性和复杂性的增长——需要我们采取前瞻性的方法来开发、部署和维护LLM。在随后的章节中,特别是第10章,我们将深入探讨这些演变数据景观的战略影响,为您准备应对它们带来的挑战和机遇。这种基础理解不仅将增强您与LLM的即时工作,还将确保您的项目在面对快速的技术和数据驱动变化时保持韧性和相关性。

让我们回顾本章涵盖的主要主题:

  • 设置LLM应用 – 基于API的闭源模型

  • 提示工程和初始化GPT

  • 设置LLM应用 – 本地开源模型

  • 通过Python使用Hugging Face的LLM

  • 探索高级系统设计 – RAG和LangChain

  • 在Jupyter笔记本中回顾简单的LangChain设置

  • 云端LLM

技术要求

对于本章,以下将是必需的:

  • 编程知识:熟悉Python编程是必需的,因为开源模型、OpenAI的API和LangChain都是使用Python代码进行说明的。

  • 访问OpenAI的API:探索闭源模型需要OpenAI的API密钥。这可以通过在OpenAI创建账户并同意他们的服务条款来获得。

  • 开源模型:需要访问本章中提到的特定开源模型。这些模型可以通过各自的存储库或通过包管理器如pipconda访问和下载。

  • 本地开发环境:需要一个安装了Python的本地开发环境。可以使用集成开发环境IDE)如PyCharm、Jupyter Notebook或简单的文本编辑器。请注意,我们推荐使用免费的Google Colab笔记本,因为它将这些要求封装在一个无缝的网页界面中。

  • 安装库的能力:你必须有权安装所需的Python库,例如NumPy、SciPy、TensorFlow和PyTorch。请注意,我们提供的代码中包含了所需的安装,你不需要事先安装它们。我们只是强调你应该有权这样做,我们预期你会这样做。具体来说,使用免费的Google Colab笔记本就足够了。

  • 硬件要求:根据你正在处理的模型复杂性和大小,你需要一台具有足够处理能力(可能包括用于机器学习任务的优秀GPU)和充足内存的计算机。这仅在你选择不使用免费的Google Colab时相关。

现在我们已经了解了LLM的变革潜力以及可用的各种工具,让我们更深入地探讨如何有效地使用API设置LLM应用程序。

设置LLM应用程序 - 基于API的闭源模型

当考虑使用模型(特别是LLM)时,有各种设计选择和权衡。一个关键的选择是是否在本地环境中托管模型,还是通过通信渠道远程使用它。本地开发环境将是你代码运行的地方,无论是你的个人电脑、本地服务器、云环境,等等。你的选择将影响许多方面,如成本、信息安全、维护需求、网络过载和推理速度。

在本节中,我们将介绍一种快速简单的方法,通过API远程使用LLM。这种方法快速简单,因为它免除了我们为本地托管LLM而分配不寻常的计算资源的需求。LLM通常需要大量的内存和计算资源,这在个人环境中并不常见。

选择远程LLM提供商

在深入实施之前,我们需要选择一个与我们的项目需求相匹配的合适的LLM(大型语言模型)提供商。例如,OpenAI提供了GPT-3.5和GPT-4的多个版本,并配有全面的API文档。

通过API在Python中访问OpenAI的远程GPT

要获取OpenAI的LLM API访问权限,我们需要在他们的网站上创建一个账户。这个过程包括注册、账户验证和获取API凭证。

OpenAI的网站提供了这些常见操作的指导,你将能够快速设置好。

注册后,我们应该熟悉OpenAI的API文档。这份文档将指导我们了解与LLM交互的各种端点、方法和参数。

我们将要进行的第一个动手实践将是通过 Python 使用 OpenAI 的 LLMs。我们准备了一个笔记本,展示了通过 API 使用 OpenAI 的 GPT 模型的简单步骤。请参考 Ch8_Setting_Up_Close_Source_and_Open_Source_LLMs.ipynb 笔记本。这个名为 设置近源和开源 LLMs 的笔记本将在当前关于 OpenAI API 的章节中使用,也将在后续关于设置本地 LLMs 的章节中使用。

让我们逐步分析代码:

  1. 我们首先安装所需的 Python 库。特别是,为了与 LLM API 进行通信,我们需要安装必要的 Python 库:

    !pip install --upgrade openai
    
  2. 定义 OpenAI 的 API 密钥:在向 LLM API 发送请求之前,我们必须将我们的个人 API 密钥嵌入到库的配置中。当你注册 OpenAI 时,API 密钥会在 OpenAI 的网站上提供给你。这可以通过将密钥的字符串明确粘贴到我们的代码中以硬编码,或者从包含该字符串的文件中读取它来完成。请注意,前者是展示 API 的最简单方式,因为它不需要设置额外的文件,但在共享开发环境中工作时可能不是最佳选择:

    openai.api_key = "<your key>"
    
  3. 设置 – 设置模型的配置。在这里,我们设置控制模型行为的各种参数。

在为通过 API 连接到 LLMs 奠定基础后,将我们的注意力转向同样重要的一个方面——提示工程和预处理,这是与这些模型有效沟通的艺术。

提示工程和 GPT 预处理

在返回讨论代码的下一部分之前,让我们暂停并提供一些背景信息。

提示工程是 NLP 中用于设计有效提示或指令的技术,当与 LLMs 交互时使用。它涉及精心设计提供给模型的输入,以产生期望的输出。通过在提示中提供特定的提示、上下文或约束,提示工程旨在引导模型的行为,并鼓励生成更准确、相关或针对性的响应。这个过程通常涉及迭代优化、实验,并理解模型的优势和局限性,以优化提示,提高在各种任务(如问答、摘要或对话生成)中的性能。有效的提示工程在利用 LMs 的能力以及塑造其输出以满足特定用户需求方面发挥着至关重要的作用。

让我们回顾一下提示工程中最具影响力的工具之一,启动。通过API启动GPT涉及在生成响应之前向模型提供初始上下文。启动步骤有助于设定生成内容的方向和风格。通过提供与所需输出相关的相关信息或示例,我们可以引导其理解并鼓励更专注和连贯的响应。启动可以通过包含特定指令、上下文,甚至与预期结果一致的片段句子来实现。有效的启动可以增强模型生成与用户意图或具体要求更匹配的响应的能力。

通过引入GPT和几种类型的信息来进行启动:

  • 主要信息是系统提示。这条信息指导模型关于可能扮演的角色,它应该如何回答问题,可能面临的约束等等。

  • 第二种信息类型是用户提示。用户提示在启动阶段发送给模型,它代表一个示例用户提示,就像您可能在ChatGPT的网页界面中输入的提示一样。然而,在启动时,这条消息可以展示给模型作为如何处理此类提示的示例。开发者将引入某种用户提示,然后展示模型如何预期回答该提示。

    例如,观察以下启动代码:

    response = client.chat.completions.create(
        model="gpt-3.5-turbo",
        messages=[
               {"role": "system",
                   "content": "You are a helpful assistant. You provide short answers and you format them in Markdown syntax"},
                  {"role": "user",
                   "content": "How do I import the Python library pandas?"},
                  {"role": "assistant",
                   "content": "This is how you would import pandas:  \n```\nimport pandas as pd\n```py"},
                  {"role": "user",
                   "content": "How do I import the python library numpy?"}
            ])
    text = response.choices[0].message.content.strip()
    print(text)
    )
    

    这是输出:

    To import numpy, you can use the following syntax: 
    ```python
    
    import numpy as np
    
    ```py
    

您可以看到我们启动模型以提供Markdown格式的简洁答案。用于教导模型的示例是问题和答案的形式。问题是通过用户提示,而我们告诉模型潜在答案的方式是通过助手提示。然后我们向模型提供另一个用户提示;这是我们要模型为我们处理的实际提示,如输出所示,它回答正确。

通过查看OpenAI关于提示工程的文档,你会发现还有其他类型的提示可以用来启动GPT模型。

回到我们的笔记本和代码,在这个部分,我们利用GPT-3.5 Turbo。我们以最简单的方式启动它,只给它一个系统提示来提供方向,以展示系统提示如何产生额外的功能。我们告诉模型通过提醒我们提示中的错误并纠正它们来完成响应。

然后我们在用户提示部分提供我们想要的提示,并在其中插入一些错误。运行那段代码并尝试一下。

尝试OpenAI的GPT模型

在这个阶段,我们向模型发送我们的提示。

以下简单的示例代码在设置近源和开源LLMs笔记本中运行一次。您可以将它封装在一个函数中,并在自己的代码中重复调用它。

值得注意的一些方面如下:

  • 解析和处理模型返回的输出:我们以连贯的方式结构化输出响应,以便用户阅读:

    print(f"Prompt: {user_prompt_oai}\n\n{openai_model}'s Response: \n{response_oai}")
    
  • 错误处理:我们设计代码允许在接受API使用失败之前进行多次尝试:

    except Exception as output:
        attempts += 1
        if attempts >= max_attempts:
            []
    
  • 速率限制和成本缓解:我们在这里没有实施此类限制,但在实验设置中,也许在生产环境中,同时拥有这两者将是理想的。

    以下代码的结果展示如下:

    Prompt: If neuroscience could extract the last thoughts a person had before they dyed, how would the world be different?
    gpt-3.5-turbo's Response:
    If neuroscience could extract the last thoughts a person had before they died, it would have profound implications for various aspects of society.
    This ability could potentially revolutionize fields such as psychology, criminology, and end-of-life care.
    Understanding a person's final thoughts could provide valuable insights into their state of mind, emotional well-being, and potentially help unravel mysteries surrounding their death.
    It could also offer comfort to loved ones by providing a glimpse into the innermost thoughts of the deceased.
    However, such technology would raise significant ethical concerns regarding privacy, consent, and the potential misuse of this information.
    Overall, the world would be both fascinated and apprehensive about the implications of this groundbreaking capability.
    Typos in the prompt:
    1\. "dyed" should be "died"
    2\. "diferent" should be "different"
    Corrections:
    If neuroscience could extract the last thoughts a person had before they died, how would the world be different?
    

模型为我们提供了一个合法、简洁的响应。然后它通知我们有关错别字,这与我们提供给它的系统提示完全一致。

那是一个展示远程、场外、闭源LLM应用的例子。虽然利用像OpenAI提供的付费API的强大功能提供了便利和尖端性能,但挖掘免费开源LLM的潜力同样巨大。让我们接下来探索这些成本效益高的替代方案。

设置LLM应用程序 - 本地开源模型

现在,我们将讨论闭源实现的补充方法,即开源、本地实现。

我们将看到您如何在不注册账户、付费或与第三方供应商(如OpenAI)共享可能包含敏感信息的提示的情况下,实现与上一节中我们审查的类似的功能结果。

关于区分开源和闭源的不同方面

在选择开源LLM(如LLaMA和GPT-J)和闭源、基于API的模型(如OpenAI的GPT)之间时,必须考虑几个关键因素。

首先,成本是一个主要因素。开源LLM通常没有许可费用,但它们需要大量的计算资源进行训练和推理,这可能很昂贵。闭源模型虽然可能收取订阅费或按使用付费的费用,但消除了对大量硬件投资的必要性。

处理速度和维护与计算资源密切相关。如果部署在足够强大的系统上,开源LLM可以提供高速处理,但需要实施团队持续维护和更新。相比之下,由提供商管理的闭源模型确保持续的维护和模型更新,通常效率更高,停机时间更短,但处理速度可能取决于提供商的基础设施和网络延迟。

关于模型更新,开源模型提供了更多控制权,但需要主动方法来整合最新的研究和改进。然而,闭源模型由提供商定期更新,确保用户无需额外努力即可访问最新的进展。

在这两种情况下,安全和隐私都是至关重要的。开源模型可能更安全,因为它们可以在私有服务器上运行,确保数据隐私。然而,它们需要强大的内部安全协议。由外部提供商管理的闭源模型通常带有内置的安全措施,但由于第三方处理数据,可能存在潜在的隐私风险。

总体而言,开源和闭源语言模型(LLM)之间的选择取决于成本、控制和便利性之间的权衡,每种选择都有一套自己的优势和挑战。

考虑到这一点,让我们重新审视 Hugging Face,这家公司汇集了最大的、最易于访问的免费语言模型(LM)中心。在下面的示例中,我们将利用 Hugging Face 简便且免费的库:transformers。

Hugging Face 的模型中心

当我们寻找为我们任务选择一个 LLM 时,我们建议参考 Hugging Face 的在线模型页面。他们提供了大量的基于 Python 的开源 LLM。每个模型都有一个专门的页面,您可以在这里找到有关它的信息,包括在您的个人环境中通过 Python 代码使用该模型所需的语法。

应该注意的是,为了在本地实现模型,您必须从运行 Python 代码的机器上拥有互联网连接。然而,由于这个要求在某些情况下可能成为瓶颈——例如,当开发环境受到公司内部网络的限制或由于防火墙限制而有限的互联网访问时——存在其他方法。我们推荐的方法是从 Hugging Face 的域名克隆模型仓库。这是一个不那么简单且不太常用的方法。Hugging Face 在每个模型的网页上提供了必要的克隆命令。

选择模型

当寻找模型时,可能会有几个因素需要考虑。根据您的意图,您可能关心配置速度、处理速度、存储空间、计算资源、法律使用限制等。另一个值得注意的因素是模型的流行度。它证明了该模型在社区中其他开发者中被选择的频率。例如,如果您寻找标记为零样本分类的 LMs,您将找到一个非常大的可用模型集合。但是,如果您进一步缩小搜索范围,以便只剩下在新闻文章数据上训练的模型,您将只剩下更小的可用模型集合。在这种情况下,您可能需要参考每个模型的流行度,并从使用最频繁的模型开始您的探索。

其他可能引起你兴趣的因素可能包括关于该模型的出版物、模型的开发者、发布该模型的公司或大学、模型训练所使用的数据集、模型设计的架构、评估指标,以及在每个模型在Hugging Face网站上网页上可能存在的其他潜在因素。

通过Python使用Hugging Face的LLMs

现在,我们将回顾一个代码笔记本,它展示了如何使用Hugging Face的免费资源在本地实现开源LLM。我们将继续使用上一节中相同的笔记本,设置近源和开源LLMs

  1. 在终端上使用pip,我们将运行以下命令:

    pip install –upgrade transformers
    

    如果直接从Jupyter笔记本运行,请在命令的开头添加!

  2. 实验Microsoft的DialoGPT-medium:这个LLM专注于对话应用。它由Microsoft生成,在与其他LLMs的常见基准比较中取得了高分。因此,它在Hugging Face平台上也非常受欢迎,从ML开发者的角度来看,它经常被下载。

  3. 在笔记本中的设置代码部分,我们将定义此代码的参数并导入模型及其分词器:

    hf_model = "microsoft/DialoGPT-medium"
    max_length = 1000
    tokenizer = AutoTokenizer.from_pretrained(hf_model)
    model = AutoModelForCausalLM.from_pretrained(hf_model)
    

    注意,此代码需要访问互联网。即使模型是本地部署的,也需要互联网连接来导入它。再次提醒,如果你愿意,你可以从Hugging Face克隆模型的repo,然后不再需要访问互联网。

  4. 定义提示:如以下代码块所示,我们在这里选择了简单的提示,类似于GPT-3.5-Turbo模型的用户提示。

  5. 实验模型:在这里,我们有适合此代码的语法。如果你想与该模型进行滚动对话,你可以将此代码包裹在一个函数中,并实时收集用户的提示。

  6. 结果:生成的提示是,如果恐龙今天还活着,它们会对人类构成威胁吗

    microsoft/DialoGPT-medium's Response:
    I think they would be more afraid of the humans
    

本节确立了LLMs可以带来的巨大价值主张。我们现在有了学习和探索高效LLM应用开发新前沿的必要背景——使用LangChain等工具构建管道。让我们深入了解这种方法。

探索高级系统设计——RAG和LangChain

检索增强生成RAG)是一个专为与LLMs无缝交互而设计的开发框架。由于LLMs具有通用性,它们能够胜任大量任务。然而,它们的通用性往往阻止它们对需要特定知识或深入领域专业知识的问题提供详细、细微的响应。例如,如果你希望使用LLM来回答有关特定学科(如法律或医学)的查询,它可能能够满意地回答一般性查询,但可能无法准确回答需要详细见解或最新知识的问题。

RAG设计为LLM处理中通常遇到的限制提供了一个全面的解决方案。在RAG框架中,文本语料库经过初步预处理,被分割成摘要或独立的块,然后嵌入到向量空间中。当提出查询时,模型识别出这些数据中最相关的部分,并利用它们来形成响应。这个过程涉及离线数据预处理、在线信息检索以及应用LLM进行响应生成的应用。这是一个灵活的方法,可以适应各种任务,包括代码生成和语义搜索。RAG模型作为一个抽象层,协调这些过程。这种方法的有效性正在不断提高,其应用范围随着LLMs的发展而扩大,在提示处理过程中需要更多上下文丰富的数据。在第10章中,我们将更深入地讨论RAG模型及其在LLM解决方案未来中的作用。

现在我们已经介绍了RAG模型的前提和功能,让我们专注于一个特定的例子,称为LangChain。我们将回顾其设计原则的细节以及它是如何与数据源交互的。

LangChain的设计理念

在本节中,我们将剖析使LangChain脱颖而出的核心方法和架构决策。这将使我们深入了解其结构框架、数据处理效率以及其将LLMs与各种数据源集成的创新方法。

数据源

LangChain最显著的优点之一是能够将任意LLM连接到定义好的数据源。这里的“任意”意味着它可以是任何现成的LLM,这些LLM的设计和训练没有针对我们想要连接的数据进行特定的考虑。使用LangChain允许我们根据我们的领域进行定制。数据源在构建用户提示的答案时用作参考。这些数据可能是公司拥有的专有数据,也可能是个人机器上的本地个人信息。

然而,当涉及到利用特定的数据库时,LangChain所做的不仅仅是将LLM指向数据;它采用特定的处理方案,使其快速高效。它创建一个向量数据库。

对于原始文本数据,无论是.txt文件中的自由文本、格式化文件还是其他各种文本数据结构,通过将文本分割成适当长度并使用指定的模型创建数值文本嵌入,创建一个向量数据库。请注意,如果指定的嵌入模型选择为LLM,它不需要与用于提示的LLM相同。例如,嵌入模型可以选择为免费、次优的开源LLM,而提示模型可以是具有最佳性能的付费LLM。这些嵌入随后存储在向量数据库中。您可以看到,这种方法非常节省存储空间,因为我们将文本和可能的编码文本转换成有限的一组数值,其本质上是密集的。

当用户输入提示时,搜索机制会在嵌入的数据源中识别相关的数据块。提示使用相同的指定嵌入模型进行嵌入。然后,搜索机制应用相似度度量,例如余弦相似度,并找到定义的数据源中最相似的文字块。然后,检索这些块的原文本。然后将原始提示再次发送,这次发送到提示LLM。区别在于,这次提示不仅包括原始用户的提示,还包括作为参考检索到的文本。这使得LLM能够获得问题和丰富的文本补充作为参考。然后,LLM可以参考添加的信息作为参考。

如果没有这个设计,当用户想要找到他们问题的答案时,他们需要阅读大量的材料并找到相关的部分。例如,这些材料可能是一家公司整个产品方法,包括许多PDF文档。这个过程利用了自动智能搜索机制,将相关材料缩小到可以放入提示中的文本量。然后,LLM构建问题的答案并立即呈现给用户。如果您愿意,可以将管道设计为引用构建答案时使用的原始文本,从而实现透明度和验证。

这个范式在图8.1中展示:

.

https://github.com/OpenDocCN/freelearn-dl-zh/raw/master/docs/ms-nlp-fund-llm/img/B18949_08_1.jpg

图8.1 – 典型LangChain管道的范式

为了解释LangChain管道背后的提示工程,让我们回顾一个金融信息用例。您的数据源是美国上市公司的证券 & 交易所 委员会SEC)的文件集合。您正在寻找向股东发放股息的公司及其年份。

你的提示如下:

Which filings mention that the company gave dividends in the year 2023?

流水线随后将这个问题嵌入其中,寻找具有相似上下文的文本块(例如,讨论派息的)。它识别了许多这样的块,如下所示:

"Dividend Policy. Dividends are paid at the discretion of the Board of Directors. In fiscal 2023, we paid aggregate quarterly cash dividends of $8.79 per share […]"

LangChain流水线随后形成一个新的提示,其中包含已识别块的文字。在这个例子中,我们假设被提示的LLM是OpenAI的GPT。LangChain将信息嵌入到发送给OpenAI GPT模型的系统提示中:

"prompts": [
    "System: Use the following pieces of context to answer the user's question. \nIf you don't know the answer, just say that you don't know, don't try to make up an answer.\n----------------\n Dividend Policy. Dividends are paid at the […]"
]

如我们所见,系统提示用于指导模型如何行动,并提供上下文。

既然我们已经了解了LangChain的基础方法和好处,让我们更深入地探讨其复杂的设计概念,从它如何高效地将LLMs与各种数据源桥接开始。

未预先嵌入的数据

虽然前面的描述是关于预处理成向量数据库形式的数据,但另一种方法是设置访问尚未处理成嵌入形式的外部数据源。例如,你可能希望利用SQL数据库来补充其他数据源。这种方法被称为多个****检索源

我们现在已经探讨了LangChain如何高效地与各种数据源接口;现在,理解其功能的核心结构元素至关重要——链和代理。

LangChain内部的原子构建块被称为组件。典型的组件可能包括提示模板、访问各种数据源以及访问LLMs。当将各种组件组合成系统时,我们形成了一个链。一个链可以代表一个完整的由LLM驱动的应用程序。

现在,我们将介绍代理的概念,并通过一个代码示例展示链和代理如何结合在一起,创建出不久前相当复杂的功能。

代理

在链之上,下一层复杂性是代理。代理通过使用链并辅以额外的计算和决策来利用链。虽然链可能对简单的请求提示产生响应,但代理会处理响应并根据规定的逻辑进行进一步的下层处理。

你可以将代理视为一种推理机制,它使用我们所说的工具。工具通过将LLMs与其他数据或功能连接起来来补充LLMs。

由于典型的LLM缺陷阻止了LLMs成为完美的多任务执行者,代理以规定和监控的方式使用工具,使它们能够检索必要的信息,将其作为上下文,并使用指定的现有解决方案执行操作。然后代理观察结果并使用规定的逻辑进行进一步的下层处理。

例如,假设我们想要计算我们地区一名普通初级程序员的薪资轨迹。这个任务由三个关键子任务组成——找出平均起薪是多少,确定薪资增长的因素(例如,生活成本的变动或典型的绩效提升),然后进行预测。一个理想的LLM能够独立完成整个过程,不需要比一个连贯的提示更多的东西。然而,考虑到典型的缺陷,如幻觉和有限的训练数据,当前的LLM无法达到可以在商业产品中商业化的水平。一种最佳实践是将任务分解,并通过代理监控思维过程。

在其最简单的设计中,这需要以下步骤:

  1. 定义一个可以访问互联网并能根据增长因子计算时间序列未来值的代理

  2. 为代理提供全面的提示

  3. 代理将提示分解为不同的子任务:

    1. 从互联网上获取平均工资

    2. 获取增长因子

    3. 通过应用增长因子到起始薪资并创建薪资值的未来时间序列来使用计算工具

为了说明代理方法,让我们回顾一个简单的任务,该任务涉及从网络上获取特定细节,并使用它来进行计算。

  1. 首先,安装以下包:

    !pip install openai
    !pip install wikipedia
    !pip install langchain
    !pip install langchain-openai
    
  2. 然后,运行以下代码:

    from langchain.agents import load_tools, initialize_agent
    from langchain_openai import OpenAI
    import os
    os.environ["OPENAI_API_KEY"] = "<your API key>"
    llm = OpenAI(model_name='gpt-3.5-turbo-instruct')
    tools = load_tools(["wikipedia", "llm-math"], llm=llm)
    agent = initialize_agent(tools, llm=llm, agent="zero-shot-react-description", verbose=True)
    agent.run("Figure out how many pages are there in the book Animal Farm. Then calculate how many minutes would it take me to read it if it takes me two minutes to read one page.")
    

    输出结果如下所示:

    > Finished chain.
    'It would take me approximately 224 minutes or 3 hours and 44 minutes to read Animal Farm.'
    

注意,我们没有应用任何方法来固定LLM以重现这个确切响应。再次运行此代码将产生略微不同的答案。

在下一章中,我们将更深入地探讨几个带有代码的示例。特别是,我们将编写一个多代理框架,其中一组代理正在共同完成一个项目。

长期记忆和引用先前对话

另一个非常重要的概念是长期记忆。我们讨论了LangChain如何通过附加额外的数据源来补充LLM的知识,其中一些可能属于专有数据,使其针对特定用例高度定制化。然而,它仍然缺少一个非常重要的功能,即引用先前对话并从中学习的能力。例如,你可以为项目经理设计一个助手。随着用户与之互动,他们理想情况下会每天更新工作进度、互动、挑战等内容。如果助手能够消化所有这些新积累的知识并保持其持续性,那就更好了。这将允许出现以下场景:

  • 用户:“关于吉姆团队的任务,我们目前处于什么位置?”

  • 助手:“根据原始路线图,吉姆团队应该处理客户对原型设计的反馈。根据上周的更新,客户只提供了部分反馈,您认为这还不足以让吉姆团队开始工作。”

我们将在下一章中更深入地探讨记忆的概念。

通过增量更新和自动化监控确保持续的相关性

为了在动态信息环境中保持 LLM 输出的准确性和相关性,实施持续更新和维护向量数据库的策略至关重要。随着知识库的持续扩展和演变,作为 LLM 响应基础的嵌入也必须如此。采用增量更新技术允许这些数据库在新的信息可用时刷新其嵌入,确保 LLMs 可以提供最准确和最新的响应。

增量更新涉及定期重新嵌入现有数据源的最新信息。这个过程可以自动化,以扫描数据源中的更新,重新嵌入新的或更新的内容,然后将这些更新的嵌入集成到现有的向量数据库中,无需进行全面的重构。通过这样做,我们确保数据库反映了最当前的知识,增强了 LLM 提供相关和细微响应的能力。

自动监控在这个生态系统中发挥着关键作用,它通过持续评估 LLM 输出的质量和相关性。这涉及到建立跟踪 LLM 性能的系统,识别由于信息过时或缺失上下文而导致响应可能不足的区域。当发现这些差距时,监控系统可以触发增量更新过程,确保数据库始终是当前知识格局的稳健和准确反映。

通过采用这些策略,我们确保 LangChain 和类似的 RAG 框架能够随着时间的推移保持其有效性。这种方法不仅增强了 LLM 应用程序的相关性,还确保它们能够适应信息快速发展的格局,保持其在 NLP 技术前沿的位置。

我们现在可以亲身体验 LangChain。

在 Jupyter 笔记本中回顾简单的 LangChain 设置

现在,我们已经准备好设置一个完整的管道,该管道可以后来用于各种 NLP 应用程序。

请参阅 Ch8_Setting_Up_LangChain_Configurations_and_Pipeline.ipynb 笔记本。这个笔记本实现了 LangChain 框架。我们将一步一步地走过它,解释不同的构建块。在这里,我们选择了一个简单的用例,因为这段代码的主要目的是展示如何设置 LangChain 管道。

在这个场景中,我们处于医疗保健行业。我们有许多护理者;每位护理者都有许多他们可能看到的病人。首席医师代表医院内的所有医师提出请求,希望能够跨他们的笔记进行智能搜索。他们了解到 LLMs 的新兴功能,并希望拥有一个工具,可以在他们编写的医疗报告中进行搜索。

例如,一位医生说了以下内容:

我经常遇到可能与几个月前看过的患者相关的科研,但我记不起那个人是谁。我希望有一个工具,我可以问,‘那个抱怨耳朵疼痛并且有偏头痛家族史的患者是谁?’,然后它会找到那个患者。’

因此,这里的商业目标是以下内容:

CTO要求我们快速构建一个以Jupyter笔记本形式的原型。我们将从医院的数据库中收集几份临床报告,并使用LangChain以示例中描述的医生的方式进行搜索。”

让我们直接进入设计解决方案的Python实现。

使用Python设置LangChain管道

深入LangChain的实际应用,本节将逐步指导您使用Python设置LangChain管道,从安装必要的库到执行复杂的相似性搜索。

安装所需的Python库

和往常一样,我们有一个需要安装的库列表。由于我们将在Jupyter笔记本中编写代码,我们可以从代码中安装它们:

  1. 加载带有模拟医生笔记的文本文件: 在这里,我们准备了一些模拟医生笔记。我们加载并按照LangChain范式处理它们。我们强调,这些不是真实的医疗笔记,那里描述的人并不存在。

  2. 处理数据以便准备嵌入: 在这里,我们根据嵌入模型的要求分割文本。正如我们在前面的章节中提到的,像用于嵌入的LMs这样的模型有一个有限的输入文本窗口,它们可以在单个批次中处理。这个大小是硬编码在其设计架构中,并且对于每个特定模型是固定的。

  3. 创建将存储在向量数据库中的嵌入: 向量数据库是LangChain范式的重要支柱之一。在这里,我们将文本转换为每个项目的嵌入。这些嵌入随后存储在一个专门的向量数据库中。LangChain库允许您使用几个不同的向量数据库。虽然我们选择了一个特定的数据库,但您可以参考向量存储页面了解更多关于不同选择的信息。

  4. 创建向量数据库: 在这里,我们创建向量数据库。这个过程可能因数据库选择的不同而略有不同。然而,这些数据库的创建者确保移除所有困难的工作,并留下一个简单的现成函数,在给定适当的向量形式嵌入的情况下为您创建数据库。我们利用Meta的Facebook AI相似性搜索FAISS)数据库,因为它简单、部署快速且免费。

  5. 基于我们内部文档进行相似度搜索:这是流程中的关键部分。我们提出几个问题,并使用LangChain的相似度搜索来识别最能回答我们问题的医生笔记。

如我们所见,相似度搜索功能能够很好地处理大多数问题。它将问题嵌入并寻找嵌入相似的报告。

然而,当正确回答问题时,相似度搜索只能走这么远。很容易想到一个问题,讨论的是与笔记非常相似的事情,但微小的差异却使相似度搜索机制困惑。例如,相似度搜索过程实际上在第二个问题中犯了一个错误,错误地将不同的月份混淆,从而提供了错误的答案。

为了克服这个问题,我们不仅想要进行相似度搜索。我们希望一个LLM能够审查相似度搜索的结果并应用其判断。我们将在下一章中看到这是如何实现的。

在为LangChain在Python中的实际应用打下基础后,现在让我们继续了解云在其中的关键作用,尤其是在利用当代计算范式中的LLM真正潜力时。

云中的LLM

在大数据和计算时代,云平台已成为管理大规模计算的重要工具,提供可快速部署和释放的基础设施、存储和服务,同时管理努力最小化。

本节将专注于云中的计算环境。这些已成为许多领先公司和机构的首选。作为一个组织,拥有云中的计算环境而不是本地环境,会带来重大差异。它影响资源共享和管理分配、维护和成本的能力。使用云服务而不是拥有物理机器有许多权衡之处。你可以通过在线搜索或甚至询问一个聊天LLM来了解它们。

与云计算相比,一个显著的不同点是提供商围绕其构建的生态系统。当你选择一个云提供商作为你的计算中心时,你将接入一系列额外的产品和服务,开启一个全新的能力世界,这些能力在其他情况下可能无法轻易获得。

在本节中,我们将重点关注这些服务中的LLM(大型语言模型)方面。

三个主要的云平台是AWS、Microsoft Azure和GCP。这些平台提供了一系列服务,满足企业和开发者的不同需求。当涉及到NLP和LLM时,每个平台都提供专门资源和服务,以促进实验、部署和生产。

让我们探索这些平台中的每一个,看看它们如何满足我们的特定需求。

AWS

AWS在云计算领域仍然是一个主导力量,提供了一套全面且不断发展的服务,以满足机器学习和人工智能开发的需求。AWS以其强大的基础设施、广泛的服务提供以及与机器学习工具和框架的深度集成而闻名,使其成为寻求使用LLM进行创新的开发者和数据科学家的首选平台。

在AWS上实验LLM

AWS提供了一套丰富的工具和服务,旨在促进LLM的开发和实验,确保研究人员和开发者能够访问最先进的机器学习能力:

  • Amazon SageMaker:AWS上机器学习的基础,SageMaker是一个全托管服务,它简化了整个机器学习工作流程。它提供Jupyter笔记本实例进行实验,支持广泛的框架,包括TensorFlow和PyTorch,以及一系列用于模型构建、训练和调试的工具。SageMaker的能力不断得到增强,以支持训练和微调LLM的复杂性,提供可扩展的计算选项和优化的机器学习环境。

  • AWS深度学习容器和深度学习AMIs:对于那些希望定制他们的机器学习环境的人来说,AWS提供了预装了流行机器学习框架的深度学习容器和Amazon Machine Images(AMIs)。这些资源简化了LLM实验的设置过程,使得开发者能够专注于创新而不是基础设施配置。

  • 预训练模型和SageMaker JumpStart:AWS通过SageMaker JumpStart扩展了其可访问的预训练模型库,简化了各种自然语言处理任务中LLM的快速实验。JumpStart还提供了解决方案模板和可执行的示例笔记本,使得开发者更容易开始和扩展他们的机器学习项目。

在AWS上部署和产品化LLM

AWS提供了一套旨在高效部署和管理大规模LLM的服务,确保模型在各种负载下易于访问且性能出色:

  • SageMaker端点:为了部署LLM,SageMaker端点提供具有自动扩展功能的全托管托管服务。这项服务允许开发者快速将训练好的模型部署到生产环境中,同时基础设施会自动调整以适应应用程序的需求。

  • 弹性推理和Amazon EC2 Inf1实例:为了优化推理成本,AWS提供了弹性推理服务,它为SageMaker实例增加了GPU驱动的推理加速功能。为了获得更高的性能和成本效率,由AWS Inferentia芯片驱动的Amazon EC2 Inf1实例为深度学习模型提供了高吞吐量和低延迟的推理服务。

  • AWS Lambda和Amazon Bedrock:对于无服务器部署,AWS Lambda支持在无需配置或管理服务器的情况下运行推理,非常适合需求可变的应用程序。Amazon Bedrock代表了向前迈出的重要一步,通过API、模型定制和无缝集成到组织网络中,提供无服务器访问基础模型,确保数据隐私和安全。

让我们继续下一个主题,微软Azure。

微软Azure

微软Azure处于云计算服务的最前沿,为ML和LLMs的开发、部署和管理提供了一个强大的平台。借助其与OpenAI的战略合作伙伴关系,Azure提供了对GPT模型的独家云访问,使其成为旨在利用高级NLP技术的开发人员和数据科学家的重要资源。最近的增强功能扩展了Azure的能力,使其成为那些希望推动AI和ML应用边界的人的更具吸引力的选择。

在Azure上实验LLMs

Azure显著丰富了其产品,以支持LLMs的研究和实验,提供各种工具和平台,满足AI开发社区的多样化需求:

  • Azure OpenAI服务:直接将OpenAI的尖端模型,包括最新的GPT版本、DALL·E和Codex,集成到Azure生态系统中。此服务使开发者能够轻松地将复杂的AI功能集成到他们的应用程序中,同时享有Azure的可伸缩性和管理工具的额外好处。

  • Azure机器学习(Azure ML):这提供了一个高级环境,用于在特定数据集上对LLMs进行定制培训和微调,从而在特定任务上提高了模型性能。Azure ML Studio的预构建和可定制的Jupyter笔记本模板支持广泛的编程语言和框架,简化了实验过程。

  • Azure认知服务:这提供了一系列预构建的AI服务,包括文本分析、语音服务和由LLMs驱动的决策能力。这些服务使开发者能够快速地将复杂的AI功能添加到应用程序中,无需深厚的ML专业知识。

在Azure上部署和商业化LLMs

Azure的基础设施和服务为LLM应用程序的部署和商业化提供了全面的解决方案,确保了可伸缩性、性能和安全性:

  • 部署选项:Azure通过Azure容器实例(ACI)支持各种部署场景,适用于轻量级部署需求,以及Azure Kubernetes服务(AKS)支持更大、更复杂的应用程序,这些应用程序需要高可伸缩性。这些服务允许高效地扩展LLM应用程序以满足用户需求。

  • 模型管理:通过 Azure ML,开发者可以管理其模型的生命周期,包括版本控制、审计和治理。这确保了部署的模型不仅性能出色,而且符合行业标准和管理要求。

  • 安全和合规性:Azure 强调在其所有服务中实现安全和合规性,提供数据加密、访问控制和全面的合规性认证等功能。这种承诺确保在 Azure 上构建和部署的应用程序符合数据保护和隐私的最高标准。

GCP

GCP 继续在云计算领域保持领先地位,提供了一套广泛的服务,以满足人工智能(AI)和机器学习(ML)发展的不断变化的需求。以其在 AI 和 ML 领域的尖端创新而闻名,GCP 提供了一个丰富的工具和服务生态系统,简化了 LLMs 的开发、部署和扩展,使其成为开发者和研究人员利用最新 AI 技术的理想平台。

在 GCP 上实验 LLMs

GCP 进一步增强了其用于实验和开发 LLMs 的功能,提供了一套全面的支持整个 ML 工作流程的工具,从数据摄取和模型训练到超参数调整和评估:

  • Vertex AI:作为 GCP 机器学习产品线的核心,Vertex AI 提供了一套集成的工具和服务,简化了机器学习工作流程。它为训练和微调 LLMs 提供了高级功能,包括用于自动化选择最佳模型架构和超参数的 AutoML 功能。Vertex AI 与 GCP 强大的数据和数据分析服务的集成使得管理对训练 LLMs 至关重要的大数据集变得更加容易。

  • 集成开发环境(IDE):Vertex AI 内置的笔记本服务提供了一个完全管理的 JupyterLab 环境,使开发者能够无缝地编写、运行和调试机器学习(ML)代码。此环境针对 ML 开发进行了优化,支持 TensorFlow 和 PyTorch 等流行框架,这些框架对于构建和实验大型语言模型(LLMs)至关重要。

  • AI 和 ML 库:GCP 继续扩展其预训练模型和机器学习 API 的库,包括专门为自然语言处理(NLP)和理解设计的那些。这些工具允许开发者快速将高级 NLP 功能集成到他们的应用程序中。

在 GCP 上部署和产品化 LLMs

GCP 为部署和产品化 LLMs 提供了强大且可扩展的解决方案,确保在其平台上构建的应用程序能够满足现实世界使用的需求:

  • Vertex AI 预测:一旦 LLM 被训练,Vertex AI 的预测服务允许轻松地将模型作为完全管理的、自动扩展的端点进行部署。此服务简化了使 LLMs 可用于应用程序的过程,同时基础设施会自动调整以适应工作负载需求。

  • Google Kubernetes Engine (GKE):对于需要高可用性和可扩展性的复杂部署场景,GKE 提供了一个托管环境来部署容器化的 LLM 应用程序。GKE 的全球基础设施确保您的模型具有高可用性,并且可以扩展以满足企业级应用程序的需求。

云服务总结

云计算领域持续快速发展,AWS、Azure 和 GCP 各自为 LLM 的开发和部署提供了独特的优势。AWS 以其广泛的基础设施和与 ML 工具的深度集成而突出,使其成为各种 ML 和 AI 项目的理想选择。Azure 通过其对 OpenAI 模型的独家访问和在微软生态系统中的深度集成,为企业利用 AI 技术的尖端提供了无与伦比的机会。GCP 以其在 AI 和 ML 领域的创新而闻名,提供与谷歌内部 AI 进步相匹配的工具和服务,吸引那些寻求最新 AI 研究和开发的人。随着这些平台功能的不断扩展,选择它们之间的差异将越来越多地取决于具体项目需求、组织协调和战略伙伴关系,这突显了基于当前和未来基于云的 AI 和 ML 环境进行深思熟虑评估的重要性。

摘要

随着自然语言处理和 LLM 领域的快速增长,系统设计的各种实践也在增加。在本章中,我们回顾了 LLM 应用和管道的设计过程。我们讨论了这些方法的组成部分,涉及基于 API 的封闭源代码和本地开源解决方案。然后,我们通过代码让您亲身体验。

我们后来更深入地探讨了系统设计过程,并介绍了 LangChain。我们回顾了 LangChain 包含的内容,并在代码中进行了示例管道的实验。

为了补充系统设计过程,我们调查了领先的云服务,这些服务允许您进行实验、开发和部署基于 LLM 的解决方案。

在下一章中,我们将重点关注特定的实际用例,并伴随代码。

Logo

葡萄城是专业的软件开发技术和低代码平台提供商,聚焦软件开发技术,以“赋能开发者”为使命,致力于通过表格控件、低代码和BI等各类软件开发工具和服务

更多推荐