pytorch - Pytorch 构建 seq2seq MT 模型,但是如何从输出张量中得到翻译结果呢?
问题描述
我正在尝试实现自己的 MT 引擎,我正在按照https://github.com/bentrevett/pytorch-seq2seq/blob/master/1%20-%20Sequence%20to%20Sequence%20Learning%20with%20Neural中的步骤进行操作%20Networks.ipynb
SRC = Field(tokenize=tokenize_en,
init_token='<sos>',
eos_token='<eos>',
lower=True)
TRG = Field(tokenize=tokenize_de,
init_token='<sos>',
eos_token='<eos>',
lower=True)
训练模型后,该链接仅共享一种批量评估的方法,但我想尝试单个字符串并获得翻译结果。例如,我希望我的模型翻译输入“男孩”并获得德语翻译。
savedfilemodelpath='./pretrained_model/2020-09-27en-de.pth'
model.load_state_dict(torch.load(savedfilemodelpath))
model.eval()
inputstring = 'Boys'
processed=SRC.process([SRC.preprocess(inputstring)]).to(device)
output=model(processed,processed)
output_dim = output.shape[-1]
outputs = output[1:].view(-1, output_dim)
for item in outputs:
print('item shape is {} and item.argmax is {}, and words is {}'.format(item.shape,item.argmax(),TRG.vocab.itos[item.argmax()]))
所以我的问题是通过以下方式获得翻译结果是正确的:
首先:将字符串转换为张量
inputstring = 'Boys'
processed=SRC.process([SRC.preprocess(inputstring)]).to(device)
第二:将张量发送到模型。由于模型有一个 TRG 参数。我必须给出张量,我不能给出 TRG 张量吗?
output=model(processed,processed)
output_dim = output.shape[-1]
outputs = output[1:].view(-1, output_dim)
第三:通过return tensor,我用argmax得到翻译结果?这样对吗?
或者我怎样才能得到正确的翻译结果?
for item in outputs:
print('item shape is {} and item.argmax is {}, and words is {}'.format(item.shape,item.argmax(),TRG.vocab.itos[item.argmax()+1]))
解决方案
我从 translate_sentence得到了答案。真的感谢@Aladdin Persson
def translate_sentence(model, sentence, SRC, TRG, device, max_length=50):
# print(sentence)
# sys.exit()
# Create tokens using spacy and everything in lower case (which is what our vocab is)
if type(sentence) == str:
tokens = [token.text.lower() for token in spacy_en(sentence)]
else:
tokens = [token.lower() for token in sentence]
# print(tokens)
# sys.exit()
# Add <SOS> and <EOS> in beginning and end respectively
tokens.insert(0, SRC.init_token)
tokens.append(SRC.eos_token)
# Go through each english token and convert to an index
text_to_indices = [SRC.vocab.stoi[token] for token in tokens]
# Convert to Tensor
sentence_tensor = torch.LongTensor(text_to_indices).unsqueeze(1).to(device)
# Build encoder hidden, cell state
with torch.no_grad():
hidden, cell = model.encoder(sentence_tensor)
outputs = [TRG.vocab.stoi["<sos>"]]
for _ in range(max_length):
previous_word = torch.LongTensor([outputs[-1]]).to(device)
with torch.no_grad():
output, hidden, cell = model.decoder(previous_word, hidden, cell)
best_guess = output.argmax(1).item()
outputs.append(best_guess)
# Model predicts it's the end of the sentence
if output.argmax(1).item() == TRG.vocab.stoi["<eos>"]:
break
translated_sentence = [TRG.vocab.itos[idx] for idx in outputs]
# remove start token
return translated_sentence[1:]
并且翻译不会生成一次。Acutualy 它一次生成一次并使用多次。
推荐阅读
- pine-script - 如何在 alertcondition() 中检查真/假结果
- json - 如何在android的sqlite中快速批量插入json数据
- javascript - 使用 onChange 更新父组件的状态
- javascript - 如何使本地网络上的 WebRTC 视频流正常工作?
- vim - Vim foldexpr匹配pattern1 OR pattern2?
- graphics - 如何在世界空间中进行遮挡剔除
- r - 在 r (frm) 中使用分数响应模型中的因子
- rust - 我可以在 Rust 中将不可变借用标记为独占吗?
- javascript - 如何使用javascript获取两个输入(类型时间)值(上午/下午)
- docker - 使用 k8s 运行 java 应用程序并使用其独特的 pod 属性进行自动缩放