来自 Facebook ICML 2017 论文 Efficient softmax approximation for GPUs 。主要用于训练辞汇表巨大的语言模型。这篇文章还涉及了 GPU 优化方面的知识,很值得一看。

Idea

文中采用的模型可以简单理解为 LSTM + softmax

想法很简单,文章的大多数词都是有辞汇表里的少数词构成的,即长尾理论或28原则。而语言模型在预测词的时候往往需要预测每个词的概率(通常是softmax),辞汇表可能非常大,低频词非常多。

那么在训练时完全可以把词语分成高频词和低频次两类,先预测词属于哪一类,然后再预测具体是哪个词,这样简单的分类就使得softmax的计算量大大减少。

原来是每个词都要计算一次, 现在是: V(高频) + P(低频) * V(低频), V(高频) 大大变小, 而 V(低频 虽然大 但 P(低频) 很小。

图片均来自论文 Efficient softmax approximation for GPUs

一个具体的例子,把辞汇分成多类,然后将除了第一个类之外的类表示成一个「词」图中的Vh大小就是 n + 3 (n为高频词数量),放进第一个类的词一起训练(注意第一个类并不单独表示为一个类,见上图每一个蓝色方块表示一个词,白色表示一个类),第一个类的词概率不变,假如预测到了V1类表示的「词」,再在V1中预测一次具体是哪个词,依次类推。

事实上,我们可以用另一种方式,把高频词也表示成一类,低频词一类或多个类,都作为叶子结点,表示成一棵树,但这样会带来性能下降(5%~10%),可能的原因是高频词的概率表示不够「直接」,被整个高频词类的概率所影响。

即原来是 P (w| h) (h 为隐含层向量,w为词)

变成 P(C| h) * P (w| C, h) 其中C 为类别

矩阵大小及计算优化

计算大量小矩阵是不划算的,很容易理解,数据传输、函数调用开销等计算本身就有额外 overhead,具体关系可表示如下:

K40,M40 是显卡型号,k 是矩阵维度

可以直观看出,分的类别不是越多越好,大致关系如下,训练时间先下降后略微提升

低频词优化

低频词上下文信息有限,并不需要太多的维度,因此可以用一个矩阵变换降低softmax的输入维度,即隐藏层的输出维度再进行计算。

Idea 来源

基于 hierarchical softmax 及变种等

优势

  1. 计算速度快,2x / 10x 对比普通的 softmax

2. 适合 GPU 计算

3. 对比原始的 softmax 几乎不降低准确度

代码

有点老,还是基于 lua 版本的 torch

facebookresearch/adaptive-softmax?

github.com
图标

推荐阅读:
相关文章