考虑以下机器翻译问题。设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 inS
都具有相同的长度。也就是说,句子具有可变数量的单词。
我正在 Theano 中实现一个机器翻译系统,第一个设计决策是使用什么样的数据结构S
和T
. 从在 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
,但我没有兴趣进一步研究如何使其工作。混乱正在呈指数级增长,我想知道我是否以错误的方式使用类型列表,或者是时候放弃它们了,因为它们还没有得到足够好的支持。