困惑度 (Perplexity)

本文深入浅出地解释了困惑度(Perplexity)这一概念,着重于如何用它来评估语言模型的效果。通过比较不同语言模型在测试集上的表现,特别是三元语言模型在训练文本后的困惑度降低情况,展示了困惑度作为评价指标的有效性和实用性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

通俗解释困惑度 (Perplexity)-评价语言模型的好坏

通俗解释困惑度 (Perplexity)-评价语言模型的好坏

忆臻

忆臻

哈尔滨工业大学 计算机科学与技术博士在读

55 人赞同了该文章

一、语言模型

本文尽量通俗解释一下困惑度的概念。既然题目中写了是用来评价语言模型的好坏,那么首先来看一下语言模型:

忆臻:深入浅出讲解语言模型​zhuanlan.zhihu.com图标

简单地说,语言模型就是用来计算一个句子的概率的模型,也就是判断一句话是否是人话的概率?

那么如何计算一个句子的概率呢?给定句子(词语序列)

它的概率可以表示为:

也就是说在给定一句话的前k个词,我们希望语言模型可以预测第k+1个词是什么,即给出一个第k+1个词可能出现的概率的分布p(xk+1|x1x2...xk)。

那么如何学习到一个语言模型呢,这里不详细叙述,可以参考:

忆臻:深入浅出讲解语言模型​zhuanlan.zhihu.com图标

二、如何评价一个语言模型好坏

在得到不同的语言模型(一元语言模型、二元语言模型....)的时候,我们如何判断一个语言模型是否好还是坏,一般有两种方法:

1、一种方法将其应用到具体的问题当中,比如机器翻译、speech recognition、spelling corrector等。然后看这个语言模型在这些任务中的表现(extrinsic evaluation,or in-vivo evaluation)。但是,这种方法一方面难以操作,另一方面可能非常耗时,可能跑一个evaluation需要大量时间,费时难操作。

2、针对第一种方法的缺点,大家想是否可以根据与语言模型自身的一些特性,来设计一种简单易行,而又行之有效的评测指标。于是,人们就发明了perplexity这个指标。

困惑度(perplexity)的基本思想是:给测试集的句子赋予较高概率值的语言模型较好,当语言模型训练完之后,测试集中的句子都是正常的句子,那么训练好的模型就是在测试集上的概率越高越好,公式如下:

[公式]

由公式可知,句子概率越大,语言模型越好,迷惑度越小。

下面是一些 ngra­m 模型经 训练文本后在测试集上的困惑度值:

可以看到,之前我们学习的 trigram 模型经训练后,困惑度由955跌减至74,这是十分可观的结果。

这节的核心就是句子概率越大,语言模型越好,迷惑度越小。

### 深学习中困惑的概念 在深学习领域,尤其是自然语言处理(NLP)困惑(Perplexity)是一个常用的评价指标。该指标用于衡量语言模型的好坏,能够反映模型对于给定数据集的不确定性程[^4]。 具体来说,语言模型可以预测序列(例如一个句子)中每个时间步词元(例如一个句子中的逐个单词)的概率分布,并据此计算整个序列的概率。较困惑意味着模型更精确地捕捉到了文本的真实概率分布,即模型表现更好。 ### 困惑的定义与意义 困惑被定义为: \[ \text{PPL} = \exp\left(-\frac{\sum_{i=1}^{N}\log p(w_i|w_1,...,w_{i-1})}{N}\right)\] 其中 \( w_i \) 表示第 i 个词语,\( N \) 是总词数,\( p(w_i|w_1,...,w_{i-1}) \) 则表示基于前序上下文条件下当前词语出现的概率。这个表达式实际上是对所有位置上词语条件概率取平均后的指数化结果[^2]。 当训练好的语言模型应用于测试集时,如果它能较好地拟合实际的语言模式,则会给出较高的似然估计值;反之则不然。通过上述公式可以看出,随着分子部分求和项增大(即负对数值减小),最终得到的结果也会越接近于理想状态下的最小值——也就是1。因此,在实践中人们往往追求更水平的困惑作为优化目标之一。 ### 实现代码展示 下面是一段 Python 代码片段,展示了如何利用 PyTorch 库实现对预训练好或自定义构建完成之后的语言模型进行困惑评测的过程: ```python import torch.nn.functional as F from tqdm import tqdm def calculate_perplexity(model, dataloader, device='cpu'): model.eval() total_loss = 0. with torch.no_grad(): for batch in tqdm(dataloader): inputs, targets = map(lambda x: x.to(device), batch) outputs = model(inputs) loss = F.cross_entropy(outputs.view(-1, outputs.size(-1)), targets.view(-1)) total_loss += loss.item() avg_loss = total_loss / len(dataloader.dataset) perplexity = np.exp(avg_loss) return perplexity ``` 此函数接收三个参数:`model`(已加载权重并准备就绪待测验的目标网络实例)`dataloader`(封装有批量样本及其标签的数据迭代器对象)`device`(指定运算设备,默认CPU)。内部逻辑主要分为两大部分:一是遍历输入批次执行推理操作获得损失累积量;二是依据所得均方误差反推出对应的困惑得分返回调用端显示输出。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值