本文主要介绍困惑度(Perplexity,简称为 PPL)在语言模型评估中的作用
困惑度的整体说明
困惑度(Perplexity,PPL)本质是交叉熵损失 \(H(p|q)\) 的一个等价指标
$$\text{Perplexity} = e^{H(p|q)}$$- 其中 \(H(p|q)\) 衡量真实标签和模型输出概率之间的差异
语言模型中损失函数即交叉熵损失,此时有 \(loss = H(p|q)\),即:
$$\text{Perplexity} = e^{\text{loss}}$$- 特别是预训练和 SFT 阶段,一般符合这个情况,RL 阶段则根据不同的损失归一化方式有所不同
- 注:一般语言模型中是先计算单个样本的困惑度(对应指数上是单个样本的 Loss),然后再平均后上报
- 参考链接:How to calculate perplexity for a language model using Pytorch, StackOverflow
1
perplexity = torch.exp(loss)
给测试集的句子赋予较高概率值的语言模型较好,在测试集上困惑度越小,模型越好
当一个语言模型训练完成后,测试集中的句子(一般是正常的自然语言句子)出现概率越高越好,概率越大,困惑度越小
单文档困惑度的定义
- 给定模型 \(\mathcal{M}\),测试文档 \(d = (w_{1}, w_{2},\cdots,w_{N})\),则模型 \(\mathcal{M}\) 下评估测试文档 \(d\) 的困惑度 \(\text{Perplexity}_\mathcal{M}(d)\) 原始定义为:
$$
\begin{align}
\text{Perplexity}_\mathcal{M}(d) &= P_\mathcal{M}(d)^{-\frac{1}{N}} \\
&= P_\mathcal{M}(w_{1}, w_{2},\cdots,w_{N})^{-\frac{1}{N}}
\end{align}
$$ - 常常会使用以下形式:
$$ \text{Perplexity}_\mathcal{M}(d) = \exp\left (-\frac{1}{N}\log P_\mathcal{M}(w_{1}, w_{2},\cdots,w_{N})\right ) $$ - 进一步有:
$$
\begin{align}
\text{Perplexity}_\mathcal{M}(d) &= \exp\left (-\frac{1}{N}\log P_\mathcal{M}(w_{1}, w_{2},\cdots,w_{N})\right ) \\
&= \exp\left (-\frac{1}{N}\log\prod_{n=1}^{N}P_\mathcal{M}(w_{n}|w_1,\cdots,w_{n-1})\right ) \\
&= \exp\left (-\frac{1}{N}\sum_{n=1}^{N}\log P_\mathcal{M}(w_{n}|w_1,\cdots,w_{n-1})\right ) \\
\end{align}
$$- 计算时,常常使用上面加法的形式
- 以上多种形式等价,两边取对数在变成自然数的指数即可证明:
- 取对数:
$$
\begin{align}
Log(\text{Perplexity}_\mathcal{M}(d) ) &= -\frac{1}{N}\log P_\mathcal{M}(w_{1}, w_{2},\cdots,w_{N}) \\
\end{align}
$$ - 变指数:
$$
\begin{align}
\text{Perplexity}_\mathcal{M}(d) &= e^{-\frac{1}{N}\log P_\mathcal{M}(w_{1}, w_{2},\cdots,w_{N})} \\
&= \exp\left (-\frac{1}{N}\log P_\mathcal{M}(w_{1}, w_{2},\cdots,w_{N})\right ) \\
\end{align}
$$ - 特别说明,一些地方会将对数和指数的底同时换成 2,实际上从推导上看,可以换成任意底数
- 取对数:
多文档困惑度的定义
- 基本思路:将多文档拼接起来,视作单个文档,然后计算困惑度即可(但需要考虑文档间词概率相互独立)
- 以上是一个文档的表述,对于多个文档 \(D = (d_{1}, d_{2},\cdots,d_{M})\) ,其中 \(d_m = (w_{1}^{m}, w_{2}^{m},\cdots,w_{N_{m}})\),则多文档的困惑度定义为:
$$
\begin{align}
\text{Perplexity}_\mathcal{M}(D) &= P_\mathcal{M}(D)^{-\frac{1}{\sum_{m=1}^{M}N_{m}}} \\
&= \left(\prod_{m=1}^{M} P_\mathcal{M}(d_{m})\right)^{-\frac{1}{\sum_{m=1}^{M}N_{m}}}
\end{align}
$$- 文档之间互相独立,所以能推出上面的结论
- 也常常写作如下形式
$$
\begin{align}
\text{Perplexity}_\mathcal{M}(D) &= \exp\left(-\frac{1}{\sum_{m=1}^{M}N_{m}}\sum_{m=1}^{M}\log P_\mathcal{M}(w_{1}^{m}, w_{2}^{m},\cdots,w_{N_{m}}^{m})\right) \\
\end{align}
$$ - 进一步可得
$$
\begin{align}
\text{Perplexity}_\mathcal{M}(D) &= \exp \left ( -\frac{1}{\sum_{m=1}^{M}N_{m}}\sum_{m=1}^{M}\log P_\mathcal{M}(w_{1}^{m}, w_{2}^{m},\cdots,w_{N_{m}}^{m}) \right ) \\
&= \exp \left ( -\frac{1}{\sum_{m=1}^{M}N_{m}}\sum_{m=1}^{M}\log\prod_{n=1}^{N_{m}}P_\mathcal{M}(w_{n}^{m}|w_{1}^{m},\cdots,w_{n-1}^{m}) \right ) \\
&= \exp \left ( -\frac{1}{\sum_{m=1}^{M}N_{m}}\sum_{m=1}^{M}\sum_{n=1}^{N_{m}}\log P_\mathcal{M}(w_{n}^{m}|w_{1}^{m},\cdots,w_{n-1}^{m}) \right ) \\
\end{align}
$$ - 注意:多个文档的困惑度不是简单的等于所有文档困惑度的积或和 ,而是等于把所有文档合并成一个大文档,大文档的困惑度则是最终所有文档的困惑度
- 特别说明:一些地方也会使用平均法,使用每个文档的平均困惑度代表示多文档的困惑度
LDA 的困惑度
- LDA中 \(w_{1},w_{2},\cdots,w_{n}\) 在参数已知的情况下是互相独立的,则有
$$
\begin{align}
\text{Perplexity}_\mathcal{M}(d) &= e^{-\frac{1}{\sum_{m=1}^{M}N_{m}}\sum_{m=1}^{M}\log P_\mathcal{M}(w_{1}^{m}, w_{2}^{m},\cdots,w_{N_{m}}^{m})} \\
&= \exp \left ( -\frac{1}{\sum_{m=1}^{M}N_{m}}\sum_{m=1}^{M}\log P_\mathcal{M}(w_{1}^{m}, w_{2}^{m},\cdots,w_{N_{m}}^{m}) \right ) \\
&= \exp \left ( -\frac{1}{\sum_{m=1}^{M}N_{m}}\sum_{m=1}^{M}\log\prod_{n=1}^{N_{m}}P_\mathcal{M}(w_{n}) \right ) \\
&= \exp \left ( -\frac{1}{\sum_{m=1}^{M}N_{m}}\sum_{m=1}^{M}\log\prod_{n=1}^{N_{m}}\sum_{k=1}^{K}P_\mathcal{M}(w_{n}=t|z_{n}=k;\mathcal{M})P_\mathcal{M}(z_{n}=k|d=d_{m};\mathcal{M})\right ) \\
&= \exp \left ( -\frac{1}{\sum_{m=1}^{M}N_{m}}\sum_{m=1}^{M}\log\prod_{n=1}^{N_{m}}\sum_{k=1}^{K}\theta_{m,k}\phi_{k,t}\right ) \\
&= \exp \left ( -\frac{1}{\sum_{m=1}^{M}N_{m}}\sum_{m=1}^{M}\log\prod_{n=1}^{N_{m}}\theta_{m,:}\phi_{:,t}\right ) \\
&= \exp \left ( -\frac{1}{\sum_{m=1}^{M}N_{m}}\sum_{m=1}^{M}\sum_{n=1}^{N_{m}}\log\theta_{m,:}\phi_{:,t}\right ) \\
\end{align}
$$ - 其中 \(\phi_{k,t}\) 表示单词t在主题k中出现的概率,\(\theta_{m,k}\) 表示主题k在文档m中出现的概率
- \(\sum_{k=1}^{K}\theta_{m,k}\phi_{k,t} = (\theta_{m,:}\phi_{:,t})\) 就是单词t出现在文档m中的概率(对隐变量主题k积分)
- 上面式子中 \((\theta_{m,:}\phi_{:,t})\) 就是两个向量的内积,在这里: \(\theta_{m,:}\) 代表行向量,表示当前文档 \(d_{m}\) 的主题分布, \(\phi_{:,t}\) 代表列向量,表示当前每个主题生成词 \(w_{t}\) 的概率
- 计算公式的代码可参考L-LDA模型的实现GitHub仓库: Labeled-LDA-Python 中的
perplexity函数和log_perplexity函数