TowardsDataScience 2023 博客中文翻译(二百零一)

原文:TowardsDataScience

协议:CC BY-NC-SA 4.0

排名算法介绍

原文:towardsdatascience.com/introduction-to-ranking-algorithms-4e4639d65b8?source=collection_archive---------0-----------------------#2023-08-16

了解排序搜索结果的主要排名算法

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 Vyacheslav Efimov

·

关注 发布于 Towards Data Science · 12 分钟阅读 · 2023 年 8 月 16 日

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

介绍

学习排序(LTR)是一类监督式机器学习算法,旨在根据与查询的相关性对一组项目进行排序。在经典机器学习中,如分类和回归问题,目标是根据特征向量预测单一值。LTR 算法在一组特征向量上操作,并预测项目的最佳排序。

LTR 有许多不同的应用。以下是其中的一些:

  • 搜索引擎。用户在浏览器搜索栏中输入查询。搜索引擎应该以一种方式对网页进行排名,使得最相关的结果出现在最上面的位置。

  • 推荐系统。一个电影推荐系统,根据输入查询选择应该推荐给用户的电影。

让我们正式定义排序问题:

给定一个存储查询和文档信息的 n 维特征向量,排序的目标是找到一个函数 f,该函数产生一个实数,表示查询与文档的相关性。此外,如果对象 i 排名高于对象 ji ▷ j),则 f(i) 应该大于 f(j)

注意。i ▷ j 表示文档 i 排名高于文档 j。

数据。

特征向量。

特征向量包括三种类型的特征:

  • 仅从文档中派生的特征(例如,文档长度,文档中的链接数量)。

  • 仅从查询中派生的特征(例如,查询长度,查询的频率)。

  • 从文档和查询的组合中派生的特征(例如,TF-IDF,BM25,BERT,文档和查询中共同出现的单词数量)。

训练数据。

为了训练模型,我们需要将训练数据输入到模型中。根据训练数据的收集方式,有两种可能的方法。

  • 离线 LTR。数据由人工手动注释。人工对不同查询和文档的对(查询,文档)相关性进行评分。这种方法成本高且耗时,但提供高质量的注释。

  • 在线 LTR。数据是通过用户与查询结果的互动(例如,对排序项目的点击次数,网页上的停留时间)隐式收集的。在这种情况下,获得训练数据是简单的,但用户互动的解释并不容易。

之后,我们有了特征向量及其对应的标签。这就是训练模型所需的一切。下一步是选择最适合问题的机器学习算法。

排序类型。

从高层次来看,大多数 LTR 算法使用随机梯度下降来找到最优的排序。根据算法在每次迭代中如何选择和比较项目的排名,存在三种主要方法:

  • 点对点排序。

  • 成对排序。

  • 列表排序。

所有这些方法都将排序任务转化为分类或回归问题。在接下来的部分,我们将看到它们如何在幕后运作。

点对点排序。

在点对点方法中,为每个特征向量单独预测分数。最终,预测的分数被排序。使用哪种类型的模型(决策树,神经网络等)进行预测并不重要。

这种类型的排序将排序问题转化为回归任务,其中回归模型试图根据选择的损失函数(例如,MSE)预测正确的相关性。

另一种有效的方法是将真实排名转化为独热编码表示,并将这些数据输入模型。在这种情况下,可以使用回归模型或分类模型(带有交叉熵损失)。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

逐点模型架构。作为输入,模型接受一个查询和一个特征向量。

尽管这种方法非常简单,但它存在以下列出的一些问题。

类别不平衡

使用逐点方法时的一个常见问题是类别不平衡。如果在现实生活中随机选择一个查询,那么很可能只有集合中的一小部分文档与之相关。因此,在训练数据中,相对文档与查询之间存在很高的不平衡。

虽然可以克服这个问题,但还有一个更严重的问题需要考虑。

糟糕的优化指标

逐点排名在优化目标上存在一个主要的基本问题:

逐点排名独立地优化文档得分,而没有考虑不同文档之间的相对得分。因此,它没有直接优化排名质量。

请看下面的例子,其中一个逐点算法对两组文档进行了预测。我们假设在训练过程中优化了均方误差(MSE)损失。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

集合包含 5 个文档,其中 1 个文档是相关的,其他 4 个是无关的。对于相关文档,预测相关性为 0.7,而对于其他文档为 0.5。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

集合包含 5 个文档,其中 1 个文档是相关的,其他 4 个是无关的。对于相关文档,预测相关性为 0.1,而对于其他文档为 0.2。

给定两个排名结果,我们可以看到从算法的角度来看,第二个排名更好,因为对应的 MSE 值较低。然而,选择第二个排名意味着用户会首先看到所有无关的结果。顺便提一下,在第一个例子中,相关结果首先显示,这在用户体验上要好得多。通常,用户不会太关注之后的推荐内容。

这个例子表明,在现实生活中,我们更关心的是首先展示相关结果以及项目的相对顺序。通过独立处理文档,逐点模型无法保证这些方面。较低的损失并不等同于更好的排名。

对输入对排名

对输入对模型在每次迭代中处理一对文档。根据输入格式的不同,有两种类型的对输入对模型。

对输入对模型

模型的输入是两个特征向量。模型输出是第一个文档排名高于第二个文档的概率。在训练过程中,这些概率是为不同的特征向量对计算的。模型的权重通过基于真实排名的梯度下降进行调整。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

对输入对模型架构。作为输入,模型接受一个查询和两个连接的特征向量。

这种方法在推理过程中有两个主要缺点:

  • 为了在推理过程中对给定查询的n个文档进行排名,每对这些文档都需要由模型处理以获得所有成对概率。总对数是平方的(准确等于n * (n — 1) / 2),这非常低效。

  • 即使拥有所有文档的成对概率,也不明显如何最终排名,尤其是在像恶性循环这样的矛盾情况下,其中有三元组文档*(x, y, z)*,模型以如下方式对其进行排名:x ▷ y, y ▷ zz ▷ x

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

恶性循环问题

由于这些缺点,成对输入模型在实践中很少使用,单输入模型被优先考虑。

单输入模型

模型接受一个单一的特征向量作为输入。在训练过程中,成对中的每个文档都独立地输入到模型中以接收其分数。然后比较这两个分数,并通过基于真实排名的梯度下降来调整模型。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

单输入模型架构。作为输入,该模型接收一个查询和一个表示文档的特征向量。在模型对两个特征向量独立分配分数后,计算排名预测。

在推理过程中,每个文档通过传递到模型中来接收一个分数。然后对这些分数进行排序,以获得最终排名。

对于熟悉 Siamese 网络(FaceNet,SBERT 等)的人来说,单输入模型可以被认为是 Siamese 网络。

成对损失函数

在每次训练迭代中,模型对一对文档预测分数。因此,损失函数应为成对的,并考虑两个文档的分数。

一般来说,成对损失函数以z为其参数,其中z是两个分数*s[i] — s[j]*的差异乘以一个常数σ。根据算法的不同,损失函数可以具有以下形式之一:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

成对排名的不同损失函数

有时分数差异z可以乘以一个常数。

RankNet是最流行的成对排名算法之一。我们将在下一部分详细了解其实现细节。

RankNet

在获得文档ij的分数后,RankNet 使用 softmax 函数进行归一化。通过这样做,RankNet 获得文档i比文档j排名更高的概率P[i][j] = P(i ▷ j)。反之,我们可以计算概率P̃[j][i] = P(j ▷ i) = 1 — P(i ▷ j)。为了简便起见,假设实际情况是 i 的排名高于 j,所以P̃[i][j] = 1P̃[j][i] = 0。对于模型权重的更新,RankNet 使用交叉熵损失,其简化如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

RankNet 损失函数

模型的权重通过梯度下降进行调整。下次模型遇到相同的文档对 i 和 j 时,文档 i 的得分可能会比之前更高,而文档 j 可能会被推得更低。

RankNet 分解

为了简化,我们不会深入探讨数学内容,但原始论文中提出了一个有趣的研究结果,作者找到了一种简化训练过程的方法。这是通过引入变量 S[i][j] 来实现的,该变量可以取三个可能的值之一:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

经过一些数学技巧,交叉熵损失的导数被分解为:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

公式中的 λ 值是一个常数,可以相对快速地计算所有文档对的 λ 值。通过取正值或负值,这些 λ 值充当了推动文档上升或下降的力量。

我们可以对单个文档 i 汇总所有成对的 λ 值。这个总和表示在排名中应用于文档 i 的总力量。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

对于找到应用于文档的总力量的 λ 值的汇总

直接使用 λ 函数可以得到更快的训练时间和更好的结果解释。

尽管成对算法比逐点方法表现更好,但它们有两个缺点。

不可解释的概率

模型输出的概率只是显示模型对某个对象 i 排在对象 j 之上的信心。然而,这些概率并不真实,有时模型可以粗略地近似这些概率,因此不应该总是用它们来进行解释,尤其是在之前看到的有恶性循环的混乱情况下。

最小化倒置不是最优解

这个问题比之前的问题更为严重。大多数成对算法,特别是 RankNet 的根本问题在于它们最小化排名倒置的数量。虽然优化倒置数量可能看起来很自然,但这并不是大多数最终用户真正想要的。考虑以下两个排名。你认为哪个排名更好?

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

两个相关的文档分别位于列表的开头和结尾。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

两个相关的文档位于列表的中间偏左位置。

尽管第二个排名的倒排数较少,这是算法的优先考虑,但普通用户仍然会更喜欢第一个排名,因为顶部至少有一个相关结果。这意味着用户不需要滚动大量文档才能找到第一个相关结果。同样,使用如nDCGERR这样的用户导向指标会更好,因为这些指标更注重顶部结果而非倒排数量。

结果显示,并非所有文档对都同样重要。算法需要调整,以更重视正确的顶部排名,而不是底部排名。

论文的研究人员提供了一个很好的例子,说明如何通过 RankNet 优化排名可能导致非最优结果:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们可以看到,第 1 位的文档被推到了第 4 位,第 15 位的文档被推到了第 10 位,所以总的倒排数减少了 2。然而,从用户体验来看,新排名变得更糟。核心问题在于 RankNet 为排名较差的文档分配了更大的梯度。然而,为了优化用户导向的指标,这应该是反向的:排名较好的文档应被进一步推高,而不是排名较差的文档。这样,像nDCG这样的用户导向指标将会更高。

列表排名

列表算法明确优化排名指标。为了使用梯度下降优化某个指标,需要为该指标计算导数。不幸的是,大多数排名指标如nDCGprecision是非连续且不可微的,因此发明了其他高级技术。

与点对点或对对排名方法不同,列表方法一次处理整个文档列表。这有时会导致大量计算,但也提供了更强的鲁棒性,因为算法在每次迭代时获得了更多的信息。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

列表模型架构。作为输入,模型接收一个查询和所有文档的特征向量。

LambdaRank

根据实现的不同,LambdaRank 可以被认为是点对点或列表方法。

当关注nDCG时,似乎最优的做法是为那些位置交换结果能提高nDCG的文档对分配更大的梯度。这一核心思想在于LambdaRank

算法名称中的“lambda”暗示 LambdaRank 还使用了 RankNet 中描述的 lambda 进行优化。

研究人员取得了惊人的成果,并证明如果 RankNet 中的损失值乘以*|nDCG|,则算法倾向于直接优化nDCG*!也就是说,LambdaRank 算法与 RankNet 非常相似,只是这次 lambda 被乘以nDCG的变化:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

nDCG 优化公式

研究中另一个令人惊讶的事实是,这种技巧不仅对 nDCG 有效,而且对其他信息检索度量也有效!类似地,如果将 λ 乘以精度变化,那么 precision 将得到优化。

最近,理论上已经证明 LambdaRank 可以优化某些信息检索度量的下界。

其他方法

我们不会详细讨论其他基于列表的方法如何工作,但仍会提供两个优秀算法的主要实现思想。

LambdaMart 是一种著名的基于列表的方法实现,它使用从 LambdaRank 派生的损失函数的梯度提升树。在实际应用中,它比 LambdaRank 表现更好。

SoftRank 解决了 nDCG 的导数存在问题。它创建了一种新的度量标准——“SoftNDCG”,它平滑地表示并近似 nDCG,使得可以找到相应的导数,并通过梯度下降更新模型的权重。事实上,这种方法也可以同样应用于其他度量标准。

结论

我们已经讨论了排名——这是机器学习中的一项重要任务,用于将一组对象按相关顺序排序。点对点和对对对方法不常使用,而基于列表的方法最为稳健。显然,我们只讨论了排名算法的一个小部分,但这些信息对于理解更复杂的技术如 ListNet 或 ListMLE 是必不可少的。可以在 这里 找到一个详细的列表方法算法。

值得注意的是,LambdaRank 目前是最先进的排名算法之一,为优化特定度量提供了很大的灵活性。

如果你想了解更多关于排名度量的信息,我强烈建议你阅读我关于这个话题的另一篇文章。

## 排名评估度量的全面指南

探索丰富的度量选择,找到最适合你问题的度量

towardsdatascience.com

资源

除非另有说明,否则所有图片均为作者所用

抽样方法介绍

原文:towardsdatascience.com/introduction-to-sampling-methods-c934b64b6b08

在 Python 中实现逆变换抽样、拒绝抽样和重要性抽样

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 Oliver S

·发表于Towards Data Science ·8 min 阅读·2023 年 1 月 10 日

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图片由Edge2Edge Media拍摄,发布在Unsplash

在这篇文章中,我们将讨论如何从概率分布中抽样。这是一个常见的需求,在机器学习环境中,这种方法最常用于对概率模型进行推断。然而,由于分布非常复杂,这通常是不可行的。因此,本帖的主要重点是介绍该任务的近似方法,特别是使用数值抽样,称为蒙特卡罗方法

尽管如此,为了介绍目的,我们将首先介绍逆变换抽样,它允许对任意可处理的分布进行精确推断。然后,我们将把重点转向近似方法,允许对(接近)任意分布进行抽样或矩估计:我们从拒绝抽样开始,然后转向重要性抽样。

请注意,这篇文章是一个系列的第一篇,旨在帮助读者熟悉[1],特别是本帖涵盖了第十一章:抽样方法的部分内容。

逆变换抽样

逆变换抽样方法允许从任何我们知道如何计算其累积分布函数(CDF)的分布中进行抽样。它包括从U[0, 1]均匀分布)中抽取y,然后计算所需的x,其计算公式如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

即,我们正在生成一个随机变量

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

然后声称

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

— 即累计分布的逆(记作F)遵循我们期望的目标分布(更具体地说,是其概率密度函数,记作f)。

当且仅当 CDF 相同,即:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

为了证明这一点,我们来检查左侧,并对方程两边应用 F:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

由于对[0, 1]上的均匀分布,我们有

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们得到,如所愿:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(证明取自COMP 480 / 580)。

Python 实现

