你也可以通过定义一个行为像 cell 那样的函数来创建你自己模型,以及一个类似于这个 cell 状态的初始化函数。在 rnnlib.cell 中有预定义的 cell,如 LSTM、RNN、和 GRN。下面来看看如何一步步建立一个 RNN:
在 GPU 上训练它 既然 torch-rnnlib 连着 nn 模块接口,仅需要在模型上调取:cuda()就能将它拉进 GPU。rnnlib 的目的是允许用户自由创建新 cell,或者使用快速基线。这样就 OK 了,如果你在上一节中使用第一或第二个 API 来构建循环网络,就可以轻松使用 cudnn 来大大加速你的网络。对于 nn.{RNN, LSTM, GRU} 接口,仅需要用 usecudnn=true 就能调取这个建构器(constructor):
对于第二个 API,仅需要将 rnnlib.Recurrent 替换成 rnnlib.makeCudnnRecurrent 并将 cell 函数改为 cudnnAPI 中已有的一个 cell 串。例如:
最终的结果通常是,模型的循环部分至少能提速两倍。要注意的是,不是整个模型提速两倍,尤其是如果大部分计算不是在循环部分中时。例如,如果你的模型中有一个 softmax,atv,比循环部分需要更多的计算,那最终速度可能只提升 1.3 倍。
Adaptive-Softmax:为 GPU 定制的 softmax 近似模型 当处理大输出空间(如语言模型)时,分类器(classifier)可能是模型的计算瓶颈。过去已经提出了许多解决方案(分层 softmax(hierarchical softmax),噪声对比估计(noise contrastive estimation),差分 softmax(differentiated softmax)),但是它们通常被设计用于标准的 CPU,并且很少充分利用 GPU 的特性。 我们研究出了一种新的近似方法,叫做自适应 softmax(adaptive softmax):一个使其计算载荷量(computational budget)适应数据分布的 softmax。它通过更快地访问最常用的类(class),为它们提供更多的资源,来达到优良的近似效果和快速运行时间之间的平衡。更准确地说,它学习了一个 k-通道(k-way)的层次 softmax(hierarchical softmax),它考虑了 GPU 的架构以有效地分配计算。这种计算资源的分配可以使用一个简单的动态规划算法来精确求解。几个技巧可以进一步处理分类器的计算负载问题:我们使用分枝少的树(shallow tree)来避免顺序计算(sequential computation),并且我们为每个 GPU 集群(cluster)确定类(class)的最小值,以避免浪费 GPU 的并行计算能力。 正如表格 1 中显示的,自适应 softmax 几乎可以与完整 softmax(full softmax)的结果相媲美,并且自适应 softmax 速度更快。它也优于 GPU 运行的其他近似模型。 表格 1. 使用 Text8 的模型结果比较。ppl 值越小越好。
图. 语言模型在不同 softmax 近似模型上的收敛效果。它建立在 LSTM 模型之上。 10 亿单词数据集在单个 GPU 上几天内达到了值为 45 的困惑度值 除自适应 softmax(adatpive softmax)外,在技术细节方面,我们使用相对标准的设置:对于小模型,我们使用层数为 1、2048 个神经元单位的的 LSTM;对于大模型,我们使用层数为 2、2048 个神经元单位的 LSTM。我们使用 L2 正则化(regularization)的权重和 Adagrad 来训练模型。我们使用大小为 128 的批处理(batch),同时设置反向传播(back-propagation)窗口的大小为 20。 关于自适应 softmax,我们使用 10 亿单词的训练数据集分布的最佳设置,即 4 个 GPU 集群(cluster),j2直播,每用一个集群,数据的维数减少 4 倍(更多细节详见论文)。
表格 2. 使用 10 亿数据集的模型 perplexity 值比较(值越小越好)。注意到 Jozefowicz 等人用了 32 个 GPU 训练,我们只用了 1 个 GPU。 (责任编辑:本港台直播) |