2

这个问题是指 Theano 中的最佳实践。这是我正在尝试做的事情:

我正在为 SMT 系统构建神经网络。在这种情况下,我在概念上将句子表示为可变长度的单词列表,并将单词表示为固定长度的整数列表。理想情况下,我想将我的语料库表示为 3D 张量(第一维 = 语料库中的句子,第二维 = 句子中的单词,第三维 = 单词中的整数特征)。困难在于句子的长度是可变的,据我所知,Theano 中的张量有严格的要求,即一维中的所有长度必须相同。

我想到的解决方案包括:

  1. 对虚拟词使用填充,使句子大小相等。但这意味着每当我遍历一个句子时,我都需要包含特殊代码来丢弃填充。
  2. 将语料库表示为矩阵向量。但是,这使得使用某些功能变得困难。例如,如果我想将一个句子中所有单词的表示相加,我不能简单地使用 *corpus.sum(axis=1)*。我必须遍历句子,执行 *sentence.sum(axis=0)*,然后将结果收集到另一个张量中。

我的问题是:这些替代方案中的哪一个是首选,还是有更好的替代方案?

4

1 回答 1

3

在大多数情况下,第一个选项可能是最佳选项。这就是我所做的,尽管它确实意味着传递一个单独的句子长度向量并屏蔽某些结果以在需要时消除填充区域。

通常,如果您想对所有句子执行一致的操作,那么将该操作应用于单个 3D 张量通常会比顺序应用于一系列矩阵更快。对于在 GPU 上运行的操作尤其如此。

如果您使用扫描操作,速度差异将变得更加放大。您最好扫描 3D 张量并在涵盖所有(或小批量)句子的步进函数中对每个单词矩阵进行操作。如果需要,您可能需要知道该矩阵的哪些行是真实数据,哪些是填充。顺便说一句,我发现将 3D 张量的第一个维度设置为时间/序列位置维度有助于使用扫描,它始终扫描第一个维度。

通常,使用零值作为填充值将导致填充对您的操作没有影响。

另一种选择是循环句子,这意味着混合 Theano 和 Python 代码,这会使一些计算变得困难或不可能。例如,如果数据存储在许多单独的矩阵中,则可能无法在所有(或批量)句子中获取成本函数相对于某些参数的梯度。

于 2015-05-28T13:02:29.613 回答