让我们对指数分布进行尝试,其定义为 pdf:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

取 CDF 并进行反转得到:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这就给出了我们想要的采样公式!让我们将其转换为 Python 代码。

我们首先定义一个函数exp_distr,用于评估给定x值的 pdf,然后定义一个函数exp_distr_sampled,用于通过逆变换方法和我们上面推导的公式从指数分布中采样。

最后,我们绘制真实的概率密度函数(pdf)和我们采样值的直方图:

import numpy as np
import matplotlib.pyplot as plt

NUM_SAMPLES = 10000
RATE = 1.5

def exp_distr(x: np.ndarray, rate: float) -> np.ndarray:
    return rate * np.exp(-x * rate)

def exp_distr_sampled(num_samples: int, rate: float) -> np.ndarray:
    x = np.random.uniform(0, 1, num_samples)
    return -1 / rate * np.log(1 - x)

x = np.linspace(0, 5, NUM_SAMPLES)
y_true = exp_distr(x, RATE)
y_sampled = exp_distr_sampled(NUM_SAMPLES, RATE)

plt.plot(x, y_true, "r-")
plt.hist(y_sampled, bins=30, density=True)
plt.show()

运行此代码会生成类似以下的结果,显示我们的采样确实产生了正确的结果:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

数值采样

如果可能,逆变换采样效果完美。然而,如前所述,它要求我们能够反转 CDF。这仅适用于某些更简单的分布——即使对于正态分布,这也显著复杂,尽管可能。当这太困难或不可能时——我们必须诉诸其他方法,我们将在本节中介绍这些方法。

我们首先进行拒绝采样,然后引入重要性采样,最后讨论这些方法的局限性和展望。

注意,两种方法仍然要求我们能够评估给定xp(x)

拒绝采样

拒绝采样涉及引入一个更简单的提议分布q,我们可以从中采样,并用它来近似p。它遵循的思想是q(x) ≥ p(x)对于所有x,我们从q中采样,但拒绝所有高于p的样本——从而最终得到分布p

如上所述,虽然可以将逆变换采样应用于正态分布,但这很困难——因此为了演示,我们在这里尝试逼近一个正态分布(p),并使用均匀分布作为提议分布(q)。让我们在这个设置中可视化上述直觉:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

现在,通过拒绝采样,我们会从类似均匀分布的q中采样,并拒绝所有高于p的样本——因此在极限情况下,得到的点将完全填满p下方的区域,即从该分布中采样。

从形式上看,我们首先选择提议分布q,然后选择一个缩放系数k,使得kq(x) ≥ p(x)对所有x都成立。接下来,我们从q中采样一个值x_0。然后,我们从[0, kq(x_0)]上的均匀分布中生成一个值u_0。如果u_0 > p(x_0),我们拒绝该样本,否则接受它。

让我们用 Python 实现这一点:

from typing import Tuple

import matplotlib.pyplot as plt
import numpy as np

NUM_SAMPLES = 10000
MEAN = 0
STANDARD_DEVIATION = 1
MIN_X = -4
MAX_X = 4

def uniform_distr(low: float, high: float) -> float:
    return 1 / (high - low)

def normal_dist(
    x: np.ndarray, mean: float, standard_deviation: float
) -> np.ndarray:
    return (
        1
        / (standard_deviation * np.sqrt(2 * np.pi))
        * np.exp(-0.5 * ((x - mean) / standard_deviation) ** 2)
    )

x = np.linspace(MIN_X, MAX_X, NUM_SAMPLES)
y_true = normal_dist(x, MEAN, STANDARD_DEVIATION)

def rejection_sampling(
    num_samples: int, min_x: float, max_x: float
) -> Tuple[np.ndarray, float]:
    x = np.random.uniform(min_x, max_x, num_samples)
    # uniform_distr(-4, 4) = 0.125 -> we need to scale this to ~0.5, i.e.
    # select k = 4.
    k = 4
    u = np.random.uniform(np.zeros_like(x), uniform_distr(min_x, max_x) * k)
    (idx,) = np.where(u < normal_dist(x, MEAN, STANDARD_DEVIATION))
    return x[idx], len(idx) / num_samples

y_sampled, acceptance_prob = rejection_sampling(NUM_SAMPLES * 10, MIN_X, MAX_X)
print(f"Acceptance probability: {acceptance_prob}")
plt.plot(x, y_true, "r-")
plt.hist(y_sampled, bins=30, density=True)
plt.show()

得到以下结果:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

接受概率:0.24774

重要性采样

通常,我们只对期望感兴趣,这也是重要性采样发挥作用的地方:它是一种通过再次使用提议分布q来逼近复杂分布p的期望(或其他矩)的技术。

一个(连续)随机变量 X 的期望定义为:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

然后我们使用一个小数学技巧将其重新表达为:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

那么这个公式说明了什么?这是

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

q下——即为了计算E[X],我们现在可以在从q采样时评估这个项!系数p(x) / q(x)被称为重要性权重。

为了演示,我们再次将p设为正态分布——并使用另一种正态分布作为q

import numpy as np

NUM_SAMPLES = 10000
MEAN_P = 3
MEAN_Q = 2

def normal_dist(
    x: np.ndarray, mean: float, standard_deviation: float
) -> np.ndarray:
    return (
        1
        / (standard_deviation * np.sqrt(2 * np.pi))
        * np.exp(-0.5 * ((x - mean) / standard_deviation) ** 2)
    )

q_sampled = np.random.normal(loc=MEAN_Q, size=NUM_SAMPLES)
p_sampled = (
    q_sampled
    * normal_dist(q_sampled, MEAN_P, 1)
    / normal_dist(q_sampled, MEAN_Q, 1)
)
print(
    f"Resulting expecation when sampling from q {np.mean(p_sampled)} vs true expecation {MEAN_P}"
)

在代码中,我们将p设为均值为 3 的正态分布。然后,我们从提议分布q中采样NUM_SAMPLES,该分布是均值为 2 的正态分布——并利用上述介绍的变换来计算在p下的X的期望——得到的结果大约是正确的(~3 对比 3)。

让我们以对方差的讨论结束这一部分:结果样本的方差将是

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

对于我们的情况,这意味着方差会随着pq之间的差异(即不一致)增加。为了演示,比较MEAN_Q = 3.25的方差,我们分别得到~0.20 和~91.71。

不过需要注意的是,重要性采样也常作为方差降低技术,通过巧妙选择q来实现——然而这可能是未来文章的主题。

限制与展望

在这篇文章中,我们介绍了三种采样方法:逆变换采样、拒绝采样和重要性采样。

逆变换抽样可以用于相对简单的分布,对这些分布我们知道如何反转累积分布函数(CDF)。

对于更复杂的分布,我们必须求助于拒绝或重要性抽样。然而,对于这两种方法,我们仍需要能够评估所讨论分布的概率密度函数(pdf)。此外,还有其他缺点,例如:当我们不能用kq适当地“框住”p时,拒绝抽样是浪费的——在高维空间中尤其棘手。重要性抽样也是如此——特别是在高维空间中——很难找到适合的提议分布q以及合适的重要性权重。

如果上述提到的缺点过于严重,我们必须求助于更强大的方法——例如来自马尔可夫链蒙特卡洛方法(MCMC)家族。这些方法对我们想要近似的分布的要求要宽松得多,并且受到的限制也较少,例如在高维空间中。

这篇文章结束了对抽样方法的介绍。请注意,所有图片除非另有说明,均由作者提供。希望你喜欢这篇文章,谢谢阅读!

本文是关于抽样的系列的第一部分。你可以在这里找到其他部分:

参考文献:

[1] Bishop, Christopher M., “模式识别与机器学习”,2006,www.microsoft.com/en-us/research/uploads/prod/2006/01/Bishop-Pattern-Recognition-and-Machine-Learning-2006.pdf

语音增强简介:第一部分 — 概念与任务定义

原文:towardsdatascience.com/introduction-to-speech-enhancement-part-1-df6098b47b91

对改善退化语音质量或抑制噪声的概念、方法和算法的介绍

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 Mattia Di Gangi

·发布于 Towards Data Science ·阅读时间 6 分钟·2023 年 1 月 17 日

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图片由 Wan San Yip 提供,来源于 Unsplash

本文是系列文章的一部分:

语音增强是一套方法和技术,旨在通过语音音频信号处理技术提高语音质量,包括清除助听器中的噪声,或从嘈杂的信道/环境中恢复难以理解的语音信号 [Wikipedia]。它有许多实际应用,包括从噪声中清除语音信号或从嘈杂的信道/环境中恢复难以理解的语音信号。

它类似于但不同于语音分离[1],即将一个音频信号算法性地分离成两个不同的通道,分别用于语音和背景。可以应用语音增强来获取语音信号,然后应用额外的算法来计算残差信号,或原始信号与增强语音之间的差异

不同的语音增强方法被应用于减少不同噪声模型(例如,平稳与非平稳)的影响。虽然这个研究领域并不新鲜,但近年来深度学习方法蓬勃发展,提升了在最具挑战性的非平稳噪声场景中的语音增强质量,即使在低信噪比(SNR)下也是如此。

术语与背景

信号: 观测一个变化且可测量的物理量。音频、视频、图像,都属于这个定义。

噪声模型: 这是描述噪声信号潜在随机过程的数学模型。由于该过程是随机的,通常用概率分布来描述。

(非)平稳过程: 假设信号由一个潜在的过程生成。它可以是确定性的或随机的。由于我们对确定性过程了解一切,因此兴趣在于随机过程。如果一个随机过程的无条件联合分布依赖于时间,则称其为平稳的。换句话说,给定一个过程的模型,事件 X 在时间 t 发生的概率不依赖于 t 本身。通过扩展,由平稳过程生成的信号也称为平稳。在音频领域,当信号的频率或谱内容随时间变化时,信号就是平稳的。这意味着,对于语音增强,真正的挑战来自于非平稳噪声,因为它更不可预测且更难与语音区分,而人声也同样是非平稳的:我们声音信号中的频率一直在变化。

实验设置

与大多数实证研究领域类似,在语音增强中,我们需要数据集来训练我们的模型和评估它们,还需要评估结果的指标,以及运行算法的硬件和软件工具。

作为硬件要求,我们绝对需要一台配备有(至少)一个 NVIDIA GPU 的现代计算机进行训练,而现代多核 CPU 在推断过程中也可能足够,尽管预计会有较高的 CPU 使用率。

在软件方面,我们需要一个使用如 Tensorflow、Pytorch 或 Jax 派生库的代码库。上面链接的 FullSubnet+ 存储库可以是一个很好的起点。

然后,我们谈到数据。测量质量和实现监督学习的最简单方法是拥有一个网络应该重建的参考信号。因此,训练集通常通过收集干净的语音信号和噪声信号来构建。然后,通过将它们添加不同级别的信噪比(SNR)来将这两者结合起来。这样,在训练过程中,可以生成大量的语音/噪声组合,网络必须学习这些组合以获得增强的语音信号。研究社区通过共享任务来推动语音增强,因此可以从这些来源找到公开数据集。每年举办的Deep Noise Suppression (DNS) Challenge就在 Interspeech 上展示。在相关的代码库中,您可以找到提供的数据集链接以及其他资源。

评估通常通过手动和自动评估来进行。两者之间的权衡已被多次提及,但可能值得重复一下。手动评估由人工执行:它既昂贵又缓慢,因为需要找到、指导和支付人力,当然他们还需要在评估之前听取音频。自动指标则快速且便宜,因此在开发周期中可以重复使用,但它们只能捕捉评估的某些方面,并且在某些情况下可能不够可靠。

在语音增强的情况下,通常使用四种主要的自动评估指标:语音质量的感知评估(PESQ)、对数似然比(LLR)、倒谱距离(CD)和加权谱斜率距离(WSS)。所有这些指标都计算清晰语音和增强语音之间的距离。PESQ 比较两个信号样本之间的质量,产生一个在-0.5 到 4.5 之间的分数,分数越高越好。其他三个指标计算两个谱之间不同属性的距离:共振峰、对数谱距离或谱斜率的加权距离。当需要时,可以增加人工评估,以评估感知质量或统计增强信号中的可识别单词。语音识别可以用来识别单词,但这时我们需要处理它自身的错误。

关于信号表示,有些语音增强模型在时间域中工作,而其他模型则在频域中工作。频域是通过对信号应用傅里叶变换获得的,是对信号的非时间性表示,提供了关于其频率成分的信息。在实践中,频域表示比时间域表示更适用于语音增强,所有最先进的方法都使用它。

示例

让我们展示一个例子,以便对这个主题有听觉上的理解。我们从一个包含响亮音乐的视频广告开始,这可能会使语音难以听清。

以创作共享许可证发布

我们首先使用著名的ffmpeg工具提取音频轨道:

## original_audio.wav

然后,我们应用 FullSubNet+算法[2],这是一种基于深度学习的方法,具有开源代码预训练模型可用。按照仓库中的说明,很容易复现这一结果:

## enhanced_audio.wav

最后,为了满足你的好奇心,展示从原始信号中增强语音得到的残余音频:

## residual_audio.wav

enhanced_audio.wav中的语音质量显著提高,并且音乐的音量根据时间被完全去除或大幅降低。结果显示了现代语音增强的有效性,但也表明结果并不完美,该领域还有更多研究在进行。此外,通过运行代码,你会发现这一操作在计算上相当昂贵。拥有 GPU 会使过程更快,但在保持或改善质量的同时减少计算复杂性是一个重要的研究目标。

结论

本系列的第一部分到此为止!我们讨论了语音增强的理念和原因,并提供了一些关于数字信号的背景信息。

在本系列的第二部分,我们将详细介绍一个公开的最先进语音增强模型。

与此同时,我鼓励你阅读文章中的链接资源,如果你对这一主题感兴趣,可以查看数字信号处理的教学资料。其中一本免费提供的书籍是Think DSP。你可以在线阅读或下载 pdf,当然也可以购买纸质版以支持作者(我不会从中获得任何收益)。

感谢你一直阅读,希望在下一部分中见到你!

语音增强简介:第二部分 — 信号表示

## 自动评价合成语音

了解深度学习和预训练模型如何用于自动语音评估的指南

towardsdatascience.com ## 使用 inotifywait 进行数据处理自动化

在拥有生产就绪的 MLOps 平台之前如何进行自动化

towardsdatascience.com ## 3 种常见的错误来源及如何避免它们

某些编码模式更容易隐藏错误。编写高质量代码并了解大脑的工作原理可以帮助…

towardsdatascience.com

参考文献

[1] Bahmaninezhad, Fahimeh 等. “语音分离的统一框架。” arXiv 预印本 arXiv:1912.07814 (2019)。

[2] 陈军等. “FullSubNet+: 基于通道注意力的 FullSubNet 与复杂谱图用于语音增强。” ICASSP 2022–2022 IEEE 国际声学、语音与信号处理会议(ICASSP)。IEEE,2022。 arxiv.org/abs/2203.12188

