def test(args): print("load model from {}".format(args["MODEL_PATH"]), file=sys.stderr) model = NMT.load(args["MODEL_PATH"]) if args["--cuda"]: model = model.to(torch.device("cuda:0")) binary = int(args["--num-classes"]) == 2 test_data = load_test_data(binary=binary) batch_size = int(args["--batch-size"]) cum_correct = 0 cum_score = 0 with torch.no_grad(): for sentences, sentiments in batch_iter(test_data, batch_size): correct = model.compute_accuracy(sentences, sentiments) * len(sentences) cum_correct += correct score = -model(sentences, sentiments).sum() cum_score += score print("test dataset size: %d" % len(test_data)) print("accuracy: %f" % (cum_correct / len(test_data))) print("loss: %f" % (cum_score / len(test_data)))
def test(): print( f"load test sentences from [{config.test_path_src}], [{config.test_path_tar}]", file=sys.stderr) test_data = Data(config.test_path_src, config.test_path_tar) test_data_loader = DataLoader(dataset=test_data, batch_size=config.test_batch_size, shuffle=True, collate_fn=utils.get_batch) model_path = "/home/wangshuhe/shuhelearn/ShuHeLearning/NMT_attention/result/02.08_window35_6_8.810715463205241_checkpoint.pth" print(f"load model from {model_path}", file=sys.stderr) model = NMT.load(model_path) if (config.cuda): model = model.to(torch.device("cuda:0")) #model = model.cuda() #model = nn.parallel.DistributedDataParallel(model) predict, test_data_tar = beam_search(model, test_data, test_data_loader, 15, config.max_tar_length) for i in range(len(test_data_tar)): for j in range(len(test_data_tar[i])): test_data_tar[i][j] = model.text.tar.id2word[test_data_tar[i][j]] for i in range(len(predict)): for j in range(len(predict[i])): predict[i][j] = model.text.tar.id2word[predict[i][j]] best_predict = [] for i in tqdm(range(len(test_data_tar)), desc="find best predict"): best_predict.append(predict[i][compare_bleu(predict[i], test_data_tar[i])]) bleu = corpus_bleu([[ref[1:-1]] for ref in test_data_tar], [pre for pre in predict]) print(f"BLEU is {bleu*100}", file=sys.stderr)
def test(): print( f"load test sentences from [{config.test_path_src}], [{config.test_path_tar}]", file=sys.stderr) #test_data_src, test_data_tar = utils.read_corpus(config.test_path) test_data = Data(config.test_path_src, config.test_path_tar) test_data_loader = DataLoader(dataset=test_data, batch_size=config.test_batch_size, shuffle=True, collate_fn=utils.get_batch) model_path = "/home/wangshuhe/shuhelearn/ShuHeLearning/NMT_transformer/small/result/02.10_145_1.037565227213504_checkpoint.pth" model = NMT.load(model_path) if (config.cuda): model = model.to(torch.device("cuda:0")) predict, test_data_tar = beam_search(model, test_data, test_data_loader, 15, config.max_tar_length) for i in range(len(test_data_tar)): for j in range(len(test_data_tar[i])): test_data_tar[i][j] = model.text.tar.id2word[test_data_tar[i][j]] for i in range(len(predict)): for j in range(len(predict[i])): predict[i][j] = model.text.tar.id2word[predict[i][j]] bleu = corpus_bleu([[tar[1:-1]] for tar in test_data_tar], [pre for pre in predict]) print(f"Corpus BLEU: {bleu * 100}", file=sys.stderr)
def test(args): data_path = args['--data_path'] model_path = args['--model_path'] beam_size = int(args['--beam_size']) max_len = int(args['--max_len']) vocab = Vocab.load() source = load_corpus(data_path+'/test.es', 'es', limit=100) reference_tgt = load_corpus(data_path+'/test.en', 'en', limit=100) device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu') model = NMT.load(model_path, vocab) model.to(device) model.eval() translate_tgt = [] with torch.no_grad(): for src in tqdm(source, desc='translate '): src, _ = vocab.src.to_tensor([src], 'src') tgt = model.translate(src.to(device), beam_size, max_len) translate_tgt.append(tgt) translate_tgt = vocab.tgt.to_sentences(translate_tgt) if reference_tgt[0][0] == '<s>': regerence_tgt = [sent[1:-1] for sent in reference_tgt] bleu_score = nltk.translate.bleu_score.corpus_bleu([[refer] for refer in reference_tgt], translate_tgt) print("corpus bleu score on test data is %.2f" % (bleu_score*100)) # write translate sentences to file with open(data_path+'/result.txt', 'w') as f: detokenizer = MosesDetokenizer('en') for sent in translate_tgt: sent = detokenizer(sent) f.write(sent+'\n') detokenizer.close()
def multi_parameter_tuning(args): lrs = [1e-2, 1e-3, 5e-3, 1e-4, 5e-4] hidden_sizes = [128, 256, 512] lr_decays = [0.9, 0.7, 0.5] iter = 0 valid_metric = {} # 存储各个模型ppl的值 dev_data_src = read_corpus(args['dev_source'], source='src') dev_data_tgt = read_corpus(args['dev_target'], source='tgt') dev_data = list(zip(dev_data_src, dev_data_tgt)) for i in lrs: for j in hidden_sizes: for k in lr_decays: print( '第%d次测试=================================================' % iter) arg_test = args arg_test['lr'], arg_test['hidden_size'], arg_test[ 'lr_decay'] = i, j, k arg_test['save_to'] = 'model_' + 'lr_' + str( i) + 'hd_size_' + str(j) + 'lr_dys_' + str(k) + '.bin' run.train(arg_test) model = NMT.load(arg_test['save_to']) dev_ppl = run.evaluate_ppl( model, dev_data, batch_size=128) # dev batch size can be a bit larger valid_metric[arg_test['save_to']] = dev_ppl print(arg_test['save_to'], ' validation: iter %d, dev. ppl %f' % (iter, dev_ppl), file=sys.stderr) iter += 1 model = min(valid_metric, key=valid_metric.get()) print('best_model is %s ,ppl is %f' % (model, valid_metric[model]))
def decode(args: Dict[str, str]): """ Performs decoding on a test set, and save the best-scoring decoding results. If the target gold-standard sentences are given, the function also computes corpus-level BLEU score. @param args (Dict): args from cmd line """ print("load test source sentences from [{}]".format(args['TEST_SOURCE_FILE']), file=sys.stderr) test_data_src = read_corpus(args['TEST_SOURCE_FILE'], source='src') if args['TEST_TARGET_FILE']: print("load test target sentences from [{}]".format(args['TEST_TARGET_FILE']), file=sys.stderr) test_data_tgt = read_corpus(args['TEST_TARGET_FILE'], source='tgt') print("load model from {}".format(args['MODEL_PATH']), file=sys.stderr) model = NMT.load(args['MODEL_PATH'], no_char_decoder=args['--no-char-decoder']) if args['--cuda']: model = model.to(torch.device("cuda:0")) hypotheses = beam_search(model, test_data_src, beam_size=int(args['--beam-size']), max_decoding_time_step=int(args['--max-decoding-time-step'])) if args['TEST_TARGET_FILE']: top_hypotheses = [hyps[0] for hyps in hypotheses] bleu_score = compute_corpus_level_bleu_score(test_data_tgt, top_hypotheses) print('Corpus BLEU: {}'.format(bleu_score * 100), file=sys.stderr) with open(args['OUTPUT_FILE'], 'w') as f: for src_sent, hyps in zip(test_data_src, hypotheses): top_hyp = hyps[0] hyp_sent = ' '.join(top_hyp.value) f.write(hyp_sent + '\n')
def decode(args: Dict[str, str]): """ Performs decoding on a test set, and save the best-scoring decoding results. If the target gold-standard sentences are given, the function also computes corpus-level BLEU score. @param args (Dict): args from cmd line """ print("load test source sentences from [{}]".format( args['TEST_SOURCE_FILE']), file=sys.stderr) test_data_src = read_corpus(args['TEST_SOURCE_FILE'], source='src') if args['TEST_TARGET_FILE']: print("load test target sentences from [{}]".format( args['TEST_TARGET_FILE']), file=sys.stderr) test_data_tgt = read_corpus(args['TEST_TARGET_FILE'], source='tgt') print("load model from {}".format(args['MODEL_PATH']), file=sys.stderr) model = NMT.load(args['MODEL_PATH']) if args['--cuda']: model = model.to(torch.device("cuda")) hypotheses = beam_search(model, test_data_src, beam_size=int(args['--beam-size']), max_decoding_time_step=int( args['--max-decoding-time-step'])) if args['TEST_TARGET_FILE']: top_hypotheses = [hyps[0] for hyps in hypotheses] bleu_score = compute_corpus_level_bleu_score(test_data_tgt, top_hypotheses) print('Corpus BLEU: {}'.format(bleu_score * 100), file=sys.stderr) with open(args['OUTPUT_FILE'], 'w') as f: for src_sent, hyps in zip(test_data_src, hypotheses): top_hyp = hyps[0] hyp_sent = ' '.join(top_hyp.value) f.write(hyp_sent + '\n') if args['--plot-attention']: plt.rcParams['font.family'] = ['sans-serif'] plt.rcParams['font.sans-serif'] = [ 'Arial Unicode MS', 'Arial', 'sans-serif' ] from matplotlib.font_manager import _rebuild _rebuild() output_dir = os.path.dirname(args['OUTPUT_FILE']) for idx, (src_sent, hyps) in tqdm(enumerate(zip(test_data_src, hypotheses)), desc='Plot attention', file=sys.stdout): top_hyp = hyps[0] hyp_sent = top_hyp.value hyp_att = top_hyp.attention filename = output_dir + '/att_%d.jpg' % idx plot_attention(hyp_att, src_sent, hyp_sent, filename)
def decode(args: Dict[str, str]): """ 在测试集上执行解码操作, 保存最高得分的解码结果. 如果给定标准句子,函数还会计算平均字符准确率CA,第一个候选句子命中率HRF,前k个候选句子命中率kHRF @param args (Dict): 命令行参数 """ if args['SENTENCE']: ps = PinyinSplit() test_data_src = [ps.split(args['SENTENCE'])] if args['TEST_SOURCE_FILE']: print("load test source sentences from [{}]".format( args['TEST_SOURCE_FILE']), file=sys.stderr) test_data_src = read_corpus(args['TEST_SOURCE_FILE'], source='src') if args['TEST_TARGET_FILE']: print("load test target sentences from [{}]".format( args['TEST_TARGET_FILE']), file=sys.stderr) test_data_tgt = read_corpus(args['TEST_TARGET_FILE'], source='tgt') print("load model from {}".format(args['MODEL_PATH']), file=sys.stderr) model = NMT.load(args['MODEL_PATH']) if args['--cuda']: model = model.to(torch.device("cuda:0")) beam_size = int(args['--beam-size']) hypotheses = beam_search(model, test_data_src, beam_size=beam_size, max_decoding_time_step=int( args['--max-decoding-time-step'])) if args['TEST_TARGET_FILE']: top_hypotheses = [hyps[0] for hyps in hypotheses] # 每句话转汉字的首选项形成的列表 avg_ca, hrf = evaluate_ca_hrf(test_data_tgt, top_hypotheses) khrf = evaluate_khrf(test_data_tgt, hypotheses) # bleu_score = compute_corpus_level_bleu_score(test_data_tgt, top_hypotheses) # 打分 # print('Corpus BLEU: {}'.format(bleu_score * 100), file=sys.stderr) print('avg_ca: {}'.format(avg_ca), file=sys.stderr) print('hrf: {}'.format(hrf), file=sys.stderr) print('{}hrf: {}'.format(beam_size, khrf), file=sys.stderr) if args['OUTPUT_FILE']: with open(args['OUTPUT_FILE'], 'w') as f: for src_sent, hyps in zip(test_data_src, hypotheses): top_hyp = hyps[0] hyp_sent = ''.join(top_hyp.value) f.write(hyp_sent + '\n') if args['SENTENCE']: print('source sentence: {}'.format(args['SENTENCE'])) for i in range(len(hypotheses[0])): result = ''.join(hypotheses[0][i].value) print('top_{}_hypotheses_{}: {}'.format(beam_size, i + 1, result))
def decode(test_src_path, test_tgt_path=None, model_path='model.bin', beam_size=5, max_decoding=70, device='cpu', output_path='output.txt'): """ Performs decoding on a test set, and save the best-scoring decoding results. If the target gold-standard sentences are given, the function also computes corpus-level BLEU score. Params: test_src_path (str): Path to the test source file test_tgt_path (str): Path to the test target file (optional). Default=None model_path (str): Path to the model file generated after training. Default='model.bin' beam_size (int): beam size (# of hypotheses to hold for a translation at every step) max_decoding (int): maximum sentence length that Beam search can produce. Default=70 device (str): device to perform the calc on. Default = 'cpu' output_path (str): Path for the output file to write the results of the translation. Default='output.txt' """ print(f'load test source sentences from [{test_src_path}]', file=sys.stderr) test_data_src = read_corpus(test_src_path, corpus_type='src') if test_tgt_path is not None: print(f'load test target sentences from [{test_tgt_path}]', file=sys.stderr) test_data_tgt = read_corpus(test_tgt_path, corpus_type='tgt') print(f'load model from {model_path}', file=sys.stderr) model = NMT.load(model_path) model = model.to(torch.device(device)) hypotheses = beam_search(model, test_data_src, beam_size=beam_size, max_decoding_time_step=max_decoding) if test_tgt_path is not None: top_hypotheses = [hyps[0] for hyps in hypotheses] bleu_score = compute_corpus_level_bleu_score(test_data_tgt, top_hypotheses) print(f'Corpus BLEU: {bleu_score}', file=sys.stderr) with open(output_path, 'w') as f: for src_sent, hyps in zip(test_data_src, hypotheses): top_hyp = hyps[0] hyp_sent = ' '.join(top_hyp.value) f.write(hyp_sent + '\n')
def decode(args: Dict[str, str]): """ Performs decoding on a test set, and save the best-scoring decoding results. If the target gold-standard sentences are given, the function also computes corpus-level BLEU score. @param args (Dict): args from cmd line """ print("load test source sentences from [{}]".format(args['TEST_SOURCE_FILE']), file=sys.stderr) test_data_src = read_corpus(args['TEST_SOURCE_FILE'], source='src') if args['TEST_TARGET_FILE']: print("load test target sentences from [{}]".format(args['TEST_TARGET_FILE']), file=sys.stderr) test_data_tgt = read_corpus(args['TEST_TARGET_FILE'], source='tgt') print("load model from {}".format(args['MODEL_PATH']), file=sys.stderr) model_dir = './saved_model/' + args['--exp-name'] model_save_path = os.path.join(model_dir, args['--save-to']) #model = NMT.load(args['MODEL_PATH'], no_char_decoder=args['--no-char-decoder']) print('loading model from path: ' + model_save_path) model = NMT.load(model_save_path, no_char_decoder=args['--no-char-decoder'], with_contex=args['--with-contex'], contex_LSTM=args['--contex-LSTM'], multi_encoder=args['--multi-encoder']) if args['--cuda']: model = model.to(torch.device("cuda:0")) hypotheses = beam_search(model, test_data_src, beam_size=int(args['--beam-size']), max_decoding_time_step=int(args['--max-decoding-time-step'])) if args['TEST_TARGET_FILE']: top_hypotheses = [hyps[0] for hyps in hypotheses] bleu_score = compute_corpus_level_bleu_score(test_data_tgt, top_hypotheses) print('Corpus BLEU: {}'.format(bleu_score * 100), file=sys.stderr) with open(args['OUTPUT_FILE'], 'w') as f: for src_sent, hyps in zip(test_data_src, hypotheses): top_hyp = hyps[0] detokenizer = TreebankWordDetokenizer() detokenizer.DOUBLE_DASHES = (re.compile(r'--'), r'--') hyp_sent = detokenizer.detokenize(top_hyp.value) # hyp_sent = ' '.join(top_hyp.value) f.write(hyp_sent + '\n')
def decode(args: Dict[str, str]): """ Performs decoding on a test set, and save the best-scoring decoding results. If the target gold-standard sentences are given, the function also computes corpus-level BLEU score. @param args (Dict): args from cmd line """ print("load test source sentences from [{}]".format( args['TEST_SOURCE_FILE']), file=sys.stderr) test_data_src = read_corpus(args['TEST_SOURCE_FILE'], source='src') if args['TEST_TARGET_FILE']: print("load test target sentences from [{}]".format( args['TEST_TARGET_FILE']), file=sys.stderr) test_data_tgt = read_corpus(args['TEST_TARGET_FILE'], source='tgt') print("load model from {}".format(args['MODEL_PATH']), file=sys.stderr) model1 = NMT.load(args['MODEL_PATH']) model2 = DPPNMT.load(args['MODEL_PATH']) if args['INDEX']: index = int(args['INDEX']) beam_search2( model1, model2, [test_data_src[index]], 5, 70, [test_data_tgt[index]], ) else: beam_search2( model1, model2, test_data_src, #int(args['--beam-size']), 5, #int(args['--max-decoding-time-step']), 70, test_data_tgt, )
def decode(args, test_data_src, test_data_tgt=None): """ Performs decoding on a test set, and save the best-scoring decoding results. If the target gold-standard sentences are given, the function also computes corpus-level BLEU score. """ print("load test source sentences from [{}]".format(test_data_src)) test_data_src = read_corpus(test_data_src, source='src') if test_data_tgt: print("load test target sentences from [{}]".format(test_data_tgt)) test_data_tgt = read_corpus(test_data_tgt, source='tgt') print("load model from {}".format(args.model_path)) model = NMT.load(args.model_path) if args.cuda: model = model.to(torch.device("cuda:0")) hypotheses = beam_search( model, test_data_src, beam_size=args.beam_size, max_decoding_time_step=args.max_decoding_time_step) if args.test_tgt: top_hypotheses = [hyps[0] for hyps in hypotheses] bleu_score = compute_corpus_level_bleu_score(test_data_tgt, top_hypotheses) print('Corpus BLEU: {}'.format(bleu_score * 100)) if args.output_file: print("Saving predictions to " + args.output_file) with open(args.output_file, 'w') as f: for src_sent, hyps in zip(test_data_src, hypotheses): top_hyp = hyps[0] hyp_sent = ' '.join(top_hyp.value) f.write(hyp_sent + '\n') else: print("No output_file given, not saving predictions")
def decode(args: Dict[str, str]): """ Performs decoding on the autograder test set Make sure to run this code before submitting the code to the auto`grader @param args (Dict): args from cmd line """ test_data_src = read_corpus(args['SOURCE_FILE'], source='src') model = NMT.load(args['MODEL_PATH']) if args['CUDA']: model = model.to(torch.device("cuda:0")) hypotheses = beam_search(model, test_data_src, beam_size=int(args['BEAM_SIZE']), max_decoding_time_step=int( args['MAX_DECODING_TIME_STEP'])) with open(args['OUTPUT_FILE'], 'w') as f: for src_sent, hyps in zip(test_data_src, hypotheses): top_hyp = hyps[0] hyp_sent = ' '.join(top_hyp.value) f.write(hyp_sent + '\n')
def train(args: Dict): """ Train the NMT Model. @param args (Dict): args from cmd line """ train_data_src = read_corpus(args['--train-src'], source='src') train_data_tgt = read_corpus(args['--train-tgt'], source='tgt') dev_data_src = read_corpus(args['--dev-src'], source='src') dev_data_tgt = read_corpus(args['--dev-tgt'], source='tgt') train_data = list(zip(train_data_src, train_data_tgt)) dev_data = list(zip(dev_data_src, dev_data_tgt)) train_batch_size = int(args['--batch-size']) clip_grad = float(args['--clip-grad']) valid_niter = int(args['--valid-niter']) log_every = int(args['--log-every']) model_save_path = args['--save-to'] vocab = Vocab.load(args['--vocab']) existing_model = args['--existing-model-path'] start_from_existing_model = existing_model and os.path.isfile( existing_model) if start_from_existing_model: print("load model from {}".format(existing_model), file=sys.stderr) model = NMT.load(existing_model, no_char_decoder=args['--no-char-decoder']) else: print("Create a new model from hyper parameters") model = NMT(embed_size=int(args['--embed-size']), hidden_size=int(args['--hidden-size']), dropout_rate=float(args['--dropout']), vocab=vocab, no_char_decoder=args['--no-char-decoder']) model.train() print_model_param_count(model) # TODO: How to print all the parameters of this model? And is it useful? if not start_from_existing_model: uniform_init = float(args['--uniform-init']) if np.abs(uniform_init) > 0.: print('uniformly initialize parameters [-%f, +%f]' % (uniform_init, uniform_init), file=sys.stderr) for p in model.parameters(): p.data.uniform_(-uniform_init, uniform_init) vocab_mask = torch.ones(len(vocab.tgt)) vocab_mask[vocab.tgt['<pad>']] = 0 device = torch.device("cuda:0" if args['--cuda'] else "cpu") print('use device: %s' % device, file=sys.stderr) model = model.to(device) optimizer = torch.optim.Adam(model.parameters(), lr=float(args['--lr'])) num_trial = 0 train_iter = patience = cum_loss = report_loss = cum_tgt_words = report_tgt_words = 0 cum_examples = report_examples = epoch = valid_num = 0 hist_valid_scores = [] train_time = begin_time = time.time() print('begin Maximum Likelihood training') avg_train_ppls = [] avg_valid_ppls = [] # output_file_path = 'outputs/loss_%s' % datetime.datetime.now().strftime("%m-%d-%Y-%I:%M%p") output_file_path = os.path.join( args['--ppl-save-dir'], 'ppl.json') if args['--ppl-save-dir'] else 'ppl.json' while True: epoch += 1 for src_sents, tgt_sents in batch_iter(train_data, batch_size=train_batch_size, shuffle=True): train_iter += 1 optimizer.zero_grad() batch_size = len(src_sents) example_losses = -model(src_sents, tgt_sents) # (batch_size,) batch_loss = example_losses.sum() loss = batch_loss / batch_size loss.backward() # clip gradient grad_norm = torch.nn.utils.clip_grad_norm_(model.parameters(), clip_grad) optimizer.step() batch_losses_val = batch_loss.item() report_loss += batch_losses_val cum_loss += batch_losses_val tgt_words_num_to_predict = sum( len(s[1:]) for s in tgt_sents) # omitting leading `<s>` report_tgt_words += tgt_words_num_to_predict cum_tgt_words += tgt_words_num_to_predict report_examples += batch_size cum_examples += batch_size if train_iter % log_every == 0: print('epoch %d, iter %d, avg. loss %.2f, avg. ppl %.2f ' \ 'cum. examples %d, speed %.2f words/sec, time elapsed %.2f sec' % (epoch, train_iter, report_loss / report_examples, np.exp(report_loss / report_tgt_words), cum_examples, report_tgt_words / (time.time() - train_time), time.time() - begin_time), file=sys.stderr) avg_train_ppls.append(np.exp(report_loss / report_tgt_words)) train_time = time.time() report_loss = report_tgt_words = report_examples = 0. # perform validation if train_iter % valid_niter == 0: # The printed values are the train loss print( 'epoch %d, iter %d, cum. loss %.2f, cum. ppl %.2f cum. examples %d' % (epoch, train_iter, cum_loss / cum_examples, np.exp(cum_loss / cum_tgt_words), cum_examples), file=sys.stderr) cum_loss = cum_examples = cum_tgt_words = 0. valid_num += 1 print('begin validation ...', file=sys.stderr) # compute dev. ppl and bleu dev_ppl = evaluate_ppl( model, dev_data, batch_size=128) # dev batch size can be a bit larger avg_valid_ppls.append(dev_ppl) valid_metric = -dev_ppl print('validation: iter %d, dev. ppl %f' % (train_iter, dev_ppl), file=sys.stderr) is_better = len(hist_valid_scores ) == 0 or valid_metric > max(hist_valid_scores) hist_valid_scores.append(valid_metric) if is_better: patience = 0 print('save currently the best model to [%s]' % model_save_path, file=sys.stderr) model.save(model_save_path) # also save the optimizers' state torch.save(optimizer.state_dict(), model_save_path + '.optim') elif patience < int(args['--patience']): patience += 1 print('hit patience %d' % patience, file=sys.stderr) if patience == int(args['--patience']): num_trial += 1 print('hit #%d trial' % num_trial, file=sys.stderr) if num_trial == int(args['--max-num-trial']): print('early stop!', file=sys.stderr) output_losses(args, log_every, valid_niter, avg_train_ppls, avg_valid_ppls, output_file_path) exit(0) # decay lr, and restore from previously best checkpoint lr = optimizer.param_groups[0]['lr'] * float( args['--lr-decay']) print( 'load previously best model and decay learning rate to %f' % lr, file=sys.stderr) # load model params = torch.load( model_save_path, map_location=lambda storage, loc: storage) model.load_state_dict(params['state_dict']) model = model.to(device) print('restore parameters of the optimizers', file=sys.stderr) optimizer.load_state_dict( torch.load(model_save_path + '.optim')) # TODO: len(optimizer.param_groups) == 1 ? Or the below code seems odd # set new lr for param_group in optimizer.param_groups: param_group['lr'] = lr # reset patience patience = 0 if epoch == int(args['--max-epoch']): print('reached maximum number of epochs!', file=sys.stderr) output_losses(args, log_every, valid_niter, avg_train_ppls, avg_valid_ppls, output_file_path) exit(0) output_losses(args, log_every, valid_niter, avg_train_ppls, avg_valid_ppls, output_file_path) if args['--is-google-colab'] and epoch % 2 == 0 and os.path.isfile( model_save_path): shutil.copy(model_save_path, args['--ppl-save-dir']) shutil.copy(model_save_path + '.optim', args['--ppl-save-dir']) print("copied model files to google drive!")
def train(args: Dict): """ Train the NMT Model. @param args (Dict): args from cmd line """ train_data_src = read_corpus(args['--train-src'], source='src') train_data_tgt = read_corpus(args['--train-tgt'], source='tgt') dev_data_src = read_corpus(args['--dev-src'], source='src') dev_data_tgt = read_corpus(args['--dev-tgt'], source='tgt') train_data = list(zip(train_data_src, train_data_tgt)) dev_data = list(zip(dev_data_src, dev_data_tgt)) train_batch_size = int(args['--batch-size']) clip_grad = float(args['--clip-grad']) valid_niter = int(args['--valid-niter']) log_every = int(args['--log-every']) model_save_path = args['--save-to'] if args['--no-attention']: use_attention = False else: use_attention = True vocab = Vocab.load(args['--vocab']) if model_save_path in os.listdir(os.getcwd()): model = NMT.load(model_save_path) optimizer = torch.optim.Adam(model.parameters(), lr=float(args['--lr'])) optimizer.load_state_dict(torch.load(model_save_path + '.optim')) if args['--cuda']: for state in optimizer.state.values(): for k, v in state.items(): if isinstance(v, torch.Tensor): state[k] = v.cuda() print('load from previous best model', file=sys.stderr) else: model = NMT(embed_size=(int(args['--embed-size-src']), int(args['--embed-size-tgt'])), hidden_size=(int(args['--hidden-size-src']), int(args['--hidden-size-tgt'])), dropout_rate=float(args['--dropout']), vocab=vocab, use_attention=use_attention) uniform_init = float(args['--uniform-init']) if np.abs(uniform_init) > 0.: print('uniformly initialize parameters [-%f, +%f]' % (uniform_init, uniform_init), file=sys.stderr) for p in model.parameters(): p.data.uniform_(-uniform_init, uniform_init) optimizer = torch.optim.Adam(model.parameters(), lr=float(args['--lr'])) model.train() vocab_mask = torch.ones(len(vocab.tgt)) vocab_mask[vocab.tgt['<pad>']] = 0 device = torch.device("cuda:0" if args['--cuda'] else "cpu") print('use device: %s' % device, file=sys.stderr) model = model.to(device) num_trial = 0 train_iter = patience = cum_loss = report_loss = cum_tgt_words = report_tgt_words = 0 cum_examples = report_examples = epoch = valid_num = 0 hist_valid_scores = [] train_time = begin_time = time.time() print('begin Maximum Likelihood training') while True: epoch += 1 for src_sents, tgt_sents in batch_iter(train_data, batch_size=train_batch_size, shuffle=True, start=int( args['--start-train'])): train_iter += 1 optimizer.zero_grad() batch_size = len(src_sents) example_losses = -model(src_sents, tgt_sents) # (batch_size,) batch_loss = example_losses.sum() loss = batch_loss / batch_size loss.backward() # clip gradient grad_norm = torch.nn.utils.clip_grad_norm_(model.parameters(), clip_grad) optimizer.step() batch_losses_val = batch_loss.item() report_loss += batch_losses_val cum_loss += batch_losses_val tgt_words_num_to_predict = sum( len(s[1:]) for s in tgt_sents) # omitting leading `<s>` report_tgt_words += tgt_words_num_to_predict cum_tgt_words += tgt_words_num_to_predict report_examples += batch_size cum_examples += batch_size if train_iter % log_every == 0: print('epoch %d, iter %d, avg. loss %.2f, avg. ppl %.2f ' \ 'cum. examples %d, speed %.2f words/sec, time elapsed %.2f sec' % (epoch, train_iter, report_loss / report_examples, math.exp(report_loss / report_tgt_words), cum_examples, report_tgt_words / (time.time() - train_time), time.time() - begin_time), file=sys.stderr) train_time = time.time() report_loss = report_tgt_words = report_examples = 0. # perform validation if train_iter % valid_niter == 0: print( 'epoch %d, iter %d, cum. loss %.2f, cum. ppl %.2f cum. examples %d' % (epoch, train_iter, cum_loss / cum_examples, np.exp(cum_loss / cum_tgt_words), cum_examples), file=sys.stderr) cum_loss = cum_examples = cum_tgt_words = 0. valid_num += 1 print('begin validation ...', file=sys.stderr) # compute dev. ppl and bleu dev_ppl = evaluate_ppl( model, dev_data, batch_size=64) # dev batch size can be a bit larger valid_metric = -dev_ppl print('validation: iter %d, dev. ppl %f' % (train_iter, dev_ppl), file=sys.stderr) is_better = len(hist_valid_scores ) == 0 or valid_metric > max(hist_valid_scores) hist_valid_scores.append(valid_metric) if is_better: patience = 0 print('save currently the best model to [%s]' % model_save_path, file=sys.stderr) model.save(model_save_path) # also save the optimizers' state torch.save(optimizer.state_dict(), model_save_path + '.optim') elif patience < int(args['--patience']): patience += 1 print('hit patience %d' % patience, file=sys.stderr) if patience == int(args['--patience']): num_trial += 1 print('hit #%d trial' % num_trial, file=sys.stderr) if num_trial == int(args['--max-num-trial']): print('early stop!', file=sys.stderr) exit(0) # decay lr, and restore from previously best checkpoint lr = optimizer.param_groups[0]['lr'] * float( args['--lr-decay']) print( 'load previously best model and decay learning rate to %f' % lr, file=sys.stderr) # load model params = torch.load( model_save_path, map_location=lambda storage, loc: storage) model.load_state_dict(params['state_dict']) model = model.to(device) print('restore parameters of the optimizers', file=sys.stderr) optimizer.load_state_dict( torch.load(model_save_path + '.optim')) # set new lr for param_group in optimizer.param_groups: param_group['lr'] = lr # reset patience patience = 0 if epoch == int(args['--max-epoch']): print('reached maximum number of epochs!', file=sys.stderr) exit(0)
def decode(args: Dict[str, str]): """ Performs decoding on a test set, and save the best-scoring decoding results. If the target gold-standard sentences are given, the function also computes corpus-level BLEU score. @param args (Dict): args from cmd line """ spacy_en = spacy.load('en') def tokenizer(text): # create a tokenizer function return [tok.text for tok in spacy_en.tokenizer(text)] TEXT = Field(sequential=True, tokenize=tokenizer, lower=True, include_lengths=True, init_token='<s>', eos_token='</s>') analogies_datafields = [("abc", TEXT), ("d", TEXT)] train, val, test = TabularDataset.splits( path="data", # the root directory where the data lies train='ngram_train.csv', validation="ngram_val.csv", test='ngram_test.csv', format='csv', skip_header= False, # if your csv header has a header, make sure to pass this to ensure it doesn't get proceesed as data! fields=analogies_datafields) pretrained_vecs = torchtext.vocab.Vectors('../GloVe-1.2/life_vectors.txt') TEXT.build_vocab( vectors=pretrained_vecs) # specials=['<pad>', '<s>', '</s>'] if args['--cuda'] == 'cpu': torch_text_device = -1 else: torch_text_device = 0 training_iter, val_iter, test_iter = Iterator.splits( (train, val, test), sort_key=lambda x: len(x.abc), batch_sizes=(100, 20, 1), device=torch_text_device, sort_within_batch=True) print("load test source sentences from [{}]".format( args['TEST_SOURCE_FILE']), file=sys.stderr) test_data_src = read_corpus(args['TEST_SOURCE_FILE'], source='src') if args['TEST_TARGET_FILE']: print("load test target sentences from [{}]".format( args['TEST_TARGET_FILE']), file=sys.stderr) test_data_tgt = read_corpus(args['TEST_TARGET_FILE'], source='tgt') print("load model from {}".format(args['MODEL_PATH']), file=sys.stderr) model = NMT.load(args['MODEL_PATH']) if args['--cuda']: model = model.to(torch.device("cuda:0")) hypotheses = beam_search(model, test_iter, beam_size=int(args['--beam-size']), max_decoding_time_step=int( args['--max-decoding-time-step'])) if args['TEST_TARGET_FILE']: top_hypotheses = [hyps[0] for hyps in hypotheses] bleu_score = compute_corpus_level_bleu_score(test_data_tgt, top_hypotheses) #accuracy (unigrams) perfectly_correct = 0 for index, hyp in enumerate(top_hypotheses): if hyp.value[0] == test_data_tgt[index][1]: perfectly_correct += 1 print('Ignore accuracy for non unigrams') print('Accuracy: {}'.format(perfectly_correct / len(test_data_tgt)), file=sys.stderr) print('Corpus BLEU: {}'.format(bleu_score * 100), file=sys.stderr) with open(args['OUTPUT_FILE'], 'w') as f: for src_sent, hyps in zip(test_data_src, hypotheses): top_hyp = hyps[0] hyp_sent = ' '.join(top_hyp.value) f.write(hyp_sent + '\n')
def decode(args: Dict[str, str]): """ Performs decoding on a test set, and save the best-scoring decoding results. If the target gold-standard sentences are given, the function also computes corpus-level BLEU score. @param args (Dict): args from cmd line """ print("load test source sentences from [{}]".format( args['TEST_SOURCE_FILE']), file=sys.stderr) test_data_src_a = read_corpus(args['TEST_SOURCE_FILE_A'], source='src') test_data_src_b = read_corpus(args['TEST_SOURCE_FILE_B'], source='src') test_data_src_c = read_corpus(args['TEST_SOURCE_FILE_C'], source='src') test_data_cat = [(test_data_src_a[i], test_data_src_b[i], test_data_src_c[i]) for i in range(len(test_data_src_a))] if args['TEST_TARGET_FILE']: print("load test target sentences from [{}]".format( args['TEST_TARGET_FILE']), file=sys.stderr) test_data_tgt = read_corpus(args['TEST_TARGET_FILE'], source='tgt') print("load model from {}".format(args['MODEL_PATH']), file=sys.stderr) model = NMT.load(args['MODEL_PATH'], no_char_decoder=args['--no-char-decoder']) if args['--cuda']: model = model.to(torch.device("cuda:0")) hypotheses = beam_search(model, test_data_cat, beam_size=int(args['--beam-size']), max_decoding_time_step=int( args['--max-decoding-time-step'])) if args['TEST_TARGET_FILE']: top_hypotheses = [hyps[0] for hyps in hypotheses] bleu_score = compute_corpus_level_bleu_score(test_data_tgt, top_hypotheses) #accuracy (unigrams) # perfectly_correct = 0 # for index,hyp in enumerate(top_hypotheses): # correct = True # print(test_data_tgt ) # print(hyp) # for index,value in enumerate(test_data_tgt[index]): # print(value) # print(hyp.value[index]) # if hyp.value[index] != value: # correct = False # if correct: # perfectly_correct += 1 # print(perfectly_correct) print('Ignore accuracy for non unigrams') # print('Accuracy: {}'.format(perfectly_correct / len(test_data_tgt)), file=sys.stderr) print('Corpus BLEU: {}'.format(bleu_score * 100), file=sys.stderr) with open(args['OUTPUT_FILE'], 'w') as f: for a, b, c, hyps in zip(test_data_src, hypotheses): top_hyp = hyps[0] hyp_sent = ' '.join(top_hyp.value) f.write(hyp_sent + '\n')
def train(args: Dict): """ Train the NMT Model. @param args (Dict): args from cmd line """ train_data_src = read_corpus(args['train_source'], source='src') train_data_tgt = read_corpus(args['train_target'], source='tgt') dev_data_src = read_corpus(args['dev_source'], source='src') dev_data_tgt = read_corpus(args['dev_target'], source='tgt') train_data = list(zip(train_data_src, train_data_tgt)) dev_data = list(zip(dev_data_src, dev_data_tgt)) train_batch_size = int(args['batch_size']) clip_grad = float(args['clip_grad']) # 梯度裁剪 valid_niter = int(args['valid_niter']) log_every = int(args['log_every']) model_save_path = args['save_to'] vocab = Vocab.load(args['vocab']) load = args['load_model'] if load: model = NMT.load(args['save_to']) else: model = NMT(embed_size=int(args['embed_size']), hidden_size=int(args['hidden_size']), dropout_rate=float(args['dropout']), vocab=vocab) model.train() uniform_init = float(args['uniform_init']) if np.abs(uniform_init) > 0. and load is False: print('uniformly initialize parameters [-%f, +%f]' % (uniform_init, uniform_init), file=sys.stderr) for p in model.parameters(): p.data.uniform_(-uniform_init, uniform_init) vocab_mask = torch.ones(len(vocab.tgt)) vocab_mask[vocab.tgt['<pad>']] = 0 device = torch.device("cuda" if args['cuda'] else "cpu") print('use device: %s' % device, file=sys.stderr) model = model.to(device) optimizer = torch.optim.Adam(model.parameters(), lr=float(args['lr'])) if load: optimizer.load_state_dict(torch.load(args['save_to'] + '.optim')) num_trial = 0 train_iter = patience = cum_loss = report_loss = cum_tgt_words = report_tgt_words = 0 cum_examples = report_examples = epoch = valid_num = 0 hist_valid_scores = [] train_time = begin_time = time.time() print('begin Maximum Likelihood training') writer = SummaryWriter('result_loss') while True: epoch += 1 for src_sents, tgt_sents in batch_iter(train_data, batch_size=train_batch_size, shuffle=True): train_iter += 1 optimizer.zero_grad() batch_size = len(src_sents) example_losses = -model(src_sents, tgt_sents) # (batch_size,) batch_loss = example_losses.sum() loss = batch_loss / batch_size loss.backward() # clip gradient 梯度裁剪 grad_norm = torch.nn.utils.clip_grad_norm_(model.parameters(), clip_grad) optimizer.step() batch_losses_val = batch_loss.item() report_loss += batch_losses_val # report 输出用 cum_loss += batch_losses_val # cum 验证用 tgt_words_num_to_predict = sum(len(s[1:]) for s in tgt_sents) # omitting leading `<s>` report_tgt_words += tgt_words_num_to_predict cum_tgt_words += tgt_words_num_to_predict report_examples += batch_size cum_examples += batch_size writer.add_scalars('lr_{}_hadsizie_{}_lrdyc_{}_loss_ppl'.format(args['lr'], args['hidden_size'], args['lr_decay']), {'loss': loss.item(), 'ppl': math.exp(report_loss / report_tgt_words)}, train_iter) if train_iter % log_every == 0: print('epoch %d, iter %d, avg. loss %.2f, avg. ppl %.2f ' \ 'cum. examples %d, speed %.2f words/sec, time elapsed %.2f sec' % (epoch, train_iter, report_loss / report_examples, math.exp(report_loss / report_tgt_words), cum_examples, report_tgt_words / (time.time()- train_time), time.time() - begin_time), file=sys.stderr) train_time = time.time() report_loss = report_tgt_words = report_examples = 0. # perform validation if train_iter % valid_niter == 0: print('epoch %d, iter %d, cum. loss %.2f, cum. ppl %.2f cum. examples %d' % (epoch, train_iter, cum_loss / cum_examples, np.exp( cum_loss / cum_tgt_words), cum_examples), file=sys.stderr) cum_loss = cum_examples = cum_tgt_words = 0. valid_num += 1 print('begin validation ...', file=sys.stderr) # compute dev. ppl and bleu dev_ppl = evaluate_ppl(model, dev_data, batch_size=128) # dev batch size can be a bit larger valid_metric = -dev_ppl print('validation: iter %d, dev. ppl %f' % (train_iter, dev_ppl), file=sys.stderr) is_better = len(hist_valid_scores) == 0 or valid_metric > max(hist_valid_scores) hist_valid_scores.append(valid_metric) if is_better: patience = 0 print('save currently the best model to [%s]' % model_save_path, file=sys.stderr) model.save(model_save_path) # also save the optimizers' state torch.save(optimizer.state_dict(), model_save_path + '.optim') elif patience < int(args['patience']): patience += 1 print('hit patience %d' % patience, file=sys.stderr) if patience == int(args['patience']): num_trial += 1 print('hit #%d trial' % num_trial, file=sys.stderr) if num_trial == int(args['max_num_trial']): print('early stop!', file=sys.stderr) return None # decay lr, and restore from previously best checkpoint lr = optimizer.param_groups[0]['lr'] * float(args['lr_decay']) print('load previously best model and decay learning rate to %f' % lr, file=sys.stderr) # load model params = torch.load(model_save_path, map_location=lambda storage, loc: storage) model.load_state_dict(params['state_dict']) model = model.to(device) print('restore parameters of the optimizers', file=sys.stderr) optimizer.load_state_dict(torch.load(model_save_path + '.optim')) # set new lr for param_group in optimizer.param_groups: param_group['lr'] = lr # reset patience patience = 0 if epoch == int(args['max_epoch']): print('reached maximum number of epochs!', file=sys.stderr) return None writer.close()
def decode(test_src_path, test_tgt_path=None, model_path='model.bin', tokenizer='nltk', spm_model_src='./spm/src.model', spm_model_tgt='./spm/tgt.model', beam_size=5, max_decoding=70, device='cpu', output_path='output.txt'): """ Performs decoding on a test set, and save the best-scoring decoding results. If the target gold-standard sentences are given, the function also computes corpus-level BLEU score. Params: test_src_path (str): Path to the test source file test_tgt_path (str): Path to the test target file (optional). Default=None model_path (str): Path to the model file generated after training. Default='model.bin' tokenizer (str): Tokenizer used (nltk or spm). Default = nltk spm_model_src (str): Path to the source spm model. Default: ./spm/src.model spm_model_tgt (str): Path to the target spm model. Default: ./spm/tgt.model beam_size (int): beam size (# of hypotheses to hold for a translation at every step) max_decoding (int): maximum sentence length that Beam search can produce. Default=70 device (str): device to perform the calc on. Default = 'cpu' output_path (str): Path for the output file to write the results of the translation. Default='output.txt' """ print(f'load test source sentences from [{test_src_path}]', file=sys.stderr) if tokenizer == 'nltk': test_data_src = read_corpus(test_src_path, corpus_type='src') elif tokenizer == 'spm': test_data_src = read_corpus_spm(test_src_path, corpus_type='src', model_path=spm_model_src) else: raise Exception( f'unrecognised tokenizer {tokenizer}. Should be nltk or spm') if test_tgt_path is not None: print(f'load test target sentences from [{test_tgt_path}]', file=sys.stderr) if tokenizer == 'nltk': test_data_tgt = read_corpus(test_tgt_path, corpus_type='tgt') else: #spm test_data_tgt = read_corpus_spm(test_tgt_path, corpus_type='tgt', model_path=spm_model_tgt) print(f'load model from {model_path}', file=sys.stderr) model = NMT.load(model_path) model = model.to(torch.device(device)) hypotheses = beam_search(model, test_data_src, beam_size=beam_size, max_decoding_time_step=max_decoding) #print(hypotheses) if test_tgt_path is not None: top_hypotheses = [hyps[0] for hyps in hypotheses] bleu_score = compute_corpus_level_bleu_score(test_data_tgt, top_hypotheses) print(f'Corpus BLEU: {bleu_score}', file=sys.stderr) with open(output_path, 'w') as f: for src_sent, hyps in zip(test_data_src, hypotheses): top_hyp = hyps[0] if tokenizer == 'nltk': hyp_sent = ' '.join(top_hyp.value) else: #spm hyp_sent = ''.join(top_hyp.value).replace('▁', ' ') f.write(hyp_sent + '\n')
def decode(args: Dict[str, str], test_iterator: BucketIterator, vocab: Vocab, device: torch.device): """ Performs decoding on a test set, and save the best-scoring decoding results. If the target gold-standard sentences are given, the function also computes corpus-level BLEU score. @param args (Dict): args from cmd line """ # print("load test source sentences from [{}]".format(args['TEST_SOURCE_FILE']), file=sys.stderr) # test_data_src = read_corpus(args['TEST_SOURCE_FILE'], source='src') # if args['TEST_TARGET_FILE']: # print("load test target sentences from [{}]".format(args['TEST_TARGET_FILE']), file=sys.stderr) # test_data_tgt = read_corpus(args['TEST_TARGET_FILE'], source='tgt') print("") print("Start Testing: load model from {}".format(args['--save-to']), file=sys.stderr) model = NMT.load(args['--save-to'], bool(args['--use-pos-embed']), bool(args['--use-copy'])) if args['--cuda']: # model = model.to(torch.device("cuda:0")) model = model.to(device) beam_size = int(args['--beam-size']) hypotheses = beam_search(model, test_iterator, beam_size, max_decoding_time_step=int( args['--max-decoding-time-step'])) thd = 3 # for i in range(len(hypotheses)): # if i >= thd: # break # print("Hypo {}:".format(i)) # for j in range(beam_size): # print(" beam {}: {}".format(j, hypotheses[i][j])) # # Compute accuracy top_hypotheses = [hyps[0].value for hyps in hypotheses] match_count = 0 src_list = [] gold_list = [] pre_list = [] for i, batch in enumerate(test_iterator): src_sents, _ = batch.src src_sents = src_sents.permute(1, 0) trg_sents = batch.trg trg_sents = trg_sents.permute(1, 0) batch_size = trg_sents.size()[0] for j in range(batch_size): idx = i * batch_size + j pred = [vocab.tgt.stoi[token] for token in top_hypotheses[idx]] trg_sent = trg_sents[j] src_sent = src_sents[j] src = [vocab.src.itos[item] for item in src_sent.tolist()] gold = [vocab.tgt.itos[item] for item in trg_sent.tolist()] src = src[1:-1] gold = gold[1:gold.index('</s>')] src_list.append(" ".join(src)) gold_list.append(" ".join(gold)) pre_list.append(" ".join(top_hypotheses[idx])) if (idx < thd): print("ID: {}".format(idx)) print("src: {}".format(" ".join(src))) print("gold: {}".format(" ".join(gold))) print("pre: {}".format(" ".join(top_hypotheses[idx]))) match_count += compute_match(trg_sent, pred, vocab.dst_eos_token_idx) accuracy = match_count * 100 / len(top_hypotheses) print("Test Accuracy: {}".format(accuracy)) result_file = args['--save-to'] + '.result.csv' result = { 'hidden_size': [args['--hidden-size']], 'beam_size': [beam_size], 'accuracy': [accuracy] } result = pd.DataFrame.from_dict(result) result.to_csv(result_file) result_data_file = args['--save-to'] + '.result_data.tsv' result_data = {'src': src_list, 'gold': gold_list, 'pre': pre_list} result_df = pd.DataFrame.from_dict(result_data) result_df.to_csv(result_data_file, sep='\t', header=False, index=False)
zip(atten_engy, instances, copy_hypothesis)): obj.append({ 'idx': idx, 'decode_engy': str(engy), 'src_tokens': ' '.join(instance.src), 'output_tokens': ' '.join(hypothesis) }) json.dump(obj, open(predict_atten_engy_path, 'w'), indent=2) logger.info("{} of {} is completed hypothesis".format( total_completed, len(instances))) return copy_hypothesis if __name__ == '__main__': config = load_config() init_logger(log_file='evaluate.log') device = torch.device('cpu') if config['gpu'] < 0 else torch.device( 'cuda:{}'.format(config['gpu'])) if config['model'] == 'nmt': model = NMT.load(config['model_save_path']) model.to(device) else: model = QGModel.load(config['model_save_path'], device) test_instances = load_instances(config['save_dir'] + '/test.ins') bleus = evaluate_bleu(model, test_instances, config, model.word_vocab, config['predict_save_path']) logger.info( '\nBLEU_1: {}\nBLEU_2: {}\nBLEU_3: {}\nBLEU_4: {}\nBLEU :{}'.format( *bleus))
import torch from nmt_model import Hypothesis, NMT if __name__ == "__main__": model = NMT.load('model.bin', no_char_decoder=True) print("[INFO] the model is loaded") for i in model.modules(): print(i) print("=" * 80)
def do_translate(src_sentence: str) -> str: hypotheses = beam_search(model, src_sentence, beam_size=5, max_decoding_time_step=70) tgt_sentence = [] for src_sent, hyps in zip(src_sentence, hypotheses): top_hyp = hyps[0] hyp_sent = ' '.join(top_hyp.value) tgt_sentence.append(hyp_sent + '\n') return ''.join(tgt_sentence) if __name__ == "__main__": os.system("clear") model = NMT.load("./training_results/model.bin") src_sentence = "" while src_sentence != "<salir>": src_sentence = input("Escribe la oración en Español: ") if src_sentence != "<salir>" and len(src_sentence.split()) > 0: src_sentence = [src_sentence.split()] result = do_translate(src_sentence) print(f"Traducción: {result}")