#Datawhale AI 夏令营
实现步骤:
1.配置环境
运行环境我们还是基于魔搭平台进行模型训练,另外,有几个包需要额外安装:
- torchtext :是一个用于自然语言处理(NLP)任务的库,它提供了丰富的功能,包括数据预处理、词汇构建、序列化和批处理等,特别适合于文本分类、情感分析、机器翻译等任务
- jieba:是一个中文分词库,用于将中文文本切分成有意义的词语
- sacrebleu:用于评估机器翻译质量的工具,主要通过计算BLEU(BilingualEvaluation Understudy)得分来衡量生成文本与参考译文之间的相似度
- spacy:是一个强大的自然语言处理库,支持70+语言的分词与训练
- 数据预处理
机器翻译任务的预处理是确保模型能够有效学习源语言到目标语言映射的关键步骤。预处理阶段通常包括多个步骤,旨在清理、标准化和转换数据,使之适合模型训练。以下是机器翻译任务预处理中常见的几个处理步骤:
清洗和规范化数据
- 去除无关信息:删除HTML标签、特殊字符、非文本内容等,确保文本的纯净性(本赛题的训练集中出现了非常多的脏数据,如“Joey. (掌声) (掌声) 乔伊”、“Thank you. (马嘶声) 谢谢你们”等这种声音词)
- 统一格式:转换所有文本为小写,确保一致性;标准化日期、数字等格式。
- 分句和分段:将长文本分割成句子或段落,便于处理和训练。
- 分词:将句子分解成单词或词素(构成单词的基本组成部分,一个词素可以是一个完整的单词,也可以是单词的一部分,但每一个词素都至少携带一部分语义或语法信息),这是NLP中最基本的步骤之一。我们这里使用了使用jieba 对中文进行分词,使用spaCy对英文进行分词。
构建词汇表和词向量
- 词汇表构建:从训练数据中收集所有出现过的词汇,构建词汇表,并为每个词分配一个唯一的索引。
- 词向量:使用预训练的词向量或自己训练词向量,将词汇表中的词映射到高维空间中的向量,以捕捉语义信息(当前大模型领域训练的 embedding 模型就是用来完成此任务的)。
序列截断和填充
- 序列截断:限制输入序列的长度,过长的序列可能增加计算成本,同时也可能包含冗余信息。
- 序列填充:将所有序列填充至相同的长度,便于批量处理。通常使用<PAD>标记填充。
添加特殊标记
- 序列开始和结束标记:在序列两端添加<SOS>(Sequence Start)和<EOS>(Sequence End)标记,帮助模型识别序列的起始和结束。
- 未知词标记:为不在词汇表中的词添加<UNK>(Unknown)标记,使模型能够处理未见过的词汇。
数据增强
- 随机替换或删除词:在训练数据中随机替换或删除一些词,增强模型的鲁棒性。同义词替换:使用同义词替换原文中的词,增加训练数据的多样性。
数据分割
- 划分数据集:将数据划分为训练集、验证集和测试集,分别用于模型训练、参数调整和最终性能评估(该赛题中已划分好,不需要自己进行划分)
- 模型训练
说到神经机器翻译就不得不提编码器-解码器模型,或编码器-解码器框架(EncoderDecoder Paradigm)。本质上,编码器解码器模型是描述输入输出之间关系的一种方式。编码器解码器这个概念在日常生活中并不少见。
例如,在电视系统上为了便于视频的传播,会使用各种编码器将视频编码成数字信号,在客户端,相应的解码器组件会把收到的数字信号解码为视频。另外一个更贴近生活的例子是电话,它通过对声波和电信号进行相互转换,达到传递声音的目的。
这种“先编码,再解码”的思想被应用到密码学、信息论等多个领域。不难看出,机器翻译问题也完美的贴合编码器解码器结构的特点。可以将源语言编码为类似信息传输中的数字信号,然后利用解码器对其进行转换,生成目标语言。
4.翻译质量评价
人们在使用机器翻译系统时需要评估系统输出结果的质量。这个过程也被称作机器翻译译文质量评价,简称为译文质量评价(Quality Evaluation of Translation)。在机器翻译的发展进程中,译文质量评价有着非常重要的作用。不论在系统研发的反复迭代中,还是在诸多的机器翻译应用场景中,都存在大量的译文质量评价环节。从某种意义上说,没有译文质量评价,机器翻译也不会发展成今天的样子。比如,本世纪初研究人员提出了译文质量自动评价方法 BLEU(Bilingual Evaluation Understudy)(Task 1知识文档已详细介绍过)。该方法使得机器翻译系统的评价变得自动、快速、便捷,而且评价过程可以重复。正是由于 BLEU 等自动评价方法的提出,机器翻译研究人员可以在更短的时间内得到译文质量的评价结果,加速系统研发的进程。
运行过程:
首先根据task2中的步骤进行环境配置,这一步算比较简单
在后面运行阶段出现了一些问题,首先是运行时间过于长,然后把test_loader的batch_size改成1尝试,还是出现了挺多错误的,由于没有学过python,做起来比较吃力,有点难懂
核心代码:
# 主函数 if __name__ == '__main__':
# 设置训练的总轮次(epochs)
N_EPOCHS = 75 #我75*5000过拟合了自己改参数
# 梯度裁剪的阈值,用于防止梯度爆炸
CLIP = 1
# 模型参数设置
# 输入维度,即英文词汇表的大小
INPUT_DIM = len(en_vocab)
# 输出维度,即中文词汇表的大小
OUTPUT_DIM = len(zh_vocab)
# 嵌入层的维度
EMB_DIM = 256
# 隐藏层的维度
HID_DIM = 512
# LSTM层的数量
N_LAYERS = 2
# Dropout的比例,用于防止过拟合
DROPOUT = 0.5
# 初始化模型,需要传入模型的各种参数以及运行设备
model = initialize_model(INPUT_DIM, OUTPUT_DIM, EMB_DIM, HID_DIM, N_LAYERS, DROPOUT, 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 = initialize_optimizer(model)
# 训练模型,传入模型、训练集和验证集的数据加载器、优化器、损失函数、训练轮次和梯度裁剪阈值
# train_model函数负责整个训练过程,包括循环遍历数据、前向传播、计算损失、反向传播和参数更新
train_model(model, train_loader, dev_loader, optimizer, criterion, N_EPOCHS, CLIP)