Load and use trained pt of machine translation model

albertjohnson: <p>I have created and trained a translation model. After the model have been trained and the app was not stopped, the result is acceptable. However, when I use load to use the .pt, the translating result is unexpected. The following is how I use the model:<br>
import torch<br>
import torch.nn as nn<br>
import torch.optim as optim<br>
import torch.nn.functional as F<br>
from torch.utils.data import Dataset, DataLoader</p>
<p>import time<br>
import math<br>
import random<br>
device = torch.device(‘cuda’ if torch.cuda.is_available() else ‘cpu’)</p>
<h1>
<a name="heading-1" class="anchor" href="#heading-1"></a>每一行数据如下</h1>
<h1>
<a name="hittcc-by-20-france-attribution-tatoebaorg-538123-cm-891077-martha-2" class="anchor" href="#hittcc-by-20-france-attribution-tatoebaorg-538123-cm-891077-martha-2"></a>‘Hi.\t嗨。\tCC-BY 2.0 (France) Attribution: <a href="http://tatoeba.org" rel="noopener nofollow ugc">tatoeba.org</a> <span class="hashtag">#538123</span> (CM) &amp; <span class="hashtag">#891077</span> (Martha)’</h1>
<p>with open(’./cmn.txt’, ‘r’, encoding=‘utf-8’) as f:<br>
data = f.read()<br>
data = data.strip()<br>
data = data.split(’\n’)<br>
print(‘样本数:\n’, len(data))<br>
print(’\n样本示例:’)</p>
<h1>
<a name="heading-3" class="anchor" href="#heading-3"></a>分割英文数据和中文数据</h1>
<p>en_data = [line.split(’\t’)[0] for line in data]<br>
ch_data = [line.split(’\t’)[1] for line in data]<br>
print(‘英文数据:\n’, en_data[:10])<br>
print(’\n中文数据:\n’, ch_data[:10])</p>
<h1>
<a name="eos-4" class="anchor" href="#eos-4"></a>按字符级切割，并添加</h1>
<p>en_token_list = [[char for char in line]+[""] for line in en_data]<br>
ch_token_list = [[char for char in line]+[""] for line in ch_data]<br>
print(‘英文数据:\n’, en_token_list[:2])<br>
print(’\n中文数据:\n’, ch_token_list[:2])</p>
<h1>
<a name="heading-5" class="anchor" href="#heading-5"></a>基本字典</h1>
<p>basic_dict = {’’: 0, ‘’: 1, ‘’: 2, ‘’: 3}</p>
<h1>
<a name="heading-6" class="anchor" href="#heading-6"></a>分别生成中英文字典</h1>
<p>en_vocab = set(’’.join(en_data))<br>
en2id = {char: i+len(basic_dict) for i, char in enumerate(en_vocab)}<br>
en2id.update(basic_dict)<br>
id2en = {v: k for k, v in en2id.items()}</p>
<h1>
<a name="heading-7" class="anchor" href="#heading-7"></a>分别生成中英文字典</h1>
<p>ch_vocab = set(’’.join(ch_data))<br>
ch2id = {char: i+len(basic_dict) for i, char in enumerate(ch_vocab)}<br>
ch2id.update(basic_dict)<br>
id2ch = {v: k for k, v in ch2id.items()}</p>
<h1>
<a name="heading-8" class="anchor" href="#heading-8"></a>利用字典，映射数据</h1>
<p>en_num_data = [[en2id[en] for en in line] for line in en_token_list]<br>
ch_num_data = [[ch2id[ch] for ch in line] for line in ch_token_list]</p>
<p>print(‘char:’, en_data[1])<br>
print(‘index:’, en_num_data[1])<br>
print(‘char:’, ch_data[1])<br>
print(‘index:’, ch_num_data[1])</p>
<p>def translate(<br>
model,<br>
sample,<br>
idx2token=None<br>
):<br>
model.predict = True<br>
model.eval()</p>
<pre><code># shape = [seq_len, 1]
input_batch = sample["src"]
# list
input_len = sample["src_len"]

output_tokens = model(input_batch, input_len)
output_tokens = [idx2token[t] for t in output_tokens]

