技术干货 | 基于MindSpore详解Perplexity语言模型评价指标

article/2025/9/24 13:27:32

01

原理介绍

在研究生实习时候就做过语言模型的任务,当时让求PPL值,当时只是调包,不求甚解,哈哈哈,当时也没想到现在会开发这个评价指标,那现在我来讲一下我对这个指标的了解,望各位大佬多多指教。

这个困惑度是如何发展来的呢?

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

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

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

简单说一下语言模型:语言模型(Language Model,LM),给出一句话的前k个词,希望它可以预测第k+1个词是什么,即给出一个第k+1个词可能出现的概率的分布p(xk+1|x1,x2,...,xk)。

困惑度的概念

困惑度的计算是基于单词的,在自然语言处理中,困惑度是用来衡量语言概率模型优劣的一个方法。一个语言概率模型可以看成是在整过句子或者文段上的概率分布。例如每个分词位置上有一个概率分布,这个概率分布表示了每个词在这个位置上出现的概率;或者每个句子位置上有一个概率分布,这个概率分布表示了所有可能句子在这个位置上出现的概率。

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

可以看到,之前我们学习的 trigram 模型经训练后,困惑度由955跌减至74,这是十分可观的结果。在Brown corpus (1 million words of American English of varying topics and genres) 上报告的最低的困惑度就是使用一个trigram model(三元语法模型)。在一个特定领域的语料中,常常可以得到更低的困惑度。

02

使用场景

我们在想衡量语言模型的好坏,然后对语言模型输出的句子进行评价。场景很简单,话不多说,上代码。

03

MindSpore的Perplexity代码实现

MindSpore,新一代AI开源计算框架。创新编程范式,AI科学家和工程师更易使用,便于开放式创新;该计算框架可满足终端、边缘计算、云全场景需求,能更好保护数据隐私;可开源,形成广阔应用生态。

2020年3月28日,华为在开发者大会2020上宣布,全场景AI计算框架MindSpore在码云正式开源。MindSpore着重提升易用性并降低AI开发者的开发门槛,MindSpore原生适应每个场景包括端、边缘和云,并能够在按需协同的基础上,通过实现AI算法即代码,使开发态变得更加友好,显著减少模型开发时间,降低模型开发门槛。

通过MindSpore自身的技术创新及MindSpore与华为昇腾AI处理器的协同优化,实现了运行态的高效,大大提高了计算性能;MindSpore也支持GPU、CPU等其它处理器。

原理就是上面说的那些,比较好理解,话不多说直接上代码。使用的是MindSpore框架实现的代码。

MindSpore代码实现

"""Perplexity"""
import math
import numpy as np
from mindspore._checkparam import Validator as validator
from .metric import Metricclass Perplexity(Metric):def __init__(self, ignore_label=None):super(Perplexity, self).__init__()if ignore_label is None:self.ignore_label = ignore_labelelse:self.ignore_label = validator.check_value_type("ignore_label", ignore_label, [int])self.clear()def clear(self):"""清除历史数据"""self._sum_metric = 0.0self._num_inst = 0def update(self, *inputs):# 输入数量的校验if len(inputs) != 2:raise ValueError('Perplexity needs 2 inputs (preds, labels), but got {}.'.format(len(inputs)))# 将输入统一转化为numpy,变为listpreds = [self._convert_data(inputs[0])]labels = [self._convert_data(inputs[1])]if len(preds) != len(labels):raise RuntimeError('preds and labels should have the same length, but the length of preds is{}, ''the length of labels is {}.'.format(len(preds), len(labels)))loss = 0.num = 0# 遍历句子中的每一个单词,再进行维度的变换for label, pred in zip(labels, preds):if label.size != pred.size / pred.shape[-1]:raise RuntimeError("shape mismatch: label shape should be equal to pred shape, but got label shape ""is {}, pred shape is {}.".format(label.shape, pred.shape))# 将label进行重塑label = label.reshape((label.size,))# 将label_expand转为int类型label_expand = label.astype(int)# label_expand扩展一维label_expand = np.expand_dims(label_expand, axis=1)first_indices = np.arange(label_expand.shape[0])[:, None]pred = np.squeeze(pred[first_indices, label_expand])if self.ignore_label is not None:ignore = (label == self.ignore_label).astype(pred.dtype)num -= np.sum(ignore)pred = pred * (1 - ignore) + ignoreloss -= np.sum(np.log(np.maximum(1e-10, pred)))num += pred.sizeself._sum_metric += lossself._num_inst += numdef eval(self):# 分母不能为0if self._num_inst == 0:raise RuntimeError('Perplexity can not be calculated, because the number of samples is 0.')return math.exp(self._sum_metric / self._num_inst)

