【问题标题】:Variable-length tensors in TheanoTheano 中的可变长度张量
【发布时间】:2015-05-28 21:02:29
【问题描述】:

这个问题是指 Theano 中的最佳实践。这是我想要做的:

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

我想到的解决方案包括:

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

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

【问题讨论】:

    标签: theano


    【解决方案1】:

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

    一般来说,如果您想对所有句子执行一致的操作,那么将该操作应用于单个 3D 张量通常会比依次应用于一系列矩阵的速度快得多。对于在 GPU 上运行的操作尤其如此。

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

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

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

    【讨论】:

    • 感谢您的回答,这符合我即将发布的问题,因为我遇到了同样的 OP 问题。 :-) 我是 Theano 的菜鸟,我不知道如何扫描 3D 张量,因为我发现不支持扫描合成。拜托,你能链接任何例子或发布一些简单的代码吗?提前致谢。
    • 我不知道您所说的“不支持扫描合成”是什么意思。 LSTM 示例展示了如何将扫描与填充序列一起使用(请参阅链接自 deeplearning.net/tutorial/lstm.html 的代码)。
    • 您好丹尼尔,感谢您的回复。我的意思是:我有一个 3D 张量 N*L*d,我可以在第一个轴 (N) 上扫描它,但我不能在每个 L*d 矩阵上调用另一个扫描函数。我会看看这个例子,非常感谢。
    • 当然可以。将扫描放在外部扫描步骤函数中。
    • 我想我知道我错在哪里了:我在另一个 theano 函数中使用了一个 theano 函数......我会试着让你知道。再次感谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-26
    • 2019-02-13
    • 1970-01-01
    相关资源
    最近更新 更多