Medium 会员

你喜欢我的写作并考虑订阅 Medium 会员以无限访问文章吗?

如果你通过此链接订阅,你将支持我而不会增加额外费用 medium.com/@mattiadigangi/membership

语音增强介绍:第二部分 — 信号表示

原文:towardsdatascience.com/introduction-to-speech-enhancement-part-2-signal-representation-ab1deca2fa74

让我们深入了解信号表示、傅里叶变换、谱和谐波。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 Mattia Di Gangi

·发布于 Towards Data Science ·阅读时间 10 分钟·2023 年 1 月 31 日

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图片由 Richard Horvath 提供,来源于 Unsplash

本文是系列的一部分:

介绍

在深入语音增强的讨论之前,我们需要明确一些关于数字信号处理的概念。在本系列的前一章中,我们介绍了一些概念并添加了进一步阅读的链接。

在第二部分中,我们将探讨数字信号的表示方式、如何更改表示方式,以及傅里叶变换为何如此重要。代码和图示将帮助你理解并进一步探索这些例子。

信号基础

本文的主要目标是理解什么是信号,它如何表示,以及傅里叶变换的重要性,这是一种经过时间考验的根据需求改变表示方式的方法。

音频信号通常表示为随时间变化的振幅。由于我们讨论的是数字信号处理,记录的音频由在规则间隔收集的许多样本组成。通常测量的是采样频率而不是样本之间的间隔长度。采样频率采样率是每秒钟的样本数量。秒的倒数(1/s)称为赫兹(Hz)。如果我们在一秒钟内有 10 个样本,则采样率为 10Hz。如果我们有 1000 个样本,则为 1 kHz(千赫兹)或 1000 Hz,依此类推,使用常见的科学前缀。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

振幅为 1.0,频率为 10 Hz,采样率为 10 kHz 的正弦信号

与频率为 1Hz 的正弦信号进行比较。它看起来比之前的信号“更宽”。我们可以想象调整频率就像拉伸弹簧一样,

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

振幅为 1.0,频率为 1 Hz,采样率为 10 kHz 的正弦信号

采样率影响信号的感知质量,因为采样率不足会导致降级,如下图所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

振幅为 1.0,频率为 10 Hz,采样率为 100 Hz 的正弦信号

在一些极其不足的采样率情况下,记录的信号可能完全不像原始的模拟信号:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

相同信号的采样率为 10 Hz。样本均匀分布,并对应于函数的零值。请注意 y=0.0 处的小水平蓝线

这些基本示例向我们展示了选择足够高采样率的重要性。对于人类语音,采样率从 8kHz 开始,这是电话的采样率,当需要高精度时,可以轻松达到 44.1 kHz。上述绘制的信号可以通过以下代码重现。

import matplotlib.pyplot as plt
import numpy as np

def sin_signal(amp, freq, phase, sr):
    """Generate a sin signal with the given characteristics"""
    x = np.arange(0, 2*np.pi, 1./sr)  # 2*pi is a full period for a sinusoid
    return amp*np.sin(freq*2*np.pi*x - phase)  # full formula for a sin-shaped signal

def plot_signal(s):
  x_ax = np.linspace(0, 1, len(s))
  plt.plot(x_ax, s)

# Change these values to modify the signal
amp = 1.0    # signal maximum amplitude
freq = 10    # sin frequency
phase = 0.0  # signal phase
sr = 10000   # sampling rate

sig = sin_signal(amp, freq, phase, sr)
plot_signal(sig)

到目前为止,我们观察到改变频率可以使信号在水平轴上“变窄”或“变宽”,而采样率会影响其精度。我们还可以通过修改振幅在垂直轴上拉伸或压缩它:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

振幅为 3.0,频率为 10 Hz,采样率为 10 kHz 的正弦信号

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

振幅为 0.5,频率为 10 Hz,采样率为 10 kHz 的正弦信号

这两个信号看起来可能相同,但快速查看垂直轴标签会发现,第一个信号的范围是从 -3.0 到 3.0,而第二个信号的范围是从 -0.5 到 0.5。最大(绝对)值与我们选择的振幅值相匹配。

我们需要理解的最后一个入门概念是信号的相位。它可以被认为是相对于参考起始时间的时间移位,并以弧度表示。让我们通过观察一个可视化的例子来理解它。之前展示的正弦信号的相位为 0,其函数可以表示为 sin(10 * 2πt),其中 10 是频率,2π是正弦函数的一个完整周期。周期是函数重复自身的间隔。现在,我们可以添加一个 π 弧度的相位,得到以下图像:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

频率为 10 Hz,采样率为 10 Khz,相位为π的正弦波

我们可以看到,它就像是信号“向左移动”了 π 弧度的持续时间。我们也可以通过减去 π 的相位将其向右移动,但这样做不会显著显示(因为向左或向右移动 π,函数的样子是一样的),所以我们将其向右移动 π/2:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

频率为 10 Hz,采样率为 10 Khz,相位为-π/2 的正弦波

我们之所以说“添加”和“减去”,是因为公式是 sin(f * 2πt + θ),其中 f 是频率,θ 是相位。

现在我们引入了一些概念,可以回到傅里叶变换及其如何帮助我们更好地理解信号。

傅里叶变换

本节的目标是为读者提供傅里叶变换的实用概念。关于傅里叶变换理论的资源很多,世界上不需要新的。建议感兴趣的读者跟随链接并查找更多资源。

傅里叶变换的基本假设是任何平稳信号都可以分解为不同频率的正弦函数的和,每个函数具有各自的振幅和相位。一个以正弦信号之和表示的信号被称为“频域”,而我们之前看到的则是在“时域”。

对信号应用傅里叶变换的结果,也称为分析,是一系列复数系数,每个系数对应于一个特定的频率。为什么是复数系数?我们可以将任何复数 z 用极坐标表示为 z = |z|e^(jθ),其中 |z| 是振幅,θ 是角度(或相位)。振幅和相位正是完全描述已知频率的正弦信号所需的全部信息。

傅里叶变换有不同类型,但最常见的是离散傅里叶变换(DFT)及其逆变换,即离散傅里叶逆变换(IDFT),这是我们处理离散信号记录所需的变换。

离散信号 x(n) 长度为 N 的离散傅里叶变换(DFT)定义为:

X(k) = Σ x(n) * e^(-j2πkn/N) 对于 k = 0,1,2,…,N-1

其中 X(k) 是离散傅里叶变换(DFT)的复数系数,k 是频率索引,n 是时间索引,N 是信号的长度,j 是虚数单位。

IDFT 是 DFT 的逆变换,它允许我们从 DFT 系数中恢复原始信号。

x(n) = 1/N * Σ X(k) * e^(j2πkn/N) 对于 n = 0,1,2,…,N-1

DFT 系数可以用来分析信号的频率内容,而逆离散傅里叶变换(IDFT)可以用来从频率分量合成信号。DFT 和 IDFT 被广泛应用于超出音频处理的许多领域,如图像和视频处理、通信系统和深度学习。

DFT 的一个重要属性是线性,即,在变换之前对信号进行的加法和乘法操作与对变换值进行的加法和乘法操作结果相同,反之亦然,因为逆离散傅里叶变换(IDFT)具有相同的属性。这使我们能够在频域中修改信号,我们可以修改各个分量,并且对时域信号的结果可以轻松预测。

信号的频谱表示

信号的频谱表示是将信号的频率内容在频域中表示的一种方法。

DFT 系数的幅度表示信号的幅度谱,幅度谱代表信号中每个频率分量的强度。幅度谱通常以分贝(dB)表示,分贝是对数尺度,使得解释不同频率分量的相对强度变得更容易。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

频率为 440Hz,幅度为 1.0,初相位为 0.0 的正弦波的频谱。唯一的非零值出现在频率 440 Hz 处。

相位图更难以解释。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

相同正弦波的相位谱

这两个图可以通过以下代码生成:

import matplotlib.pyplot as plt
import numpy as np

freq = 440
duration = 1.0
sr = 10000
n = round(duration * sr)
x = np.arange(0, n) / sr
a = np.sin(freq*2*np.pi*x)
f = np.fft.rfft(a)
freqs = np.fft.rfftfreq(n, 1./sr)
plt.plot(freqs, np.abs(f))
plt.plot(freqs, np.angle(f))

在图中,我们有复数函数来获取幅度和角度。

现在让我们看一个低通滤波器的示例,该滤波器减少高频的影响。我们通过将不同频率的正弦波相加来生成一个信号,然后对频率高于 1000 的信号幅度除以 2。

import matplotlib.pyplot as plt
import numpy as np

freqs = np.arange(10, 5000, 100)
duration = 1.0
sr = 10000
n = round(duration * sr)
x = np.arange(0, n) / sr
signal = sum(np.sin(freq*2*np.pi*x) for freq in freqs)
plt.plot(x, signal)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

相同幅度的正弦波的和

频谱:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

上述信号的频谱。所有非零频率的贡献相同。

现在我们按如下方式应用低通滤波器:

low_pass = np.array(f)
low_pass[freqs > 1000] = low_pass[freqs > 1000] / 2
plt.plot(freqs, np.abs(low_pass))

获取可预测的频谱

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

应用低通滤波器后的频谱

请注意,这仅仅意味着感兴趣的频率的幅度已被除以二。由于我们仅使用正弦波,因此映射是直接的,但如果我们从不同的信号开始,情况也是如此。

最后,我们可以恢复修改后的信号。

sig_ = np.fft.irfft(low_pass)
plt.plot(x, sig_)

得到如下信号

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

从 irfft 重建的信号

这与起始信号相似,但缩小了近乎两倍。

谐波

现在让我们观察一个比正弦波更复杂的信号,例如一个三角形状的信号:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

频率为 10、幅度为 1、相位为 0 的三角形信号

我们可以用以下代码生成它:

import matplotlib.pyplot as plt
import numpy as np

freq = 10
sr = 10000
ts = np.linspace(0, 1, sr)
x = freq * ts
frac, _ = np.modf(x)
y = (np.abs(frac - 0.5) - 0.25) * 4
plt.plot(x, y)

基本思想是我们只取 xs 的小数部分,它们具有恒定的增量,然后取与 0.5 的差的绝对值。这就形成了三角形状。然后,我们有一个偏置和缩放,将信号从[0, 0.5]转换到[-1, 1]。

现在让我们看看这个信号的幅度谱。我们将频率更改为更高的值,例如 440 Hz,以便于可视化:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

频率为 440 Hz 的三角形信号的频谱

与正弦信号不同,这个信号有多个非零值。如果你认为它们的分布中存在某种模式,那么你是对的!一个三角形状的信号由一个相对强的正弦信号组成,频率相同,称为基频,在这种情况下是 440Hz。其他频率称为谐波,是基频的倍数。图中分辨率不高,但这些谐波的频率为:1320 Hz、2200 Hz、3080 Hz 等,覆盖了偶数倍数。最后一个是三角形信号的特性,而一般情况下,谐波可以是基频的所有倍数。基频很重要,因为通常情况下,信号的感知音高取决于基频,即使它不是最显著的,即最高的系数。

此外,你还可以看到更多(非常小的)非零系数。这是数字信号处理中的一个伪影,称为混叠。在对信号进行数字表示的采样时,我们丢失了两个点之间发生的情况的信息。对于低频来说这不是问题,因为我们有足够的样本来进行插值,但对于高频来说,这会变成一个明显的问题。

在上面的图中,我们可以看到频率高达 5000 Hz,但第 7 个谐波会是 5720 Hz。采样的效果是造成频率的“折叠”,也就是在 5000 之后我们开始向回计数。然后,第 7 个谐波被检测为 4280:5000 — (5720–5000)。混叠频率继续向回,直到达到 0,然后再折回到另一个方向。

采样率越高,混叠效应越低,信号越清晰。

结论

在这篇文章中,我们进入了信号表示和傅里叶变换的世界。理解基本术语及其在信号中的意义对于继续本系列的内容非常重要。

文章中充满了图表和代码,以帮助读者以实用的方式理解这些概念,并让读者轻松地进行示例操作。

在本系列的下一部分中,我们将通过探索混响开始进行语音增强。

感谢您读到这里,敬请关注下一部分!

## Python 多态与注册 | Python 模式

学习一种模式以在扩展 Python 代码功能时隔离包。