使用方法如下:

import numpy as np
from mindspore import Tensor
from mindspore.nn.metrics import Perplexityx = Tensor(np.array([[0.2, 0.5], [0.3, 0.1], [0.9, 0.6]]))
y = Tensor(np.array([1, 0, 1]))
metric = Perplexity(ignore_label=None)
metric.clear()
metric.update(x, y)
perplexity = metric.eval()
print(perplexity)2.231443166940565

每个batch(比如两组数据)进行计算的时候如下:

import numpy as np
from mindspore import Tensor
from mindspore.nn.metrics import Perplexitymetric = Perplexity(ignore_label=None)
metric.clear()
x = Tensor(np.array([[0.2, 0.5], [0.3, 0.1], [0.9, 0.6]]))
y = Tensor(np.array([1, 0, 1]))
metric.update(x, y)x1= Tensor(np.array([[0.2, 0.5], [0.3, 0.1], [0.9, 0.6]]))
y1 = Tensor(np.array([1, 0, 1]))
metric.update(x1, y1)
perplexity = metric.eval()
print(perplexity)

Perplexity的影响因素

1. 训练数据集越大,PPL会下降得更低,1billion dataset和10万dataset训练效果是很不一样的;

2. 数据中的标点会对模型的PPL产生很大影响,一个句号能让PPL波动几十,标点的预测总是不稳定;

3. 预测语句中的“的,了”等词也对PPL有很大影响,可能“我借你的书”比“我借你书”的指标值小几十,但从语义上分析有没有这些停用词并不能完全代表句子生成的好坏。

所以,语言模型评估时我们可以用perplexity大致估计训练效果,作出判断和分析,但它不是完全意义上的标准,具体问题还是要具体分析。


http://chatgpt.dhexx.cn/article/c7jjfecQ.shtml

相关文章

Perplexity定义

Refer from http://blog.csdn.net/pipisorry/article/details/42460023 http://blog.csdn.net/pipisorry/article/details/42460023 熵/信息熵 Perplexity定义 perplexity是一种信息理论的测量方法,b的perplexity值定义为基于b的熵的能量(b可以是一个概…

gensim---LDA---perplexity

以下内容来源于https://blog.csdn.net/qq_25073545/article/details/79773807 使用gensim实现lda,并计算perplexity( gensim Perplexity Estimates in LDA Model) Neither. The values coming out of bound() depend on the number of topi…

世界上第一个会话搜索引擎——Perplexity AI使用测评

引言 比起传统的列表式搜索,Perplexity AI把艳惊四座的ChatGPT和必应搜索结合起来,既有ChatGPT式的问答,又像普通搜索引擎那样列出链接,就连马斯克也亲自称赞:它不仅总结出了推文的由来,还将推文的内容解释…

主题模型TopicModel:LDA主题模型的评估

http://blog.csdn.net/pipisorry/article/details/42460023 基础知识:熵 [熵与互信息] 皮皮blog Perplexity定义 perplexity是一种信息理论的测量方法,b的perplexity值定义为基于b的熵的能量(b可以是一个概率分布,或者概率模型…

语言模型常用评价方法:perplexity、bleu

目录 1. perplexity(困惑度、复杂度) 2. BLEU 代码实现 1. perplexity(困惑度、复杂度) 更多详细,参考:详解语言模型NGram及困惑度Perplexity 语言模型:语言模型可以表示为一个计算 的模型&a…

LDA主题模型绘制困惑度(perplexity)-主题数曲线——python

主题建模作为一种基于机器学习的文本内容分析技术,一般用于推断文本文档中隐藏主题的技术。很多研究使用了基于Latent Dirichlet Allocation (LDA)的主题建模算法来处理大规模文档并识别潜在主题。LDA主题模型已经在多个研究领域得到应用,且都有着不俗表…

Android keystore

