亲爱的chainer社区,
我无法在NStepLSTM
official example(英语到法语翻译)中使用seq2seq
的逻辑用法。
def __call__(self, xs, ys):
xs = [x[::-1] for x in xs] #Reverse x
据我所知,xs
是英语短语,ys
是法语短语。你为什么要颠倒英语短语?
您如何训练网络?您将xs
和ys
嵌入到连续空格中,然后使用exs
向编码器提供内容,以获取英语短语的潜在表示形式。但是你将潜在的表示放入解码器eys
。但eys
是法语短语的连续表示。在测试阶段,解码器无法知道由此产生的法语短语,可以吗?你如何应用你的网络?
hx, cx, _ = self.the encoder(None, None, exs)
_, _, os = self.decoder(hx, cx, eys)
ys_in = [F.concat([eos, y], axis=0) for y in ys]
为什么我们将end of sequence
放在开头?
ys = self.xp.full(batch, EOS, 'i')
在def translate
中,我们将end of sequence
数组放入解码器,为什么?
醇>
如果我不想翻译句子而是建立一个自动编码器来将短语映射到潜在空间,我该怎么办?
答案 0 :(得分:1)
感谢您的提问。
问题1
请参阅以下seq2seq原始论文。
他们建议:
Note that the LSTM reads the input sentence in reverse, because doing so introduces many short term dependencies in the data that make the optimization problem much easier.
(摘要)
we found that reversing the order of the words in all source sentences (but
not target sentences) improved the LSTM’s performance markedly
https://papers.nips.cc/paper/5346-sequence-to-sequence-learning-with-neural-networks.pdf
我认为官方示例代码也会像上面的论文那样反转输入句子。
问题2
然后你将潜在的表示放入解码器
eys
。但eys
是法语短语的连续表示
是的。这段代码用于训练时间,所以我们知道目标句子(金字)。
hx, cx, _ = self.the encoder(None, None, exs)
_, _, os = self.decoder(hx, cx, eys)
在测试时,您应该使用def translate(self, xs, max_length=100):
。
此方法可用于预测来自源句xs
的句子。
result = []
for i in range(max_length):
eys = self.embed_y(ys)
eys = F.split_axis(eys, batch, 0)
h, c, ys = self.decoder(h, c, eys)
cys = F.concat(ys, axis=0)
wy = self.W(cys)
ys = self.xp.argmax(wy.data, axis=1).astype('i')
result.append(ys)
对于每个循环,预测带有源句子向量和前一个单词ys
的单词。
问题3 问题4
我认为这一部分应如下:
ys_in = [F.concat([bos, y], axis=0) for y in ys]
(开头)
官方代码使用eos
和。
最终问题
如果我不想翻译句子而是建立一个自动编码器来将短语映射到潜在空间,我该怎么办?
如果要构建自动编码器,
xs = [x[::-1] for x in xs]
bos
eos
代替ys_in = [F.concat([eos, y], axis=0) for y in ys]
醇>
使用eos
而不是bos
都可以。
您只需为自动编码器删除此行xs = [x[::-1] for x in xs]
。
如果您想使用bos
,则应修改如下:
UNK = 0
EOS = 1
BOS = 2
47:eos = self.xp.array([EOS], 'i')
48: ys_in = [F.concat([eos, y], axis=0) for y in ys]
=>
bos = self.xp.array([BOS], 'i')
ys_in = [F.concat([bos, y], axis=0) for y in ys]
79: ys = self.xp.full(batch, EOS, 'i')
=>
ys = self.xp.full(batch, BOS, 'i')
def load_vocabulary(path):
with open(path) as f:
# +2 for UNK and EOS
word_ids = {line.strip(): i + 3 for i, line in enumerate(f)}
word_ids['<UNK>'] = 0
word_ids['<EOS>'] = 1
word_ids['<BOS>'] = 2
return word_ids
如果您还有其他问题,请再次问我。