首页 > 解决方案 > 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]))

标签: pytorchtorchtext

解决方案


我从 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 它一次生成一次并使用多次。


推荐阅读