1.keystore是一个密钥库,密钥库中可以放很多对密钥对(私钥证书(证书中包含公钥,数字签名,证书有效期,组织机构名称,申请时间,算法等。))kestore中有两种密码,一个密码是访问密钥库的…

查看KeyStore的信息,(本地的和线上的)

本地的: 1.找到jdk路径、如图 输入cmd 2.输入:keytool -list -v -keystore C:\Users\j\Desktop\app-android-v1.6-1caec749d84e708f91fd90ab383e42d7b417a47e\你的名.keystore 注意:C:\Users\j\Desktop\app-android-v1.6-1caec749d84e708f9…

Keystore与Truststore的区别

Keystore vs Truststore 概念 Keystore 用于存储特定程序应提供给双方(服务器或客户端)以进行验证的私钥和身份证书。 Truststore 用于存储来自认证机构 (CA) 的证书,这些证书验证服务器在 SSL 连接中提供的证书。 区别 KeystoreTruststo…

Keystore、Key attestation

最近看见了Keystore这个名词不知道什么意思,百度找到了前辈的优秀文章,这里copy学习一下,原文链接放在文末,感谢前辈。 Keystore的技术演进之路 Android提供的keystore功能发展历程伴随着Android版本不断演进。 从 Android 6.0 …

Android KeyStore流程

文章目录 一、Keystore二、Keystore架构及接口函数1. Keystore组件架构2. IKeymasterDevice.hal中的几个重要接口函数2.1 begin函数2.2 update函数2.3 finish函数2.4 abort函数 3. Keymaster TA4. 对称密码函数API 三、从Keystore到Keymaster的完整分析1. cts问题2. 代码流程分…

AndroidStudio生成keystore

相信大家都慢吞吞的切换将开发工具迁移到了AS,今天,奉上生成keystore的方法。 看图: 点击我选中的Generate Signed APK,翻译过来大致是,生成已签署的APK,我们点击这一项 如果还没有生成keystore&#xff…

keytool生成keystore、truststore、证书

keytool生成keystore、truststore、证书 1. 打开cmd命令行,进入文件夹(如:D:\test_icessl_key)。keytool会把接下来生成的所有文件都保存到此处。 2. 输入:keytool -genkeypair -alias icesslkey -keyalg RSA -validi…

Android Studio 默认keystore 以及自定义keystore

我们使用Android Studio 运行或测试我们的app 它使用一个默认的debug.keystore进行签名。 这个默认签名(keystore)是不需要密码的,它的默认位置在 $HOME/.android/debug.keystore,如果不存在Android studio会自动创建它。 例如我的debug.keystore就在…

SSL证书中的keystore是什么

什么是keystore 是java的密钥库、用来进行通信加密用的、比如数字签名。keystore就是用来保存密钥对的,比如公钥和私钥。 在keystore里,包含两种数据: 密钥实体(Key entity)——密钥(secret key&#xff0…

Keystore密钥库

近来由于项目需要做Single Sign On, 研究了一下CAS(具体配置等下篇再介绍), 而这个CAS的配置最关键的不是CAS本身,而是数字证书,如何配置多台服务器之间的信任链接。因此,有必要把keystore, keytool的东西翻出来晒晒。…

KeyStore秘钥库

keytool 在打包Android APK的时候进行签名需要选择一个keystore,查看秘钥库: C:\Users\47355\.android>keytool -list -v -keystore debug.keystore 输入密钥库口令: 密钥库类型: PKCS12 密钥库提供方: SUN 您的密钥库包含 1 个条目 别名: androidd…

keystore 介绍

随时随地阅读更多技术实战干货,获取项目源码、学习资料,请关注源代码社区公众号(ydmsq666) Keytool 是一个有效的安全钥匙和证书的管理工具. Java 中的 keytool.exe (位于 JDK\Bin 目录下)可以用来创建数字证书,所有的…

安卓生成keystore和查看keystore

————————————————重要通知—————————————— Hello,本人的博客文章已更新至个人网站(www.jonexu.cn) 文章中有问题可以到网站联系博主,后续新的文章也将更新在个人网站 —————————————…

Python Tkinter库的简单使用

今天写了两个小小的图像界面小游戏,对Tkinter库进行了简单的熟悉。 1.随机造句小游戏: import Tkinter as tk import random window tk.Tk()def randomNoun():nouns ["cats", "hippos", "cakes"]noun random.choice…