我在阅读的一篇论文,http://www.cs.toronto.edu/~ilya/pubs/2011/LANG-RNN.pdf,使用每字符比特数作为测试指标来评估文本生成计算机模型的质量,但没有提到它是如何计算的。我在网上搜索了一番,实在找不到相关的资料。
有谁知道如何计算它吗?最好是用Python,但伪代码或其他任何形式都可以。谢谢!
回答:
每字符比特数是衡量压缩方法性能的一个指标。它的应用方法是压缩一个字符串,然后测量压缩表示总共占用的比特数,除以原始字符串中符号(即字符)的数量。压缩版本占用的每字符比特数越少,压缩方法的效果就越好。
换句话说,作者们使用他们的生成语言模型来进行压缩,并假设压缩方法的高有效性表明底层生成模型的高准确性。
在第1节中,他们指出:
本文的目标是通过将使用新型Hessian-Free优化器训练的大型RNN应用于预测文本流中下一个字符的任务,来展示其强大能力。这是一个重要的问题,因为更好的字符级语言模型可以改善文本文件的压缩(Rissanen & Langdon, 1979)[…]
Rissanen & Langdon (1979)的文章是算术编码的原始描述,这是一种众所周知的文本压缩方法。
算术编码基于生成语言模型运行,就像作者们构建的那样。给定一个(可能是空的)字符序列,模型会预测接下来可能出现的字符。人类也可以做到这一点,例如给定输入序列hello w
,我们可以猜测下一个字符的概率:o
的概率很高(因为hello world
是一个合理的延续),但像h
(如hello where can I find..
)或i
(如hello winston
)这样的字符也有非零概率。所以我们可以为这个特定输入建立一个字符的概率分布,这正是作者们的生成模型所做的。
这自然与算术编码相符:给定已经编码的输入序列,接下来字符的比特序列由可能字符的概率分布决定:概率高的字符得到较短的比特序列,概率低的字符得到较长的序列。然后从输入中读取下一个字符,并使用从概率分布中确定的比特序列进行编码。如果语言模型好,字符将以高概率被预测,因此比特序列将很短。然后压缩继续进行下一个字符,再次使用到目前为止的输入来建立字符的概率分布,确定比特序列,然后读取实际的下一个字符并相应地编码它。
请注意,生成模型在每一步都被用来建立新的概率分布。所以这是一个自适应算术编码的实例。
在所有输入都被读取和编码后,测量结果的总长度(以比特为单位),并除以原始未压缩输入中的字符数量。如果模型好,它将以高准确性预测字符,因此用于每个字符的比特序列平均将很短,因此每字符的总比特数将较低。
关于现成的实现
我不知道有哪种算术编码的实现可以轻松集成你自己的生成语言模型。大多数实现都是在读取输入时动态构建自己的自适应模型,即调整字符频率表。
你可以考虑从arcode开始。我查看了代码,似乎有可能集成你自己的模型,尽管这并不容易。self._ranges
成员代表语言模型;基本上是一个累积字符频率的数组,所以self._ranges[ord('d')]
是所有小于d
的字符的总相对频率(即假设只有小写字母字符的情况下,a
、b
、c
)。你需要在每个输入字符后修改这个数组,并将你从生成模型中获得的字符概率映射到字符频率范围。