考虑以下机器翻译问题 . 设 s
为源句, t
为目标句 . 这两个句子在概念上表示为索引列表,其中索引对应于相关词典中单词的位置 . 例:
s = [34, 68, 91, 20]
t = [29, 0, 43]
请注意, s
和 t
不一定具有相同的长度 . 现在让 S
和 T
成为这样的实例的集合 . 换句话说,它们是平行的语料库 . 例:
S = [[34, 68, 91, 20], [4, 7, 1]]
T = [[29, 0, 43], [190, 37, 25, 60]]
请注意,并非 S
中的所有 s
都具有相同的长度 . 也就是说,句子具有可变数量的单词 .
我正在Theano中实现一个机器翻译系统,第一个设计决策是 S
和 T
使用什么样的数据结构 . 从Matrices with different row lengths in numpy上发布的一个答案中,我了解到类型列表是存储可变长度张量的一个很好的解决方案 .
但是,我意识到它们使我的代码复杂化了很多 . 我举个例子 . 假设我们有两个类型列表 y
和 p_y_given_x
,旨在计算负损失可能性 . 如果它们是常规的张量,那么这样的简单陈述就足够了:
loss = t.mean(t.nnet.categorical_crossentropy(p_y_given_x, y))
但 categorical_crossentropy
只能应用于张量,所以在类型列表的情况下,我必须迭代它们并将函数分别应用于每个元素:
_loss, _ = theano.scan(fn=lambda i, p, y: t.nnet.categorical_crossentropy(p[i], y[i]),
non_sequences=[p_y_given_x, y],
sequences=[t.arange(y.__len__(), dtype='int64')])
loss = t.mean(_loss)
除了使我的代码变得越来越混乱之外,这些问题还会传播 . 例如,如果我想计算损失的梯度,则以下内容不再起作用:
grad_params = t.grad(loss, params)
我没有工作 . 我确定它与 loss
的类型有关,但我不想再调查如何让它工作 . 这个烂摊子正在成倍增长,我想知道我是否以错误的方式使用打字列表,或者是否有时间放弃它们,因为它们尚未得到足够的支持 .
1 回答
任何人都没有使用类型列表 . 但是拥有它们的想法是你通过扫描每个句子来迭代它们 . 然后,您可以在1次扫描中完成所需的一切 . 每次操作不进行1次扫描 .
因此,扫描仅用于对小批量中的每个示例进行迭代,并且扫描内部是在一个示例上完成的所有内容 .
我们还没有用grad测试类型列表 . 它可能缺少某些实现 .