赞
踩
基于术语词典干预的机器翻译挑战赛选择以英文为源语言,中文为目标语言的机器翻译。本次大赛除英文到中文的双语数据,还提供英中对照的术语词典。参赛队伍需要基于提供的训练数据样本从多语言机器翻译模型的构建与训练,并基于测试集以及术语词典,提供最终的翻译结果,数据包括:
·训练集:双语数据:中英14万余双语句对
·开发集:英中1000双语句对
·测试集:英中1000双语句对
·术语词典:英中2226条
最终提交翻译结果文档,并基于BLUE-4标准进行评价
Transformer模型为encoder-decoder结构,如下图所示:
在翻译任务中,编码器用来处理源语言,解码器用来处理目标语言(如图所示,在中翻英的任务中,编码器输入中文,解码器输入英文)
各层作用概述:
在输入层中,embedding和position的作用分别是将单词转换为对应向量表示,以及为每一个词添加位置编码,使得最终输出结果的语序能得到保证
self-attention层是Transformer的重大创新,当输入的词向量经过该层时,会计算当前的词向量与文本中其他词向量的近似程度,这种近似程度通过权重的大小来表示,进而让模型将“注意力”放在权重大的单词上,避免了传统基于RNN模型在过长文本上容易丢失信息的问题。
在解码器中,还额外添加了一个Masked Multi-Head Attention,是由于编码,解码器在训练过程中需要生成关于全文的注意力信息,而解码器在最终输出翻译时,是一个自回归的过程,不能让解码器看到当前正在输出的单词之后的文本。
前馈层接受自注意力子层的输出作为输入,并通过一个带有 Relu 激活函数的两层全连接网络对输入进行更加复杂的非线性变换。实验证明,这一非线性变换会对模型最终的性能产生十分重要的影响。
即残差连接与层归一化,用于避免由于网络深度较大时,在训练过程中容易发生的梯度消失问题。
# 主函数 if __name__ == '__main__': # 模型参数 D_MODEL = 512 #模型的宽度(token进入模型时的长度) NHEAD = 8 #注意力层头的个数 NUM_ENCODER_LAYERS = 3 NUM_DECODER_LAYERS = 3 DIM_FEEDFORWARD = 1024 #前馈神经网络神经元个数 DROPOUT = 0.1 N_EPOCHS = 10 CLIP = 1 # 初始化模型 model = initialize_model(en_vocab, zh_vocab, D_MODEL, NHEAD, NUM_ENCODER_LAYERS, NUM_DECODER_LAYERS, DIM_FEEDFORWARD, DROPOUT).to(DEVICE) print(f'The model has {sum(p.numel() for p in model.parameters() if p.requires_grad):,} trainable parameters') # 定义损失函数 criterion = nn.CrossEntropyLoss(ignore_index=zh_vocab['<pad>']) # 初始化优化器 optimizer = optim.Adam(model.parameters(), lr=0.0001, betas=(0.9, 0.98), eps=1e-9) # 训练模型 save_path = '../model/best-model_transformer.pt' train_model(model, train_loader, dev_loader, optimizer, criterion, N_EPOCHS, CLIP, save_path=save_path) print(f"训练完成!模型已保存到:{save_path}")
在本次训练过程中,主要对训练的参数进行调整和加入术语词典,在初始代码中,参数为:
D_MODEL = 256,DIM_FEEDFORWARD=512,N_EPOCHS = 5,最终训练的误差Train Loss为5.2,提交到竞赛平台的分数为6.42,而作出以上调整后(D_MODEL = 512,DIM_FEEDFORWARD=1024,N_EPOCHS = 10),训练效果和提交分数如下
说明增加训练数据集的遍历次数、模型的宽度以及前馈神经网络神经元的个数对模型训练效果的提升具有显著作用。
在增加术语词典机制后,分数在此基础上也有增加。
# 存储成字典 def load_dictionary(dict_path): term_dict = {} with open(dict_path, 'r', encoding='utf-8') as f: data = f.read() data = data.strip().split('\n') source_term = [line.split('\t')[0] for line in data] target_term = [line.split('\t')[1] for line in data] for i in range(len(source_term)): term_dict[source_term[i]] = target_term[i] return term_dict def post_process_translation(translation, term_dict): """ 使用术语词典进行后处理(这里的处理比较简单,加入更精细、高效的处理方式) """ translated_words = [term_dict.get(word, word) for word in translation] return "".join(translated_words) # 加载你的术语词典 dict_path = '../dataset/en-zh.dic' # 这应该是你的术语词典文件路径 term_dict = load_dictionary(dict_path) save_dir = '../results/submit_add_dict.txt' with open(save_dir, 'w') as f: translated_sentences = [] for batch in test_loader: # 遍历所有数据 src, _ = batch src = src.to(DEVICE) translated = translate_sentence(src[0], en_vocab, zh_vocab, model, DEVICE) #翻译结果 results = post_process_translation(translated, term_dict) results = "".join(results) f.write(results + '\n') # 将结果写入文件 print(f"翻译完成,结果已保存到{save_dir}")
本次线上学习让我了解了NLP领域模型的发展和基本原理,希望接下来能学到更多的调参优化方法,以及对背后的数学原理有更深入的理解。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。