return "".join(output_tokens)
</code></pre>
<p>INPUT_DIM = len(en2id)<br>
OUTPUT_DIM = len(ch2id)</p>
<h1>
<a name="heading-9" class="anchor" href="#heading-9"></a>超参数</h1>
<p>BATCH_SIZE = 32<br>
ENC_EMB_DIM = 256<br>
DEC_EMB_DIM = 256<br>
HID_DIM = 512<br>
N_LAYERS = 2<br>
ENC_DROPOUT = 0.5<br>
DEC_DROPOUT = 0.5<br>
LEARNING_RATE = 1e-4<br>
N_EPOCHS = 100<br>
CLIP = 1</p>
<p>bidirectional = True<br>
attn_method = “general”<br>
enc = Encoder(INPUT_DIM, ENC_EMB_DIM, HID_DIM,<br>
N_LAYERS, ENC_DROPOUT, bidirectional)<br>
dec = AttnDecoder(OUTPUT_DIM, DEC_EMB_DIM, HID_DIM, N_LAYERS,<br>
DEC_DROPOUT, bidirectional, attn_method)<br>
model = Seq2Seq(enc, dec, device, basic_dict=basic_dict).to(device)</p>
<p>optimizer = optim.Adam(model.parameters(), lr=LEARNING_RATE)</p>
<h1>
<a name="heading-10" class="anchor" href="#heading-10"></a>数据集</h1>
<p>train_set = TranslationDataset(en_num_data, ch_num_data)<br>
train_loader = DataLoader(<br>
train_set, batch_size=BATCH_SIZE, collate_fn=padding_batch)<br>
best_valid_loss = float(‘inf’)</p>
<h1>
<a name="heading-11" class="anchor" href="#heading-11"></a>加载最优权重</h1>
<p>model.load_state_dict(torch.load(“en2ch-attn-model.pt”))</p>
<p>seed = 2020<br>
random.seed(seed)<br>
for i in random.sample(range(len(en_num_data)), 10):  # 随机看10个<br>
en_tokens = list(filter(lambda x: x != 0, en_num_data[i]))  # 过滤零<br>
ch_tokens = list(filter(lambda x: x != 3 and x<br>
!= 0, ch_num_data[i]))  # 和机器翻译作对照<br>
sentence = [id2en[t] for t in en_tokens]<br>
print("【原文】")<br>
print("".join(sentence))<br>
translation = [id2ch[t] for t in ch_tokens]<br>
print("【原文】")<br>
print("".join(translation))<br>
test_sample = {}<br>
test_sample[“src”] = torch.tensor(<br>
en_tokens, dtype=torch.long, device=device).reshape(-1, 1)<br>
test_sample[“src_len”] = [len(en_tokens)]<br>
print("【机器翻译】")<br>
print(translate(model, test_sample, id2ch), end="\n\n")</p>
<p>while True:<br>
in_data = input(“English: “)<br>
input_data = []<br>
input_data.append(in_data)<br>
en_token_list = [[char for char in line]+[””] for line in input_data]<br>
en_num_data = [[en2id[en] for en in line] for line in en_token_list]</p>
<pre><code>en_tokens = list(filter(lambda x: x != 0, en_num_data[0]))  # 过滤零
sentence = [id2en[t] for t in en_tokens]
test_sample = {}
test_sample["src"] = torch.tensor(
    en_tokens, dtype=torch.long, device=device).reshape(-1, 1)
test_sample["src_len"] = [len(en_tokens)]
print("【机器翻译】")
print(translate(model, test_sample, id2ch), end="\n\n")</code></pre>

ptrblck: <p>Could you compare the model outputs using a static input (e.g. <code>torch.ones</code>) before saving the model and after loading it? If these two outputs are equal up to the limited numerical precision of floating point numbers, I would guess that the data preprocessing might be different.</p>
<p>PS: you can post code snippets by wrapping them into three backticks ``` <img src="https://discuss.pytorch.org/images/emoji/apple/wink.png?v=10" title=":wink:" class="emoji" alt=":wink:"></p>