[towardsdatascience.com ## 阅读和撰写 ML 研究论文的技巧

通过数十次同伴评审所获得的经验教训

[towardsdatascience.com ## 选择您的深度学习工具

为什么您的工具可能取决于您组织的团队结构

[towardsdatascience.com

深入阅读

Think DSP 第二章详细讲解了本文的概念。

Medium 会员

您是否喜欢我的写作,并考虑订阅 Medium 会员以获得无限访问权限?

如果通过此链接订阅,您将支持我,而您无需额外支付费用 medium.com/@mattiadigangi/membership

统计抽样与重抽样介绍

原文:towardsdatascience.com/introduction-to-statistical-sampling-and-resampling-1a6110965c3a

统计抽样是统计学的一个基本组成部分,它使我们能够有效地获得感兴趣的群体的信息,而不需要直接研究它

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 Andrea D’Agostino

·发表于 Towards Data Science ·阅读时间 10 分钟·2023 年 5 月 16 日

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图片来源:Testalize.meUnsplash

任何研究人员最隐秘的愿望之一就是能够拥有他/她打算研究的整个群体的数据。

研究整个群体可以让研究人员对所研究的现象获得完整的理解,因为这可以收集该群体中所有个体的信息。

在大多数情况下,这在实践和理论上都是不现实的。

例如,考虑一下由意大利罗马市的人组成的群体。如果我们的研究需要包括这些个体的回应,由于现实世界的限制,可能不可能找到并联系到他们所有人。

我们需要找到这些人并请求他们的回应——这需要针对罗马的所有个体。

这可能会证明是过于昂贵和耗时的,无论是对于单独工作的研究人员还是团队。

因此,通常需要使用样本作为对群体的近似。

抽样并不像人们想象的那样简单。它有一些不明显的定义和细微差别是值得了解的。实际上,能够明确和深思熟虑地制定抽样策略对你的研究有着巨大的影响,无论是对你还是对团队。

在这篇文章中,你将了解统计抽样及其如何对你的研究和实验结果产生巨大影响。

通过阅读本文,你将学到以下内容

  • 你将能够定义样本是什么,以及它与群体在统计层面上有何不同

  • 理解为什么抽样在大多数情况下是必要的

  • 什么使样本代表总体,以及哪些因素影响这种属性

  • 你将学习一些最相关的抽样技术,以及如何在研究设计中考虑这些技术的示例和图像

让我们开始吧!

让我们定义什么是样本

样本不过是你希望研究的总体的一个子集。 与总体代表你要分析的整个个体或对象组不同,样本仅代表其中的一部分。

研究样本使我们能够通过接近我们期望在观察数据中发现的某种程度的真相来研究总体。

就这样。

现在,当提出问题时,细微差别就会出现,例如

  • 我实验的纳入标准是什么?

  • 适合这种情况的抽样策略是什么

  • 我如何从这个样本中收集数据

还有其他方面。所以虽然定义样本是件简单的事,但抽样相当复杂,并且影响你正在进行的整个研究。

为什么研究一个总体会很困难?

原因可能有很多,但一些最常见的包括

  • 总体过于庞大,你无法从所有个体那里获取数据

  • 缺乏资源,例如时间和金钱,以收集整个总体的数据

  • 识别所有属于总体的个体的难度

  • 无法收集某些个体的数据,由于某种形式的不可接触性

以及许多其他取决于项目的方面。

在这些情况下,统计抽样成为一种实用且高效的解决方案用于估计总体特征。一旦从样本中收集了数据,就可以用它来推断更大总体的特征。

“代表性”样本是什么意思?

代表性样本是一个总体的子集,预计会与总体本身共享一些特征。

给定某个度量(如个体的身高或他们在某个测试中的分数),

代表性样本是一个准确反映该度量分布的样本,如果整个总体被研究的话。

大多数时候研究人员对给定度量的总体分布一无所知,所以他/她可以使用抽样技术,例如随机抽样,这有助于确保总体中的每个个体都有相等的被纳入样本的概率。

但这并不简单,因为验证抽样技术的唯一实证方法是通过观察和实验。

例如,你可以使用随机抽样,因为你认为总体中的个体相似。如果情况如此,实验可能会揭示出实际上有多个彼此差异较大的独立群体,这些群体值得单独研究。

影响采样的因素

以下是影响采样质量及其正确估计总体能力的因素列表:

  • 参考总体:样本的选择取决于对参考总体的了解,即从中提取样本的人群、物体、事件或数据组。

  • 采样方法:有几种采样方法,包括简单随机抽样、分层抽样、聚类抽样、系统抽样和配额抽样。方法的选择取决于总体的特征和研究的目标。

  • 样本大小:样本大小取决于估计所需的精度和可靠性水平。通常,样本越大,估计越准确。这是因为随着样本中个体数量的增加,参考总体越来越接近。

  • 纳入标准:使用的纳入标准可能会影响样本的代表性和估计的准确性。重要的是使用适当的筛选程序以避免选择偏差。

  • 数据收集方式:数据的收集方式(例如,电话采访、在线问卷、实地观察)会影响数据质量和样本的代表性。

  • 数据收集时间:这可能会影响样本的代表性,因为总体的特征可能随时间变化。

采样技术

我们现在将看到一系列可供研究人员使用的采样技术,这些技术可以用来接近总体。同样,没有“最佳”技术——你应该理解并根据你正在处理的案例进行调整。

  • 随机抽样

  • 分层抽样

  • 系统抽样

  • 配额抽样

  • 自助法

我们一个一个地来看。

随机抽样

简单随机抽样是最广泛使用的采样技术之一,涉及从总体中随机选择个体,使每个个体有相等的机会被纳入样本。

当总体是同质的且没有理由将其划分为组时,这种采样技术很有用。此外,简单随机抽样相对容易实施且不需要专业知识。

然而,简单随机抽样存在一些限制,例如在总体高度异质的情况下,确保样本代表性的难度

在这种情况下,拥有领域特定的知识对于理解和正确处理这些现象非常重要。

这里有一张关于随机抽样如何工作的图像

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

随机抽样的工作原理。图像由作者提供。

层次抽样

层次抽样是一种 将总体根据一个或多个特征划分为同质群体(称为层)的抽样技术。

一旦确定了层次,就会在每个层次中选择一个简单随机样本。

当总体在感兴趣的特征上具有异质性,并且你希望确保每个层次在样本中得到适当代表时,这种技术非常有用。

例如,如果你想研究公司在不同地区的客户满意度,可以按地区划分总体,并从每个地区中选择一个简单随机样本。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

层次抽样的工作原理。图像由作者提供。

系统抽样

系统抽样是一种抽样方法,其中总体项目按顺序排列,并从一个随机起始点开始,每隔 k 个项目选择一个项目(例如,每第十个项目)。

当总体项目的列表已经可用,并且需要随机选择样本时,可以使用这种抽样方法。

当总体较大且识别每个个体会需要过多时间或资源时,系统抽样非常有用。

然而,如果所选个体的范围与总体中的特定模式重合,则系统抽样可能会有偏差。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

系统抽样的工作原理。图像由作者提供。

基于配额的抽样

配额抽样是一种非概率抽样方法,在这种方法中,个体的选择是 为了获得参考总体特征的比例代表性。

使用这种方法,总体基于某些感兴趣的特征(例如,性别、年龄、教育、地理区域)被划分为类别或“配额”,每个配额中要选择的个体数量是根据总体的比例确定的。

每个配额内的受试者选择可以使用随机或非随机抽样方法,根据研究的需要进行选择。

基于配额的抽样的优点是,即使每个配额内的受试者选择不是随机的,它也能获得一个按比例代表参考总体特征的样本。

这种抽样方法常用于 民意调查, 因为它能够相对快速且廉价地获得具有代表性的样本。然而,配额抽样可能会受到选择样本的招聘人员的知识和观点的影响,因此可能会存在选择偏差。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

基于配额的抽样的工作原理。图像由作者提供。

自助法

自助法是一种重新抽样技术**,它通过从总体中随机选择并替换一定数量的元素来生成样本,从而近似总体。**

这个过程会重复多次,从而创建大量样本。从这些样本中提取任何统计量(如均值或中位数),这将成为最终样本的一部分,从而近似总体。

自助法在你想要估计样本统计量或机器学习模型的准确性时非常有用。与其对总体分布做假设,自助法使用合成样本的分布来估计标准误差和置信区间

自助法(Bootstrapping)在总体分布未知或无法从原始总体中获取重复样本时特别有用。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

自助法的工作原理。图片作者。

结论

在这篇文章中,我们已经看到统计抽样是研究过程中的一个基本概念。

我们已经看到,基于研究者在参考领域的知识以及他所面临的各种偏见,抽样可以比收集整个总体的数据更有效地获取目标总体的信息。

我们还讨论了常用的抽样技术,包括随机抽样、分层抽样、系统抽样和配额抽样,以及自助法(Bootstrapping)。

最后,我们强调了正确定义参考总体以及选择最合适的抽样方法对于研究目标的重要性。

希望这篇介绍能帮助你个人成长、领域知识的提升以及你的项目。

下一篇文章 👋

推荐阅读

对感兴趣的人来说,这里有我为每个机器学习相关主题推荐的书单。这些书在我看来是必读书籍,对我的职业生涯产生了巨大影响。

免责声明:这些是亚马逊的附属链接。我将从亚马逊那里获得一小笔佣金,因为我向你推荐了这些商品。你的体验不会改变,也不会收取额外费用,但这将帮助我扩大业务,并制作更多关于人工智能的内容。

有用的链接(由我编写)

如果你想支持我的内容创作活动,请随时通过下面的推荐链接加入 Medium 的会员计划。我将从你的投资中获得一部分,你将能够无缝访问 Medium 上大量的数据科学及其他领域的文章。

[## 使用我的推荐链接加入 Medium - Andrea D’Agostino

作为 Medium 会员,你的会员费的一部分将转给你阅读的作者,你可以完全访问每一个故事…

medium.com](https://medium.com/@theDrewDag/membership?source=post_page-----1a6110965c3a--------------------------------)

流处理框架介绍

原文:towardsdatascience.com/introduction-to-streaming-frameworks-d612583a3246

理解在评估和比较流处理技术时需要考虑的一些关键特性。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 Pier Paolo Ippolito

·发布于 Towards Data Science ·阅读时长 6 分钟·2023 年 11 月 8 日

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Joao Branco 提供的照片,Unsplash

介绍

随着数据架构变得越来越成熟,流处理不再被视为奢侈品,而是一项在不同行业中广泛应用的技术。由于技术和资源限制,批处理实际上一直是处理和交付应用程序的首选方式,但随着基于 Apache 的分布式系统中微批处理和原生流处理框架的发展,高规模流处理现在变得更加可及(见图 1)。

使用流处理系统的一些示例应用包括:处理交易数据以发现异常、天气数据、来自远程位置的物联网数据、地理位置跟踪等。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 1:批处理与流处理(作者提供的图片)。

实时处理与微批处理

流处理系统主要有两种类型:微批处理和实时处理:

  • 在实时流处理过程中,每条记录都会在其可用时立即被处理。因此,这可能导致系统具有非常低的延迟,能够立即利用传入的数据(例如,在金融系统中检测欺诈交易)。

  • 在微批处理系统中,数据点不是一个一个处理,而是以小块的形式处理,然后在特定时间间隔后或达到最大存储大小时返回。这种方法因此更倾向于高吞吐量而非低延迟。最后,如果有兴趣执行复杂的操作,例如在存储系统中输出结果之前进行聚合(如最小值、最大值、均值)、连接等操作,微批处理系统可以特别有用。因此,微批处理可以被认为是在执行例如每小时报告任务(如平均天气温度等)时的一个非常好的折衷方案。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2:实时与微批处理(图片由作者提供)。

选择流处理框架

现在我们已经澄清了微批处理和实时流处理的区别,我们可以开始审查一些需要考虑的关键点:

  • 延迟

  • 吞吐量

  • 内存使用

  • 可扩展性

  • 故障恢复

  • 消息传递保证

延迟

延迟可以定义为处理一个或多个输入并返回输出所需的时间(流记录进入系统后处理的时间)。如果低延迟是主要限制,则流处理框架将是我们的最佳选择。在微批处理中,输入实际上是在被消费之前缓存的(因此增加了延迟时间)。

吞吐量

吞吐量表示系统返回的输出数据的汇总速率。例如,这可以通过每秒处理的输入数据量来表示。例如,Apache Spark 可以使用微批处理,通过缓存输入数据能够实现高吞吐量速率。另一方面,原生流处理框架为了尽可能优化延迟评分,则会注册较低的吞吐量速率。

内存使用

由于流处理框架每天处理大量数据,优化内存使用可以是一个非常重要的因素,以确保系统在重负载下不会被压垮。根据系统架构,这些系统实际上可以设计成保留不同时间段的数据,如果数据保留时间过长或同时接收大量数据,则内存可能成为一个大限制。因此,评估不同框架的内存使用优化可能是一个相当复杂的任务,并且高度依赖于你所从事项目的具体情况。在这种情况下,使用不同示例的来流量创建使用基准可以提供有价值的见解,以便做出决策。

可扩展性

在并行处理流处理框架中,可扩展性可以通过系统处理不断增加的工作量并均匀分配任务到不同工作节点的能力来表示。例如,这可以通过实现主从架构来完成,其中主节点负责最优地规划任务在工作节点之间的分配,以尽可能避免工作节点在等待依赖项时闲置。此外,在高度可扩展的架构中,系统应该能够自动理解何时需要或不需要在集群中添加/删除资源(例如工作节点),以响应不断上升/下降的工作负载。

故障恢复

另一个需要考虑的重要因素是故障恢复。实际上,这可以定义为系统在其组件之一失败后能够保持弹性并继续操作的能力。例如,如果一个工作节点内存耗尽且不再功能正常,应该自动启动一个新的节点以减少停机时间,并且它应该能够从类似的阶段继续操作,以避免完全从头开始重启整个过程。在处理非常大的负载的分布式系统中,故障恢复是一个非常重要的特性,因为故障可能比预期的更频繁。

消息交付保证

最终,每个流处理框架可以提供不同的输入交付保证。三个最重要的交付保证是:

  • 准确一次交付

  • 至多一次交付

  • 至少一次交付

使用“准确一次”交付,系统保证每个传入的输入将被处理一次。相反,使用“至多一次”交付,大多数输入预计将被处理,但如果过程中的某些事情出现问题,则无法保证输入会被处理。最终,使用“至少一次”交付,保证每个输入都会被处理,并且某些消息可能也会被处理两次或更多次。

选择消息交付方法时需要记住的两个关键标准是:延迟和计算成本。例如,从准确性的角度来看,“一次交付”在大多数使用案例中可能是最佳选择,尽管这种方法很容易带来大量额外的开销(例如,需要一个记录历史系统来确定输入是否已经处理过,以及在发生故障时进行恢复)。因此,根据应用程序的可能约束,其他消息交付系统可能会为你提供更多价值。

Apache Spark、Flink 和 Kafka

提供流处理功能的三个最显著的 Apache 项目是:Spark、Flink 和 Kafka。Spark 仅提供微批处理,Flink 提供原生流处理和批处理,而 Kafka 仅提供流处理。

现在,Apache Spark 是最流行的批处理工作负载系统之一,通过其改进的结构化流处理 API 也越来越多地用于流处理任务(具有亚秒级延迟)。结构化流处理提供了更易于使用的 API、精确一次处理、内置容错和接近实时的处理能力。如果你对了解更多关于 Apache Spark 的信息感兴趣,可以在我的介绍文章和优化文章中找到更多资料。

Apache Flink 可以支持无限(流式)和有限(批处理)流。不过,与 Spark 相反的是,默认情况下,运行时是流式的而非批处理的。此外,Flink 还能够执行有状态的计算(利用时间上的数据依赖进行聚合、连接等)。

最后,Apache Kafka 是一个专门设计用于执行流处理操作的平台。它始于 2011 年的一个消息队列系统,现在已经成为一个完整的流处理框架,内置了对计算和存储的支持。Apache Kafka 由 4 个关键 API 组成:Kafka Streams、Producer、Consumer 和 Connector。使用 Kafka Streams API 可以提供许多优势,如开箱即用的出色扩展性、集群管理、自动故障转移等。

此外,如果需要,可以在同一系统中结合使用不同的框架,以充分发挥它们的最佳功能(例如,使用 Kafka 进行流处理存储,使用 Flink 进行计算)。

联系方式

如果你想随时了解我的最新文章和项目,请在 Medium 上关注我并订阅我的邮件列表。以下是我的一些联系方式:

Open LLM Falcon-40B 简介:性能、训练数据和架构

原文:towardsdatascience.com/introduction-to-the-open-llm-falcon-40b-performance-training-data-and-architecture-98388fa40226?source=collection_archive---------4-----------------------#2023-06-07

开始使用 Falcon-7B、Falcon-40B 及其指令版本

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 本杰明·玛丽

·

关注 发表在 Towards Data Science ·6 分钟阅读·2023 年 6 月 7 日

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

照片由Brandon拍摄,发布于Unsplash

Falcon 模型自 2023 年 5 月发布以来引起了广泛关注。

它们是因果大语言模型(LLM),或所谓的“仅解码器”模型,非常类似于 GPT。

定义:因果语言模型

因果语言建模涉及预测一个令牌后面的令牌。在训练期间,模型的注意力仅集中在左侧上下文上。右侧上下文被屏蔽。这些模型通常在数十亿个词上进行训练。

Falcon 模型自 5 月 31 日起完全免费,甚至用于商业用途(Apache 2.0 许可证)。Falcon 模型由阿布扎比技术创新研究所(TII)开发和训练。

根据初步结果,Falcon-40B,作为 Falcon 模型中最大的一个,超越了所有其他因果 LLM,包括 LLaMa-65B 和 MPT-7B。

在这篇博客文章中,我详细介绍了 Falcon-40B、Falcon-7B 及其指令版本。我们将看到它们与其他模型的表现对比、训练方式以及如何在自己的 GPU 上使用 QLoRa 运行 Falcon7-B。

OpenLLM 上的表现

Falcon-40B 的指令版本在OpenLLM 排行榜中排名第一。标准版本排名第二。

OpenLLM 排行榜评估 LLM 在 4 个任务上的表现:

  • AI2 Reasoning Challenge (25-shot):小学科学问题。

  • HellaSwag (10-shot):一个常识推理基准测试。

  • MMLU (5-shot):涵盖数学、计算机科学和法律等多个领域的 57 个任务。

  • TruthfulQA (0-shot):一个评估模型回答问题时真实性的基准。

Falcon-40B 在所有这些任务上都超越了 Meta AI 的 LLaMa-65B。

Falcon RefinedWeb

Falcon 模型主要在Falcon RefinedWeb数据集上进行训练。它也是由 TII 创建的,并在 Apache 2.0 许可证下分发。

RefinedWeb 从 CommonCrawl 中提取,并经过彻底策划。TII 声称它对多模态友好,因为保留了图片的链接和替代文本。

在 Hugging Face Hub 发布的数据集卡片中,TII 写道:“这个公开提取 […]”。对我来说,因此不清楚 Falcon 模型是否在这个仅为“提取”的公开版本数据集上进行训练,还是使用了更大的内部版本。

这个提取文件解压需要 2.8Tb 的硬盘空间。

由于它在 Hugging Face Hub 中可用,你只需运行以下代码即可开始使用:

from datasets import load_dataset
rw = load_dataset("tiiuae/falcon-refinedweb")

注意:你需要“datasets”库。如果没有,你可以通过“pip install datasets”安装。

RefinedWeb 与策划的语料库结合,以训练 Falcon 模型。

这个数据集代表了 Falcon 模型预训练数据的 75%。它仅涵盖英语。为了增加更多语言,他们还准备了“RefinedWeb-Europe”,涵盖了多种欧洲语言:德语、西班牙语、法语、意大利语、葡萄牙语、波兰语、荷兰语、罗马尼亚语、捷克语和瑞典语。

最后,为了覆盖更多的体裁和领域,他们添加了书籍、对话(例如,来自 Reddit)、代码、技术报告和科学论文(例如,来自 arXiv)的语料库。注意:他们没有透露“代码”的来源。也不清楚他们编制的数据集的许可证是什么。

总共,这相当于 1500 亿个标记用于预训练 Falcon 模型。

Falcon-40B 和 Falcon-7B 的预训练

对于预训练,他们使用了:

Falcon-40B 具有以下架构:

  • 层数:60

  • 嵌入维度:8,192

  • 头数:64

  • 词汇表大小:65,024

  • 序列长度:2,048

这与 LLaMa 的架构非常相似,只是词汇表大了一倍。

在我看来,序列长度在我们看到 LLM 接受超过 10,000 个标记的情况下,如 GPT-4 和Claude,显得相当短。

Falcon-7B 有一个较小的架构,使其能够在消费者硬件上进行微调。与 40B 版本唯一的区别是层数和嵌入维度减少了一半:

  • 层数:60

  • 嵌入维度:4,544

两个版本都使用了 bfloat16 精度和 AdamW。它们使用了 AWS SageMaker 和 384 个 A100 40GB GPU 的 P4d 实例,但尚未透露训练持续了多长时间。

Falcon-40B/7B 的指令版本

Falcon-40B7B 的指令版本表现更好。

Falcon-40B-Instruct 在 AWS SageMaker 上训练,使用了配备 64 个 A100 40GB GPU 的 P4d 实例。对于 Falcon-7B-Instruct,他们仅使用了 32 个 A100。

它们在 250 百万个标记的聊天/指令数据集混合数据上进行了微调,这些数据来源于Bai zeGPT4allGPTeacher和 1300 万标记的 RefinedWeb 语料库。

Bai ze 是由 ChatGPT 生成的数据集。我会对在商业应用中使用 Falcon 模型的指令版本保持谨慎。根据 OpenAI 的使用条款

“限制。你不得 […] (iii) 使用服务的输出开发与 OpenAI 竞争的模型”

“服务”包括 ChatGPT。而 Falcon-40B 是一个可以与 OpenAI 的 GPT 模型“竞争”的模型。

如何在你的 GPU 上使用 Falcon-7B 和 QLoRa

在上一篇文章中,我介绍了 QLoRa 在消费级硬件上微调 LLMs 的方法:

QLoRa: 在你的 GPU 上微调大型语言模型

现在可以在消费级硬件上对具有数十亿参数的模型进行微调。

towardsdatascience.com

你可以对 Falcon-7B 按相同的步骤操作,但它不会在 Google Colab 的免费实例上运行。模型需要过多的 CPU 内存。

如果你的计算机有 32 Gb 的 RAM,这应该可以工作。如果没有这么多 RAM,你将需要选择云计算或 Google Colab Pro 等方式。

一旦你有了支持 Falcon-7B 的环境,还有一些小修改需要对我的 QLoRa 教程进行调整。

首先,你必须安装“einops”:

pip install -q einops

然后,按如下方式修改模型的加载:

model = AutoModelForCausalLM.from_pretrained(model_id, quantization_config=bnb_config, device_map="auto", trust_remote_code=True)

在这一行中,“trust_remote_code=True” 是必要的。这是 Hugging Face 获得你同意一些代码由模型直接在你的机器上执行的方式。在这里,Falcon 运行一个配置脚本。

除此之外,其它方面应该与我的教程相同。

如果你不想使用 QLoRa 并且有 GPU 集群访问权限,标准的加载和运行 Falcon-7B/Falcon-40B 的方法可以参考 Hugging Face 模型卡片

from transformers import AutoTokenizer, AutoModelForCausalLM
import transformers
import torch

model = "tiiuae/falcon-40b"

tokenizer = AutoTokenizer.from_pretrained(model)
pipeline = transformers.pipeline(
    "text-generation",
    model=model,
    tokenizer=tokenizer,
    torch_dtype=torch.bfloat16,
    trust_remote_code=True,
    device_map="auto",
)
sequences = pipeline(
   "Girafatron is obsessed with giraffes, the most glorious animal on the face of this Earth. Giraftron believes all other animals are irrelevant when compared to the glorious majesty of the giraffe.\nDaniel: Hello, Girafatron!\nGirafatron:",
    max_length=200,
    do_sample=True,
    top_k=10,
    num_return_sequences=1,
    eos_token_id=tokenizer.eos_token_id,
)
for seq in sequences:
    print(f"Result: {seq['generated_text']}")

结论

Falcon 模型是预训练的 LLMs。如果你有数据进行微调,你可以将它们用于任何自然语言处理任务。请注意,即使不进行微调,标准(非指令型)版本在许多任务中已经表现得非常好,如在 OpenLLM 排行榜上所示,能够回答来自各个领域的问题并进行常识推理。

Falcon 模型的“指令”版本已经过微调。它们表现得像 ChatGPT,即具有一般知识的聊天机器人。

Falcon 模型也是流行的 LLaMa 模型的非常有趣的替代品。Falcon-40B 是:

  • 更小:LLaMa 有 65 亿参数,而 Falcon-40B 只有 40 亿参数,因此需要的内存较少。

  • 更好:在 OpenLLM 排行榜上,Falcon-40B 排名第一。

  • 免费:Falcon 模型在 Apache 2.0 许可证下分发,允许商业使用,而 LLaMa 只能用于研究目的。

如果你对这些模型感兴趣,关注这篇博客文章。TII 将发布一篇科学论文/技术论文,更详细地描述他们的工作。一旦上线,我会在这里提供链接。

如果你喜欢这篇文章并希望阅读接下来的文章,支持我的最佳方式是使用这个链接成为 Medium 会员:

[## 通过我的推荐链接加入 Medium - 本杰明·玛丽

加入我们的人工智能社区,获取前沿研究的访问权限。这个博客旨在揭示人工智能领域的最新进展。

medium.com](https://medium.com/@bnjmn_marie/membership?source=post_page-----98388fa40226--------------------------------)

如果你已经是会员并希望支持这项工作, 请在 Medium 上关注我

权重量化简介

原文:towardsdatascience.com/introduction-to-weight-quantization-2494701b9c0c?source=collection_archive---------0-----------------------#2023-07-07

使用 8 位量化来减少大型语言模型的大小

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 Maxime Labonne

·

关注 发表在 Towards Data Science ·14 分钟阅读·2023 年 7 月 7 日

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

大型语言模型(LLMs)以其广泛的计算需求而闻名。通常,通过将参数数量(大小)乘以这些值的精度(数据类型),可以计算模型的大小。然而,为了节省内存,可以通过一种称为量化的过程使用较低精度的数据类型来存储权重。

我们在文献中区分了两大类权重量化技术:

  • 训练后量化(PTQ)是一种直接的技术,其中已训练好的模型的权重被转换为较低的精度,而不需要进行任何重新训练。尽管实施起来简单,但 PTQ 可能会导致性能下降。

  • 量化感知训练(QAT)在预训练或微调阶段纳入权重转换过程,从而提升模型性能。然而,QAT 计算成本高且需要代表性的训练数据。

本文聚焦于 PTQ 以减少参数的精度。为了获得良好的直觉,我们将应用简单和更复杂的技术于一个使用 GPT-2 模型的示例。

完整代码可以在Google ColabGitHub上自由获取。

📚 浮点表示的背景

数据类型的选择决定了所需的计算资源量,影响模型的速度和效率。在深度学习应用中,平衡精度和计算性能成为一个至关重要的任务,因为更高的精度通常意味着更大的计算需求。

在各种数据类型中,浮点数由于能够以高精度表示广泛的值范围,因此在深度学习中被广泛使用。通常,浮点数使用n位来存储数值。这些n位进一步被划分为三个不同的部分:

  1. 符号:符号位指示数字的正负性质。它使用一个位,其中 0 表示正数,1 表示负数。

  2. 指数:指数是一段位表示基数(在二进制表示中通常为 2)的幂。指数可以是正数或负数,从而使数字能够表示非常大或非常小的值。

  3. 尾数/有效数字:剩余的位用于存储尾数,也称为有效数字。它表示数字的有效数字。数字的精度严重依赖于尾数的长度。

这种设计允许浮点数以不同精度覆盖广泛的值范围。用于这种表示的公式是:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

为了更好地理解这一点,让我们深入探讨在深度学习中最常用的数据类型:float32(FP32)、float16(FP16)和 bfloat16(BF16):

  • FP32 使用 32 位表示一个数字:一个位用于符号,八个位用于指数,其余 23 个位用于尾数。虽然它提供了较高的精度,但 FP32 的缺点是其计算和内存开销较大。

  • FP16 使用 16 位存储一个数字:一个用于符号,五个位用于指数,十个位用于尾数。虽然这使其在内存上更高效并加速计算,但减少的范围和精度可能会引入数值不稳定性,可能影响模型的准确性。

  • BF16也是一种 16 位格式,但有一个符号位,个位用于指数,个位用于尾数。BF16 扩展了表示范围,相较于 FP16,减少了下溢和溢出的风险。尽管由于尾数位数减少而精度降低,但 BF16 通常不会显著影响模型性能,是深度学习任务的一个有用折中方案。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

作者提供的图片

在机器学习术语中,FP32 通常被称为“全精度”(4 字节),而 BF16 和 FP16 则被称为“半精度”(2 字节)。但我们是否可以更进一步,用一个字节来存储权重?答案是 INT8 数据类型,它由一个 8 位表示组成,能够存储 2⁸ = 256 种不同的值。在下一节中,我们将看到如何将 FP32 权重转换为 INT8 格式。

🔰 初步的 8 位量化

在这一部分,我们将实现两种量化技术:一种是具有绝对最大值(absmax)量化的对称量化,另一种是具有零点量化的非对称量化。在这两种情况下,目标是将 FP32 张量X(原始权重)映射到 INT8 张量X_quant(量化权重)。

使用absmax 量化,原始数值除以张量的绝对最大值,并乘以缩放因子(127),将输入映射到范围[-127, 127]。要检索原始 FP16 值,INT8 数值除以量化因子,承认由于四舍五入导致的一些精度损失。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

例如,假设我们有一个绝对最大值为 3.2 的值。一个 0.1 的权重将被量化为round(0.1 × 127/3.2) = 4。如果我们想将其反量化,将得到4 × 3.2/127 = 0.1008,这意味着一个 0.008 的误差。以下是对应的 Python 实现:

import torch

def absmax_quantize(X):
    # Calculate scale
    scale = 127 / torch.max(torch.abs(X))

    # Quantize
    X_quant = (scale * X).round()

    # Dequantize
    X_dequant = X_quant / scale

    return X_quant.to(torch.int8), X_dequant

使用零点量化,我们可以考虑非对称输入分布,这在考虑 ReLU 函数的输出(仅正值)时特别有用。输入值首先按值的总范围(255)除以最大值和最小值之间的差异进行缩放。然后通过零点偏移将这个分布映射到范围[-128, 127](注意与 absmax 相比的额外值)。首先,我们计算缩放因子和零点值:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

然后,我们可以使用这些变量来量化或反量化我们的权重:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

例如:我们有一个最大值为 3.2 和一个最小值为-3.0。我们可以计算出缩放因子为255/(3.2 + 3.0) = 41.13,零点为*-round(41.13 × -3.0) - 128 = 123 -128 = -5*,因此我们之前的权重 0.1 将被量化为round(41.13 × 0.1 -5) = -1。这与之前使用 absmax 获得的值(4 与-1)差异很大。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

作者提供的图片

Python 实现非常简单:

def zeropoint_quantize(X):
    # Calculate value range (denominator)
    x_range = torch.max(X) - torch.min(X)
    x_range = 1 if x_range == 0 else x_range

    # Calculate scale
    scale = 255 / x_range

    # Shift by zero-point
    zeropoint = (-scale * torch.min(X) - 128).round()

    # Scale and round the inputs
    X_quant = torch.clip((X * scale + zeropoint).round(), -128, 127)

    # Dequantize
    X_dequant = (X_quant - zeropoint) / scale

    return X_quant.to(torch.int8), X_dequant

我们可以利用 transformers 库在真实模型上使用这两个函数,而不是依赖完整的玩具示例。

我们首先加载 GPT-2 的模型和分词器。这是一个非常小的模型,我们可能不想对其进行量化,但它对于本教程来说足够了。首先,我们想观察模型的大小,以便稍后进行比较,并评估由于 8 位量化而节省的内存

!pip install -q bitsandbytes>=0.39.0
!pip install -q git+https://github.com/huggingface/accelerate.git
!pip install -q git+https://github.com/huggingface/transformers.git
from transformers import AutoModelForCausalLM, AutoTokenizer
import torch
torch.manual_seed(0)

# Set device to CPU for now
device = 'cpu'

# Load model and tokenizer
model_id = 'gpt2'
model = AutoModelForCausalLM.from_pretrained(model_id).to(device)
tokenizer = AutoTokenizer.from_pretrained(model_id)

# Print model size
print(f"Model size: {model.get_memory_footprint():,} bytes")
Model size: 510,342,192 bytes

GPT-2 模型在 FP32 中的大小约为 487MB。下一步是使用零点和 absmax 量化权重。在以下示例中,我们将这些技术应用于 GPT-2 的第一个注意力层,以查看结果。

# Extract weights of the first layer
weights = model.transformer.h[0].attn.c_attn.weight.data
print("Original weights:")
print(weights)

# Quantize layer using absmax quantization
weights_abs_quant, _ = absmax_quantize(weights)
print("\nAbsmax quantized weights:")
print(weights_abs_quant)

# Quantize layer using absmax quantization
weights_zp_quant, _ = zeropoint_quantize(weights)
print("\nZero-point quantized weights:")
print(weights_zp_quant)
Original weights:
tensor([[-0.4738, -0.2614, -0.0978,  ...,  0.0513, -0.0584,  0.0250],
        [ 0.0874,  0.1473,  0.2387,  ..., -0.0525, -0.0113, -0.0156],
        [ 0.0039,  0.0695,  0.3668,  ...,  0.1143,  0.0363, -0.0318],
        ...,
        [-0.2592, -0.0164,  0.1991,  ...,  0.0095, -0.0516,  0.0319],
        [ 0.1517,  0.2170,  0.1043,  ...,  0.0293, -0.0429, -0.0475],
        [-0.4100, -0.1924, -0.2400,  ..., -0.0046,  0.0070,  0.0198]])

Absmax quantized weights:
tensor([[-21, -12,  -4,  ...,   2,  -3,   1],
        [  4,   7,  11,  ...,  -2,  -1,  -1],
        [  0,   3,  16,  ...,   5,   2,  -1],
        ...,
        [-12,  -1,   9,  ...,   0,  -2,   1],
        [  7,  10,   5,  ...,   1,  -2,  -2],
        [-18,  -9, -11,  ...,   0,   0,   1]], dtype=torch.int8)

Zero-point quantized weights:
tensor([[-20, -11,  -3,  ...,   3,  -2,   2],
        [  5,   8,  12,  ...,  -1,   0,   0],
        [  1,   4,  18,  ...,   6,   3,   0],
        ...,
        [-11,   0,  10,  ...,   1,  -1,   2],
        [  8,  11,   6,  ...,   2,  -1,  -1],
        [-18,  -8, -10,  ...,   1,   1,   2]], dtype=torch.int8)

原始(FP32)值和量化值(INT8)之间的差异很明显,但 absmax 和零点权重之间的差异则更微妙。在这种情况下,输入值看起来偏移了 -1。这表明这一层的权重分布相当对称。

我们可以通过对 GPT-2 中的每一层(线性层、注意力层等)进行量化,并创建两个新模型:model_absmodel_zp,来比较这些技术。准确地说,我们将实际用量化的权重替换原始权重。这有两个好处:它使我们可以 1/ 比较权重的分布(相同的尺度),以及 2/ 实际运行这些模型。

确实,PyTorch 默认不允许 INT8 矩阵乘法。在实际场景中,我们会将其去量化以运行模型(例如 FP16),但以 INT8 存储。在下一部分,我们将使用 [bitsandbytes](https://github.com/TimDettmers/bitsandbytes) 库来解决这个问题。

import numpy as np
from copy import deepcopy

# Store original weights
weights = [param.data.clone() for param in model.parameters()]

# Create model to quantize
model_abs = deepcopy(model)

# Quantize all model weights
weights_abs = []
for param in model_abs.parameters():
    _, dequantized = absmax_quantize(param.data)
    param.data = dequantized
    weights_abs.append(dequantized)

# Create model to quantize
model_zp = deepcopy(model)

# Quantize all model weights
weights_zp = []
for param in model_zp.parameters():
    _, dequantized = zeropoint_quantize(param.data)
    param.data = dequantized
    weights_zp.append(dequantized)

现在我们的模型已经被量化,我们想检查这一过程的影响。直观上,我们想确保量化的权重接近原始权重。一种直观的方法是绘制去量化和原始权重的分布。如果量化有损,它将极大地改变权重分布。

下图展示了这种比较,其中蓝色直方图表示原始(FP32)权重,红色直方图表示去量化后的(来自 INT8)权重。注意,我们仅在 -2 和 2 之间显示此图,因为有一些绝对值非常高的离群值(稍后会详细讨论)。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

两个图表非常相似,都在 0 附近有一个惊人的峰值。这个峰值表明我们的量化相当有损,因为反转过程并没有输出原始值。这在 absmax 模型中尤为明显,该模型在 0 附近显示了一个更低的谷值和一个更高的峰值。

让我们比较原始模型和量化模型的性能。为此,我们定义了一个 generate_text() 函数来生成 50 个标记,并使用 top-k 采样

def generate_text(model, input_text, max_length=50):
    input_ids = tokenizer.encode(input_text, return_tensors='pt').to(device)
    output = model.generate(inputs=input_ids,
                            max_length=max_length,
                            do_sample=True,
                            top_k=30,
                            pad_token_id=tokenizer.eos_token_id,
                            attention_mask=input_ids.new_ones(input_ids.shape))
    return tokenizer.decode(output[0], skip_special_tokens=True)

# Generate text with original and quantized models
original_text = generate_text(model, "I have a dream")
absmax_text   = generate_text(model_abs, "I have a dream")
zp_text       = generate_text(model_zp, "I have a dream")

print(f"Original model:\n{original_text}")
print("-" * 50)
print(f"Absmax model:\n{absmax_text}")
print("-" * 50)
print(f"Zeropoint model:\n{zp_text}")
Original model:
I have a dream, and it is a dream I believe I would get to live in my future. I love my mother, and there was that one time I had been told that my family wasn't even that strong. And then I got the
--------------------------------------------------
Absmax model:
I have a dream to find out the origin of her hair. She loves it. But there's no way you could be honest about how her hair is made. She must be crazy.

We found a photo of the hairstyle posted on
--------------------------------------------------
Zeropoint model:
I have a dream of creating two full-time jobs in America—one for people with mental health issues, and one for people who do not suffer from mental illness—or at least have an employment and family history of substance abuse, to work part

我们可以通过计算每个输出的困惑度来量化它,而不是尝试判断一个输出是否比其他输出更有意义。这是一个常用的评估语言模型的指标,用于测量模型在预测序列中下一个标记时的不确定性。在这个比较中,我们做了一个常见的假设,即分数越低,模型越好。实际上,高困惑度的句子也可能是正确的。

我们使用一个最小函数来实现它,因为不需要考虑上下文窗口的长度,因为我们的句子较短。

def calculate_perplexity(model, text):
    # Encode the text
    encodings = tokenizer(text, return_tensors='pt').to(device)

    # Define input_ids and target_ids
    input_ids = encodings.input_ids
    target_ids = input_ids.clone()

    with torch.no_grad():
        outputs = model(input_ids, labels=target_ids)

    # Loss calculation
    neg_log_likelihood = outputs.loss

    # Perplexity calculation
    ppl = torch.exp(neg_log_likelihood)

    return ppl

ppl     = calculate_perplexity(model, original_text)
ppl_abs = calculate_perplexity(model_abs, absmax_text)
ppl_zp  = calculate_perplexity(model_zp, absmax_text)

print(f"Original perplexity:  {ppl.item():.2f}")
print(f"Absmax perplexity:    {ppl_abs.item():.2f}")
print(f"Zeropoint perplexity: {ppl_zp.item():.2f}")
Original perplexity:  15.53
Absmax perplexity:    17.92
Zeropoint perplexity: 17.97

我们发现原始模型的困惑度略低于另外两个模型。一次实验并不十分可靠,但我们可以多次重复这个过程,以查看每个模型之间的差异。从理论上讲,零点量化应稍微优于 absmax,但计算成本也更高。

在这个例子中,我们将量化技术应用于整个层(每张量基础)。然而,我们可以在不同的粒度水平应用它:从整个模型到单个值。一次性量化整个模型会严重降低性能,而量化单个值会产生很大的开销。在实践中,我们通常更喜欢逐向量量化,它考虑了同一张量中行和列的值的变异性。

然而,即使是逐向量量化也不能解决离群特征的问题。离群特征是出现在所有变换器层中的极端值(负值或正值),当模型达到某个规模(>6.7B 参数)时。这是一个问题,因为一个离群值可以降低所有其他值的精度。但丢弃这些离群特征并不是一个选项,因为这会大大降低模型的性能。

🔢 8 位量化与 LLM.int8()

Dettmers et al. (2022)引入的 LLM.int8() 是解决离群值问题的一个方案。它依赖于逐向量(absmax)量化方案,并引入了混合精度量化。这意味着离群特征以 FP16 格式处理以保持其精度,而其他值则以 INT8 格式处理。由于离群值约占 0.1% 的值,这有效地将 LLM 的内存占用减少了近 2 倍。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

作者提供的图片

LLM.int8() 通过三个关键步骤进行矩阵乘法计算:

  1. 从输入隐藏状态X中提取包含离群特征的列,使用自定义阈值。

  2. 使用 FP16 对离群值进行矩阵乘法,并使用 INT8 进行逐向量量化(对隐藏状态X进行逐行量化,对权重矩阵W进行逐列量化)。

  3. 对非离群结果进行反量化(从 INT8 到 FP16),并将其与离群结果相加,以获得完整的 FP16 结果。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

作者提供的图片

这种方法是必要的,因为 8 位精度有限,当量化具有大值的向量时可能导致显著的误差。这些误差也会随着它们在多个层之间传播而放大。

由于 bitsandbytes 库已集成到 Hugging Face 生态系统中,我们可以轻松使用这项技术。我们只需在加载模型时指定 load_in_8bit=True(它还需要一个 GPU)。

device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

model_int8 = AutoModelForCausalLM.from_pretrained(model_id,
                                             device_map='auto',
                                             load_in_8bit=True,
                                             )
print(f"Model size: {model_int8.get_memory_footprint():,} bytes")
Model size: 176,527,896 bytes

通过这额外的一行代码,模型现在几乎缩小了三倍(168MB vs. 487MB)。我们甚至可以像之前那样比较原始权重和量化权重的分布:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在这种情况下,我们看到在 -2,-1,0,1,2 等值周围有尖峰。这些值对应于以 INT8 格式存储的参数(非异常值)。你可以通过使用 model_int8.parameters() 打印模型的权重来验证这一点。

我们还可以使用这个量化模型生成文本,并与原始模型进行比较。

# Generate text with quantized model
text_int8 = generate_text(model_int8, "I have a dream")

print(f"Original model:\n{original_text}")
print("-" * 50)
print(f"LLM.int8() model:\n{text_int8}")
Original model:
I have a dream, and it is a dream I believe I would get to live in my future. I love my mother, and there was that one time I had been told that my family wasn't even that strong. And then I got the
--------------------------------------------------
LLM.int8() model:
I have a dream. I don't know what will come of it, but I am going to have to look for something that will be right. I haven't thought about it for a long time, but I have to try to get that thing

再次强调,判断最佳输出是困难的,但我们可以依靠困惑度指标来给出一个(大致的)答案。

print(f"Perplexity (original):   {ppl.item():.2f}")

ppl = calculate_perplexity(model_int8, text_int8)
print(f"Perplexity (LLM.int8()): {ppl.item():.2f}")
Perplexity (original):   15.53
Perplexity (LLM.int8()): 7.93

在这种情况下,量化模型的困惑度是原始模型的两倍低。一般来说,这种情况并不常见,但它显示了这种量化技术的竞争力。实际上,LLM.int8()的作者展示了性能下降非常小,可以忽略不计(<1%)。然而,它在计算方面有额外的成本:对于大模型,LLM.int8()大约慢了 20%。

结论

本文概述了最流行的权重量化技术。我们首先了解了浮点表示,然后介绍了两种 8 位量化技术:absmax零点量化。然而,它们的局限性,特别是在处理异常值时,导致了 LLM.int8() 技术,该技术还保留了模型的性能。这种方法突显了权重量化领域的进展,揭示了正确处理异常值的重要性。

展望未来,我们的下一篇文章将深入探讨 GPTQ 权重量化技术。这项技术由 Frantar 等人 提出,只使用了 4 位,并且代表了权重量化领域的重大进展。我们将提供如何使用 AutoGPTQ 库实现 GPTQ 的全面指南。

如果你对更多关于 LLM 的技术内容感兴趣,可以在 Twitter 上关注我 @maximelabonne

参考文献

指数移动平均的直观解释

原文:towardsdatascience.com/intuitive-explanation-of-exponential-moving-average-2eb9693ea4dc?source=collection_archive---------2-----------------------#2023-12-16

理解在梯度下降算法中使用的基本算法背后的逻辑

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 Vyacheslav Efimov

·

关注 发表在 Towards Data Science ·6 分钟阅读·2023 年 12 月 16 日

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

介绍

在时间序列分析中,通常需要通过考虑之前的值来理解序列的趋势方向。序列中下一个值的近似可以通过多种方法进行,包括使用简单的基线或构建先进的机器学习模型。

指数(加权)移动平均 是这两种方法之间的一个强大折衷方案。其内部具有简单的递归方法,使得算法的高效实现成为可能。同时,它非常灵活,可以成功适应大多数类型的序列。

本文涵盖了该方法背后的动机、工作流程描述和偏差修正——一种有效的技术,用于克服近似中的偏差障碍。

动机

想象一个问题是近似一个随时间变化的给定参数。在每次迭代中,我们知道所有先前的值。目标是预测下一个值,它依赖于之前的值。

一种简单的策略是直接取最后几个值的平均值。这在某些情况下可能有效,但对于一个参数更依赖于最新值的情况并不十分合适。

克服这个问题的一种可能方法是对更近期的值分配更高的权重,对之前的值分配更少的权重。指数移动平均正是遵循这一原则的策略。它基于假设变量的近期值对形成下一个值的贡献大于先前的值

公式

为了理解指数加权移动平均的工作原理,让我们看一下它的递归方程:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

指数加权移动平均公式

  • vₜ 是一个时间序列,用于近似给定变量。它的索引 t 对应于时间戳 t。由于这个公式是递归的,因此初始时间戳 t = 0 的值 v₀ 是必需的。在实际应用中,v₀ 通常取为 0。

  • θ 是当前迭代中的观测值。

  • β 是一个介于 0 和 1 之间的超参数,用于定义如何在先前的平均值 vₜ-₁ 和当前观测值 θ 之间分配权重的重要性。

让我们写出这个公式来计算前几个参数值:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

计算 t 时刻的公式

结果是,最终公式如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

t 时刻的指数移动平均

我们可以看到,最近的观测值 θ 的权重为 1,倒数第二个观测值的权重为 β,倒数第三个观测值的权重为 β²,依此类推。由于 0 < β < 1,乘法项 βᵏ 随着 k 的增加而指数下降,因此,观测值越老,其重要性越低。最后,每个求和项都乘以 (1 —β)。

在实践中,β 的值通常选择接近 0.9。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

不同时间戳的权重分布(β = 0.9)

数学解释

利用数学分析中的著名第二个奇妙极限,可以证明以下极限:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

第二个奇妙极限

通过将 β = 1 - x 代入,我们可以将其改写成如下形式:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

另一种形式的奇妙极限

我们还知道,在指数加权平均的公式中,每个观察值都乘以一个 βᵗ 的项,其中 t 表示观察值被计算的时间戳数。由于基数 β 在两种情况中是相等的,我们可以使两个公式的指数相等:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

通过使用这个公式,对于选择的 β 值,我们可以计算出权重项达到 1 / e ≈ 0.368 的大致时间戳数量 t。这意味着在最近的 t 次迭代中计算的观察值的权重项大于 1 / e,而在最后 t 个时间戳范围之外计算的观察值的权重低于 1 / e,其重要性则大大减少。

实际上,低于 1 / e 的权重对指数加权平均的影响微乎其微。这就是为什么人们说对于给定的 β 值,指数加权平均会考虑到最后的 t = 1 / (1 - β) 个观察值

为了更好地理解公式,让我们插入不同的 β 值**:**

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

例如,选择 β = 0.9 表示大约在 t = 10 次迭代后,权重衰减到 1 / e,相较于当前观察值的权重。换句话说,指数加权平均主要依赖于最后的 t = 10 个观察值。

偏差修正

使用指数加权平均的一个常见问题是,在大多数问题中,它不能很好地近似前几项值。这是由于在前几次迭代中缺少足够的数据。例如,假设我们给定了以下时间序列:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

目标是用指数加权平均来近似它。然而,如果我们使用常规公式,那么前几个值将对 v₀ 赋予较大权重,而 v₀ 为 0,尽管散点图上的大多数点都在 20 以上。因此,初始的加权平均序列将会过低,无法准确近似原始序列。

一种简单的解决方案是将 v₀ 的值设置得接近第一次观察值 θ₁。虽然这种方法在某些情况下效果很好,但它仍然不完美,特别是当给定序列波动时。例如,如果 θ₂ 与 θ₁ 差异过大,那么在计算第二个值 v₂ 时,加权平均通常会更重视先前的趋势 v₁ 而不是当前的观察值 θ₂。结果,近似值将会非常差。

更加灵活的解决方案是使用一种称为“偏差修正”的技术。它不是简单地使用计算得到的值 vₖ,而是将其除以 (1 —βᵏ)。假设 β 选择接近 0.9–1,这个表达式在初始迭代中,当 k 较小的时候,趋近于 0。因此,与其慢慢累积前几个值,其中 v₀ = 0,不如将它们除以一个相对较小的数,使它们变成更大的值。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

带有和不带有偏差修正的指数移动平均计算示例

一般来说,这种缩放方法效果很好,并能精确地调整前几个项。当 k 增大时,分母逐渐接近 1,从而逐渐忽略这种缩放的效果,因为从某一迭代开始,算法可以高可信度地依赖于其最近的值,而无需任何额外的缩放。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

结论

在本文中,我们介绍了一种极其有用的时间序列近似技术。指数加权平均算法的鲁棒性主要通过其超参数 β 来实现,该参数可以针对特定类型的序列进行调整。除此之外,引入的偏差修正机制使得即使在信息较少的早期时间戳上,也能有效地近似数据。

指数加权平均在时间序列分析中具有广泛的应用范围。此外,它还被用于梯度下降算法的变体中,以加速收敛。其中最受欢迎的之一是深度学习中的动量优化器,它消除了优化函数的不必要振荡,使其更精确地对准局部最小值。

除非另有说明,所有图像均由作者提供

逆物理信息化神经网络

原文:towardsdatascience.com/inverse-physics-informed-neural-net-3b636efeb37e?source=collection_archive---------2-----------------------#2023-03-27

iPINN ~with code

解决逆微分方程问题

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 John Morrow

·

关注 发表在 Towards Data Science ·11 min read·2023 年 3 月 27 日

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

照片由 Daniele Levis Pelusi 提供,来源于 Unsplash

(1) 引言:什么是物理信息化?

物理学、生物学、化学、经济学、工程学等许多领域的关系由微分方程定义。(请参见这里获取详细列表。)一般来说,微分方程(DE)描述了变量如何受到其他变量变化率的影响。例如,微分方程解释了当质量在弹簧上振动时,其位置如何随时间变化,这与质量的速度和加速度相关。物理信息神经网络(PINN)生成遵循微分方程描述的关系的响应(无论研究对象是物理学、工程学、经济学等)。相比之下,逆物理信息神经网络(iPINN)作用于响应并确定产生该响应的微分方程的参数。PINN 和 iPINN 通过在训练过程中包含一个约束来进行训练,该约束迫使神经网络的输入和输出之间的关系符合所建模的微分方程。

本文从 PINN 的实现开始,然后在 PINN 模型的基础上实现 iPINN。对建模微分方程的解析解包括在内,以便与 PINN 和 iPINN 产生的响应进行比较。

(2) 二阶微分方程

本文重点讨论描述阻尼谐波运动的 PINN 和 iPINN,例如带阻尼的弹簧-质量系统(图 1)和由电阻、电感和电容(RLC)串联连接的组件组成的电子电路(图 2)。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 1:振动质量与弹簧

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2:RLC 电路

这些应用由二阶微分方程(DE)定义,其中包括相对于时间的二阶导数。方程 1 是弹簧-质量系统的二阶微分方程,其中参数 m、c 和 k 分别是质量、阻尼系数和弹簧常数。质量的位移由 x 表示,时间由 t 表示。x 对 t 的二阶导数是质量的加速度,而一阶导数是质量的速度。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

方程 1

方程 2 是 RLC 电路的二阶微分方程,其中 R、L 和 C 分别是电阻、电感和电容。电路中的电流由 i 表示,时间由 t 表示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

方程 2

这两个微分方程产生类似的响应,即质量从静止位置被位移后释放时的运动,以及在预充电电容器并施加初始电压后关闭开关时电流随时间的变化。下一节介绍 RLC 电路响应的详细信息。

(3) RLC 电路响应

以下是图 2 中 RLC 电路可能响应的概述,包括每个响应的方程 2 的解析解方程。(作者提供的解析解推导可以在 这里 下载。)解析响应将在后续与 PINN 生成的和 iPINN 生成的响应进行比较。

根据组件的值,这个 RLC 电路可以产生三种不同类型的响应:欠阻尼、临界阻尼和过阻尼。所有这三种响应都基于在开关关闭之前电容器充电到电压 V₀ 和以下初始条件:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

方程 3

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

方程 4

(3.1) 欠阻尼响应

当 R、L 和 C 的值产生以下条件时,会发生欠阻尼响应:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

方程 5

例如,设 R = 1.2(欧姆),L = 1.5(亨利),C = 0.3(法拉),V₀ = 12(伏特)。这些值的方程 2 的解析响应为:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

方程 6

以下是方程 6 的响应图。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3: 欠阻尼响应

(3.2) 临界阻尼响应

当 R、L 和 C 的值产生以下条件时,会发生临界阻尼响应:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

方程 7

例如,设 R = 4.47(欧姆),L = 1.5(亨利),C = 0.3(法拉),V₀ = 12(伏特)。这些值的方程 2 的解析响应为:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

方程 8

以下是方程 8 的响应图。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4: 临界阻尼响应

(3.3) 过阻尼响应

当 R、L 和 C 的值产生以下条件时,会发生过阻尼响应:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

方程 9

例如,设 R = 6.0(欧姆),L = 1.5(亨利),C = 0.3(法拉),V₀ = 12(伏特)。这些值的方程 2 的解析响应为:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

方程 10

以下是方程 10 的响应图。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 5: 过阻尼响应

(4) PINN 结构

通常,神经网络使用已知的输入和输出数据对进行训练。训练输入数据被输入神经网络,产生的输出与训练输出数据通过损失函数进行比较。此函数返回的损失值通过反向传播调整网络权重,以减少损失。PINNs 和 iPINNs 使用自定义损失函数,包括额外的损失组件,以约束神经网络生成符合所建 DE 的输出。

一个 DE 的 PINN 模型在方程 2 中将时间 t 作为神经网络的输入,输出对应的电流 i。训练 PINN 以符合 DE 需要计算输出相对于输入的第一和第二导数,即 di/dtd²i/dt²。这些导数在 TensorFlow 和 PyTorch 中通过各个平台的自动微分功能获得。本文中的 PINN 和 iPINN 是通过 TensorFlow 的GradientTape开发的。

对于每个 PINN 训练输入,GradientTape 计算的第一和第二导数与 RLC 按照方程 2 中的 DE 组合,产生的结果应为零。实际结果与零之间的差异称为残差。残差成为用于训练 PINN 的损失函数的一个组成部分。

二阶 DE,如方程 2,还要求解符合两个初始条件。在这种情况下,第一个条件是 t = 0i 的值(方程 3),第二个条件是 t = 0di/dt 的值(方程 4)。每个初始条件都作为损失函数的一个组成部分。

图 6 展示了总损失的组成。损失 2 来自残差。损失 1 和损失 3 来自初始条件。在训练过程中,反向传播用于减少总损失。PINN 的 d²i/dt²di/dt 输出由 GradientTape 提供。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 6: PINN 损失函数

(5) PINN 实现

以下是 PINN 实现的 python 代码。完整的 PINN 实现代码可以在这里找到。

(5.1) 神经网络模型定义

PINN 的神经网络具有两个全连接的隐藏层,每层有 128 个神经元。时间点有一个输入,响应点有一个输出。

列表 1: PINN TensorFlow 模型

(5.2) PINN 初始化

在 PINN 模型中,RLC组件值以及初始电容电压(第 2-5 行)是决定 DE 响应的常数。共同位置点,指定在时间域中(第 8 行),是计算残差的点。初始条件(第 11 和 15 行)来自方程 3 和方程 4。

列表 2: PINN 初始化

(5.3) PINN 训练步骤

以下是训练步骤函数的 Python 代码。对于每个训练批次,步骤函数计算三部分损失,然后使用总损失更新神经网络中的权重。

损失 1: 方程 3 的初始条件与网络输出 pred_y(第 9 行)进行比较。差异的平方是 model_loss1(第 10 行)。

损失 2: 共定位点(第 30 行)计算残差。它使用来自 GradientTape 的一阶梯度 dfdx(第 17 行)和二阶梯度 dfdx2(第 26 行),以及网络输出 pred_y(第 29 行),来计算方程 2 的左侧。这一值的平方为 model_loss2(第 31 行)。

损失 3: 方程 4 的初始条件将 L 与一阶梯度 dfdx(第 17 行)的乘积与 v_init2 比较。差异的平方为 model_loss3(第 19 行)。

三个损失组件的总和,model_loss(第 35 行),用于计算损失相对于神经网络权重的梯度(第 38 行)。优化器随后更新权重(第 41 行)。

清单 3:PINN 训练步骤

(6) PINN 结果

下面是对三个测试案例训练 PINN 的结果。这些测试条件如第三部分所述:欠阻尼、临界阻尼和过阻尼。每个图展示了三个轨迹:

  • 解析方程的响应(蓝色)

  • 共定位点(绿色)

  • 训练好的 PINN 的输出响应(红色)

欠阻尼测试案例:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 7:欠阻尼响应

临界阻尼测试案例:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 8:临界阻尼响应

过阻尼测试案例:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(7) iPINN 结构

图 10 说明了总损失的组成。与 PINN 模型类似,损失 2 来自残差,只是 RLC 是在训练过程中确定的变量。相比之下,在 PINN 模型中,RLC 是常数。与 PINN 一样,损失 1 和损失 3 强制遵守方程 3 和方程 4 的初始条件。

iPINN 模型包括一个额外的损失函数,损失 4,强制输出响应与待调查的微分方程响应匹配。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 10:iPINN 损失函数

(8) iPINN 实现

以下是 PINN 实现的 Python 代码。iPINN 实现的完整代码可以在这里找到。

iPINN 的神经网络模型定义与 PINN 网络(第 5.1 节)相同,即两个完全连接的隐藏层,每层有 128 个神经元。输入为时间点,输出为响应点。

(8.1) iPINN 初始化

被研究的微分方程的响应被加载在第 4 行。两个初始条件(第 9 行和第 13 行)与 PINN 模型中的相同。如上所述,RLC是 iPINN 模型中的可训练变量(第 18–20 行)。

(8.2) iPINN 训练步骤

损失 1: 方程 3 的初始条件与网络输出pred_y(第 10 行)进行比较。差异的平方为model_loss1(第 11 行)。

损失 2: 与 PINN 训练步骤函数一样,残差(第 34 行)在由t_coloc定义的共定位点处计算,产生model_loss2(第 35 行)。RLC是可训练变量。

损失 3: 方程 4 的初始条件将可训练变量L与一阶梯度dfdx(第 18 行)的乘积进行比较,以* v_init2为标准。差异的平方为model_loss3*(第 20 行)。

损失 4: 该损失组件将网络输出(第 39 行)与被研究的微分方程的响应i_coloc进行比较,产生model_loss4(第 40 行)。

四个损失组件的总和,model_loss(第 43 行),用于计算损失相对于神经网络权重和三个可训练变量:RLC(第 49 行)的梯度。然后优化器更新网络的权重(第 52 行),并在第 53–55 行更新RLC的值。

(9) iPINN 结果

以下是使用 iPINN 识别三个未知测试响应的结果。呈现给 iPINN 的测试响应是根据第三部分的条件生成的:欠阻尼、临界阻尼和过阻尼。下表比较了用于生成测试响应的RLC组件值与 iPINN 确定的值。每个图表呈现三个轨迹:

  • 解析方程的响应曲线(蓝色)

  • 需要由 iPINN 识别的响应数据(60 点)(绿色)

  • 训练后的 iPINN 输出响应(红色)

欠阻尼测试案例:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

表 1:欠阻尼测试案例

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 11:欠阻尼响应

临界阻尼测试案例:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

表 2:临界阻尼测试案例

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 12:临界阻尼响应

过阻尼测试案例:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

表 3:过阻尼测试案例

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 13:过阻尼响应

(10) 结论

这项研究展示了神经网络可以成功求解微分方程,这些方程描述了科学、工程和经济学众多领域中的许多关系。训练了一个物理信息神经网络来解决电子电路的二阶微分方程,结果是一个能够对输入信号产生与实际电路相同响应的神经网络。

这项研究还展示了神经网络能够确定未知微分方程的参数。具体而言,训练了一个逆物理信息神经网络,通过仅使用来自电路的样本响应来确定电子电路的未知组件值。此外,在确定未知组件值后,得到的神经网络能够对输入信号产生与实际电路相同的响应。

参考文献

[1] M. Raissi, P. Perdikaris, 和 G. E. Karniadakis, “物理信息深度学习(第一部分):非线性偏微分方程的数据驱动解法”,2017. [在线]. 网址: https://arxiv.org/abs/1711.10561

[2] M. Raissi, P. Perdikaris, 和 G. E. Karniadakis, “物理信息深度学习(第二部分):非线性偏微分方程的数据驱动发现”,2017. [在线]. 网址: arxiv.org/abs/1711.10566

这篇文章的 pdf 版本可以 在这里下载

除非另有说明,所有图片均由作者提供。

ChatGPT 真的智能吗?

原文:towardsdatascience.com/is-chatgpt-actually-intelligent-42d07462fe59

也许不是……

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 兰楚

·发表于 Towards Data Science ·阅读时间 12 分钟·2023 年 7 月 21 日

如果你在过去几个月里使用过任何社交媒体平台,我相信你一定听说过 ChatGPT、Google Bard、Microsoft Bing 和许多新的语言模型。所有这些新模型,有人可能会争辩说,比你我写得更好,他们的英语也确实比我的好 🥲 每隔几年,就会有人发明一些疯狂的东西,让你完全重新考虑可能性。而在这篇文章中,我们将讨论一种让全世界都在震撼的发明——是的,你猜对了——ChatGPT。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图片由 Bing 图像创建器生成。对人类智能的艺术表现。

随着我们越来越依赖 AI 为我们做事和做决策,提出 AI 是否真正智能的问题是自然的,特别是它对语言的理解是否反映了我们自己的理解,还是在本质上有所不同?

为了理解这一切,我们将首先探讨生成预训练变换器(GPT)和 ChatGPT 的工作原理,然后讨论 AI 智能的含义。

理解 GPT 模型

GPT 模型最初由 OpenAI 在其论文 改进语言理解的生成预训练 中提出,使用无监督预训练,然后在各种语言任务上进行监督微调。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

来源: language_understanding_paper.pdf

该模型架构基于 Transformers,已在机器翻译和文档生成等任务中展现出强大的性能。该模型架构首次在 Google 研究人员的论文 “Attention is all you need” 中提出。与递归神经网络卷积神经网络相比,它提供了一个有组织的内存,用于管理文本中的长期依赖关系,从而在广泛的任务中实现了更好的性能。

这是一个预测游戏

你可以将 GPT 模型视为一种擅长预测下一个内容的机器。例如,如果你给它短语“她没有右转,而是转……”,GPT 可能会预测“左转”或“回转”或其他作为下一个单词。它是如何学习到这一点的?它通过阅读大量现有文本,学习单词在与其他单词的上下文中如何出现,并预测可能出现的下一个最可能的单词。或者更准确地说,它学习如何解读数据中的位置编码。这意味着我们给句子中的每个单词打上一个编号,当你在大量文本上训练模型时,它学习如何解读句子中每个单词的位置编码。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图片由作者提供。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图片由作者提供。

Transformer

但这不仅仅是一次猜一个词,它是在考虑整个句子甚至段落——这就是 transformer 架构发挥作用的地方。

帮助 GPT 做出这些预测的“魔法成分”是 transformer 架构中的自注意力机制。该机制帮助模型在预测下一个单词时确定句子中每个单词的重要性。例如,在句子“我每天都带着我的狗散步,因为它让我……”中,单词“狗”可能会提示 GPT 下一个单词很可能与狗和情感相关,如“快乐”或“放松”。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

来源:language_understanding_paper.pdf

自注意力机制

自注意力究竟是什么?让我们想象一群人(单词)正在玩一个游戏(句子)。在这个游戏中,每个玩家代表一个句子中的单词。现在,想象每个玩家需要确定他们应该多关注场上其他每个玩家,包括自己,以预测游戏中的下一个动作。

在这个上下文中,自注意力机制就像每个玩家与游戏中的其他所有玩家进行交流。这种交流使他们能够评估其他每个玩家的重要性。有些玩家对你可能显得非常重要(高注意力),而其他玩家可能显得不那么重要(低注意力)。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

作者提供的图片。箭头的粗细代表了强注意力。

重要性的级别由每个玩家与个人对游戏理解的相关性决定。例如,如果你在足球比赛中是前锋,你可能会发现中场球员非常重要,因为他们支持你的进攻,而门将可能对你的即时行动看起来不那么重要。

现在,想象这一切同时发生,每一个玩家与所有其他玩家进行沟通,以了解他们在游戏中的相关性。由此,每个玩家计算出每个其他玩家的显著性分数,包括他们自己。

换句话说,每个玩家不仅仅是考虑一个其他玩家,而是同时考虑场上所有其他玩家。这种同时考虑是自注意力机制的一个关键特性,它使模型能够捕捉游戏中玩家之间复杂的关系和依赖。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

作者提供的图片。

在上述例子中,“word”这个词的意思非常不同。自注意力机制允许模型在周围词语的上下文中理解一个词。当模型处理第一个句子中的“server”时,它可能会关注“check”这个词,而在第二个句子中,服务器可能会关注“crashed”这个词,因为模型理解第二个句子中“server”指的是计算机服务器/系统的唯一方式是通过“crashed”这个词。同时,在第一个句子中,词“server”关注“check”这个词,因为这是模型理解第一个句子中“server”指的是一个人的唯一方式。

自注意力机制允许 GPT 模型在预测下一个词时权衡句子中每个词的重要性,通过将每个词的权重输出为一个向量,这些向量将作为预测层的输入。

预测层

Transformer 层顶部的最终部分是一个线性层,它将 Transformer 层的向量输出转换为一组 logits——机器学习模型分配的用于预测句子中下一个词的分数。每个可能的下一个词汇都获得一个 logit(一个分数)。这些 logits 随后通过 SoftMax 函数获得概率,具有最高概率的词被选择为预测词。

这个过程类似于一个预测游戏。 由于在我们的示例句子“Instead of turning right, she turns…”中,可能出现很多种接下来的单词,因此模型响应的方式中存在一定的随机性。在许多情况下,GPT 模型可以用不同的方式回答相同的问题——我认为我们所有人都在与 ChatGPT 互动时经历过这种情况。

ChatGPT 的工作原理

微调 GPT 模型以进行对话

ChatGPT 是 GPT-3.5 的一个微调版本,并且已经以一种允许它理解和响应用户问题和指令的方式进行了开发。

训练数据

三个主要的信息来源是(1)互联网上公开可用的信息,(2)从第三方处获得的许可信息,以及(3)用户或人类训练师提供的信息。

训练过程

在这一部分,我将对 ChatGPT 的训练过程进行高层次的解释,其中包括监督微调、创建奖励模型用于强化学习以及使用邻近策略优化(PPO)进行微调。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

来源:训练语言模型以遵循人类反馈的指令 OpenAI 等,2022 arxiv.org/pdf/2203.02155.pdf

第 1 步:训练一个监督学习模型

在这一步中,目标是向模型提供所需行为的示例。这是通过让人类 AI 训练师与模型进行互动来实现的。

这从收集用户的提示开始。这些提示然后交给 AI 训练师,AI 训练师生成展示所需输出行为的响应。然后,这些提示-响应标注数据被用来微调 GPT-3.5,目标是在未来面对类似提示时生成类似的响应。

第 2 步:训练一个奖励模型以进行强化学习

目标是训练一个奖励模型,该模型根据监督微调模型输出的结果对其进行评分,这些输出对于 AI 训练师来说是多么令人满意。换句话说,这个奖励模型根据 AI 训练师的偏好对输出的质量进行评估。

这就是它的工作原理:

  • 选择一个提示列表,监督微调模型为每个提示生成多个输出。

  • AI 训练师对输出结果进行从最好到最差的排名。结果是一个新的标注数据集,其中的排名就是标签。

  • 这些新数据用于训练一个奖励模型,该模型接受 SFT 模型的输出并按偏好顺序对其进行排名。

第 3 步:使用 PPO 算法优化策略

强化学习(RL)现在被应用于通过优化奖励模型来改进策略。在 RL 中,策略是代理在环境中做出决策时遵循的策略或规则集合。这是一种让代理根据当前状态确定采取何种行动的方法。

强化学习如何工作——以捉迷藏游戏为例

RL 是通过与环境的连续交互来优化长期目标的学习过程。根据当前输入,你做出决策,下一次输入取决于你的决策。PPO(近端策略优化)是 OpenAI 用来训练 RL 代理的算法。在 RL 中,代理/AI 直接从和更新当前策略中学习,而不是仅仅从过去的经验(仅训练数据)中学习。这意味着 PPO 根据代理采取的行动和收到的奖励不断更新当前策略。

首先,在第 1 步中训练过的监督微调模型用于初始化 PPO 模型。它会在给定提示时生成一个响应。在下一阶段,奖励模型(在第 2 步中建立)为响应生成奖励分数。最后,奖励反馈给基准模型,以使用 PPO 算法更新参数,旨在提高未来更好响应的可能性。这个过程会重复多次,模型随着从奖励模型收到更多反馈而不断改进,并使用 PPO 调整其参数。这使得模型能够从人类反馈中学习,并提高生成未来更好响应的能力。

GPT 模型真的“智能”吗?

尽管 GPT 模型生成类人文本的能力令人印象深刻,但它对语言的理解是否与人类的理解相同或有根本区别?

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

由 Dall-E 2 生成的图像。经典的智能概念。

一项来自斯坦福大学的研究尝试了解预训练语言模型(PTLM),如 BERT 或 RobBERTa,是否能够通过找出上下文与定义之间的语义相关性来理解定义。该方法是,在给定上下文句子c中的目标词w时,模型需要检测一个句子g是否可以被视为w定义的描述。PTLM 通过使用余弦相似度计算上下文嵌入与候选定义嵌入之间的语义相似性,余弦相似度计算两个嵌入之间角度的余弦值。余弦相似度越接近 1,两者的语义相似性越高。研究发现,PTLM 在定义抽象时难以理解。

所以,我想第一个需要解决的问题是“理解”和“智能”实际上是什么意思。

在这方面,《随机鹦鹉的危险:语言模型是否过大?》 的作者认为由大型语言模型生成的文本缺乏实际的意义和意图

传统上,当两个人进行对话时,他们都会尽力理解对方的信仰、知识、经验和观点。我们选择使用的词语和我们所说的内容取决于我们对对方的心理“图景”或理解。无论是孩子还是成人,同事还是家庭成员,伴侣,还是我们在公交车站刚认识的人,我们对他们的思想和特征都有一定的假设。同样,当我们听别人讲话时,我们会根据对他们的心理理解,包括他们的信仰、知识、理解和意图,自动将他们的话语置于背景中。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图片来源:Priscilla Du PreezUnsplash

当语言模型生成文本时,它没有任何沟通的意图,也不会考虑阅读者的信仰或思想。用于创建模型的训练数据并未涉及与听众互动或理解他们的观点。实际上,语言模型不能像人类一样理解和进行有意义的沟通。

然而,我们的人脑受到语言的影响很大,我们将与大型语言模型的沟通解释为它们试图传达有意义的意图。如果沟通的一方缺乏实际意义,我们对更深层次/推断意义的理解就变成了一种幻觉。

从 GPT 模型的构建方式来看,显然这些语言模型并不以自觉的方式处理信息和生成文本。这完全是一个预测游戏,根据模型从训练数据中看到的模式来预测接下来会出现哪些词。此外,像 ChatGPT 这样的语言模型有时会写出看似合理但实际上错误或无意义的答案,因为它并不像我们——人类一样拥有常识推理能力。

人工智能能获得意识吗?

人类智能和理解与意识是密不可分的——意识是感知事物、痛苦、快乐、爱和愤怒的能力。意识与有机体相关联,因此自然会有一个问题:非有机系统是否可能获得意识?因为我们对人类意识知之甚少,所以不能排除计算机发展意识的可能性。这仍然是一个正在进行的研究,无论 AI 是否能够拥有意识,我们可能在未来几十年中会看到。不过,也许有一个好消息是,至少目前我们不必面对科幻小说中的噩梦——AI 获得意识并决定奴役和消灭人类的情景 😃.

我认为,机器智能要达到类似于人类智能的水平还需要很长时间。“想象 AI 系统拥有情感甚至人类水平的意识已经不再是科幻小说中的场景,”BBC说道。大多数专家同意,AI 离这种复杂程度还很遥远,但它正以闪电般的速度发展,难以想象未来几年会是什么样子。

我相信我们可以相当有信心地说,当前的人工智能模型已经发展出一套与人类智能某些方面密切相关的技能。也许是时候让 AI 创造者更多地投资于理解意识。

参考文献

  1. 介绍 ChatGPT (openai.com)

  2. ChatGPT 和我们的语言模型如何开发 | OpenAI 帮助中心

  3. ChatGPT 的幕后故事:由创建者讲述 | MIT 技术评论

  4. Brown, T., Mann, B., Ryder, N., Subbiah, M., Kaplan, J. D., Dhariwal, P., … & Amodei, D. (2020). 语言模型是少样本学习者。神经信息处理系统的进展, 33, 1877–1901。

  5. Ouyang, L., Wu, J., Jiang, X., Almeida, D., Wainwright, C., Mishkin, P., … & Lowe, R. (2022). 通过人类反馈训练语言模型以遵循指令。神经信息处理系统的进展, 35, 27730–27744。

  6. Radford, A., Narasimhan, K., Salimans, T., & Sutskever, I. (2018). 通过生成预训练提高语言理解能力。

  7. Bender, E. M., Gebru, T., McMillan-Major, A., & Shmitchell, S. (2021 年 3 月). 关于随机鹦鹉的危险:语言模型是否可能过大?🦜. 收录于2021 年 ACM 公平性、问责制与透明度会议论文集(第 610–623 页)。

  8. 人工智能真的智能吗?如果你曾经在任何社交媒体上… | 作者:Telmo Subira Rodriguez | 2023 年 7 月 | Medium

  9. Vaswani, A., Shazeer, N., Parmar, N., Uszkoreit, J., Jones, L., Gomez, A. N., … & Polosukhin, I. (2017). 注意力机制就是你所需的一切。神经信息处理系统进展, 30

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值