一、Task1: 前情提要(这一部分很好理解,将教程简要摘录如下)
自然语言处理主要应用于机器翻译、舆情监测、自动摘要、观点提取、文本分类、问题回答、文本语义对比、语音识别、中文OCR等,本期夏令营中搭配的赛题实践是针对机器翻译(Machine Translation,MT)的。
(1)机器翻译的发展历程
① 基于规则的机器翻译(1950s-1980s)
利用语言学家编写的语法规则和词典进行翻译。
这种方法需要对源语言和目标语言的语法和词汇有深入的理解,但其灵活性和适应性较差,难以处理复杂的语言结构和多义词问题。
最严重的缺陷在于其缺乏翻译过程中对上下文信息的建模,这使得基于规则的翻译模型的鲁棒性不佳。
② 基于统计的机器翻译(1990s-2000s)
通过分析大量双语文本,自动学习源语言和目标语言之间的对应关系。
由于其依赖于大量训练数据,对于资源匮乏的语言支持不足。
最主流的方法是基于词的统计机器翻译(Word-based MT)以及基于短语的统计机器翻译(Phrase-based SMT),总体上来看包含预处理、句子对齐、词对齐、短语抽取、短语特征准备、语言模型训练等步骤。
③ 基于神经网络机器翻译(2010s-present)
深度学习技术的快速发展推动了神经网络机器翻译(Neural Machine Translation,NMT)的兴起。
NMT使用深度神经网络模型,如长短期记忆网络(LSTM)和 Transformer,能够自动学习源语言和目标语言之间的复杂映射关系,无需人工设计特征或规则。
NMT在翻译质量、速度和适应性方面取得了显著进步,成为当前机器翻译领域的主流方法。
此次赛题实践便是在这个范畴内的。
④ 未来发展趋势
更加智能化和个性化方向发展。一方面,结合上下文理解、情感分析等技术,提高翻译的准确性和自然度;另一方面,通过用户反馈和个性化学习,提供更加符合用户需求的翻译服务。
(2)机器学习和深度学习项目中的数据集划分
① 训练集(Training Set):
训练模型,使模型能够学习输入数据与输出结果之间的映射关系。
让模型在训练数据上尽可能地拟合好,学习到数据的内在规律。
② 开发集/验证集(Development/Validation Set):
在模型训练过程中调整超参数、选择模型架构以及防止过拟合。
独立于训练集的数据,用于评估模型在未见过的数据上的表现。
选择最佳的模型配置,避免模型在训练集上过度拟合,确保泛化能力。
③ 测试集(Test Set):
最终评估模型性能。
提供一个公正、无偏见的性能估计,反映模型在未知数据上的泛化能力。
(3)赛题:基于术语词典干预的机器翻译挑战赛
在特定领域或行业中,由于机器翻译难以保证术语的一致性,导致翻译效果还不够理想。对于术语名词、人名地名等机器翻译不准确的结果,可以通过术语词典进行纠正,避免了混淆或歧义,最大限度提高翻译质量。
【评估指标】:采用自动评价指标 BLEU-4 进行评价
BLEU,全称为Bilingual Evaluation Understudy(双语评估替换),是一种对生成语句进行评估的指标。
用于衡量计算机生成的翻译与一组参考译文之间的相似度。这个指标特别关注 n-grams(连续的n个词)的精确匹配,可以被认为是对翻译准确性和流利度的一种统计估计。
计算BLEU分数时,首先会统计生成文本中n-grams的频率,然后将这些频率与参考文本中的n-grams进行比较。如果生成的翻译中包含的n-grams与参考译文中出现的相同,则认为是匹配的。最终的BLEU分数是一个介于0到1之间的数值,其中1表示与参考译文完美匹配,而0则表示完全没有匹配。
BLEU-4 特别指的是在计算时考虑四元组(即连续四个词)的匹配情况。
(4)实践
一键跑通baseline代码,稍微扩大使用训练集中的样本数量和训练轮数效果便有提升,体验感不错。
二、Task2:从baseline代码(基于神经网络建模,解决机器翻译问题)详解入门深度学习
基于神经网络解决机器翻译任务的流程如下:
这里主要学习到数据预处理的常见步骤:
-
清洗和规范化数据
-
去除无关信息:删除HTML标签、特殊字符、非文本内容等,确保文本的纯净性(本赛题的训练集中出现了非常多的脏数据,如“Joey. (掌声) (掌声) 乔伊”、“Thank you. (马嘶声) 谢谢你们”等这种声音词)
-
统一格式:转换所有文本为小写,确保一致性;标准化日期、数字等格式。
-
分句和分段:将长文本分割成句子或段落,便于处理和训练。
-
-
分词
-
分词:将句子分解成单词或词素(构成单词的基本组成部分,一个词素可以是一个完整的单词,也可以是单词的一部分,但每一个词素都至少携带一部分语义或语法信息),这是NLP中最基本的步骤之一。我们这里使用了使用
jieba
对中文进行分词,使用spaCy
对英文进行分词。
-
-
构建词汇表和词向量
-
词汇表构建:从训练数据中收集所有出现过的词汇,构建词汇表,并为每个词分配一个唯一的索引。
-
词向量:使用预训练的词向量或自己训练词向量,将词汇表中的词映射到高维空间中的向量,以捕捉语义信息(当前大模型领域训练的 embedding 模型就是用来完成此任务的)。
-
-
序列截断和填充
-
序列截断:限制输入序列的长度,过长的序列可能增加计算成本,同时也可能包含冗余信息。
-
序列填充:将所有序列填充至相同的长度,便于批量处理。通常使用
<PAD>
标记填充。
-
-
添加特殊标记
-
序列开始和结束标记:在序列两端添加
<SOS>
(Sequence Start)和<EOS>
(Sequence End)标记,帮助模型识别序列的起始和结束。 -
未知词标记:为不在词汇表中的词添加
<UNK>
(Unknown)标记,使模型能够处理未见过的词汇。
-
-
数据增强
-
随机替换或删除词:在训练数据中随机替换或删除一些词,增强模型的鲁棒性。
-
同义词替换:使用同义词替换原文中的词,增加训练数据的多样性。
-
-
数据分割
-
划分数据集:将数据划分为训练集、验证集和测试集,分别用于模型训练、参数调整和最终性能评估(该赛题中已划分好,不需要自己进行划分)
-
(1)编码器-解码器模型的神经机器翻译
在源语言句子的表示形式确定之后,需要设计相应的编码器和解码器结构。在当今主流的神经机器翻译系统中,编码器由词嵌入层和中间网络层组成:
-
当输入一串单词序列时,词嵌入层(embedding)会将每个单词映射到多维实数表示空间,这个过程也被称为词嵌入。
-
之后中间层会对词嵌入向量进行更深层的抽象,得到输入单词序列的中间表示。中间层的实现方式有很多,比如:循环神经网络、卷积神经网络、自注意力机制等都是模型常用的结构。
解码器的结构基本上和编码器是一致的,在基于循环神经网络的翻译模型中,解码器只比编码器多了输出层,用于输出每个目标语言位置的单词生成概率,而在基于自注意力机制的翻译模型中,除了输出层,解码器还比编码器多一个编码解码注意力子层,用于帮助模型更好地利用源语言信息。
(2)基于循环神经网络的机器翻译模型
左侧为编码器部分,源语言单词按照其在文本序列中的先后顺序被依次送入到循环神经网络(RNN)当中。在每个时间步 t 中,模型依据送入的源语言单词对应修改并维护其模型内部的隐状态
,这个隐状态编码了输入的源语言序列前 t 个时刻的所有必要信息。按照这种方式当 m 个输入全部被送入到编码器之后,所对应的
可以认为包含了源语言序列的所有信息。
右侧为解码器部分,它接收编码器输出的编码源语言句子信息的向量 作为初始隐状态
。由于 RNN 的循环过程在每个时间步都要求一个输入单词,为了启动解码过程,一般会使用一个保留的特殊符号 “[Start]” 作为翻译开始的标记送入到 RNN 解码器当中并解码出目标语言序列的第一个单词
。由于目标语言序列的长度无法被提前预知,因此使用另一个保留符号 “[Stop]” 作为预测结束的标志。当某一个时刻 t 预测出的目标语言单词为
=“[Stop]” 时,解码过程动态地停止。在上述过程当中,主要涉及到两步运算,第一步是 RNN 接收前一时刻隐状态
并依据当前时刻输入
(目标语言单词
对应的语义嵌入)对隐状态进行维护并生成
的运算过程,第二步是依据当前时刻隐状态生成目标语言单词的过程:
其中 U,W,V 是可学习的参数。U,W 负责维护循环状态,而 V 负责将当前时刻状态转换到词表大小的概率分布 P∈,从中可以采样得到目标语言单词
。
通过循环网络对源语言文本进行编码,它仅仅使用一个定长的向量 编码整个源语言序列。这对于较短的源语言文本没有什么问题,但随着文本序列长度的逐渐加长,单一的一个向量
可能不足以承载源语言序列当中的所有信息。
(3)引入注意力机制的循环神经网络机器翻译框架
注意力机制的引入使得不再需要把原始文本中的所有必要信息压缩到一个向量当,具体来说,给定源语言序列经过编码器输出的向量序列 ,
,
,...,
,注意力机制旨在依据解码端翻译的需要,自适应地从这个向量序列中查找对应的信息。
(4)baseline代码中实现了一个经典的序列到序列(Seq2Seq)模型,中间层使用GRU网络,并且在网络中加入了注意力机制(Attention Mechanism)
Seq2Seq(Sequence to Sequence,序列到序列模型) 是一种循环神经网络的变种,包括编码器 (Encoder) 和解码器 (Decoder) 两部分。
门控循环单元(gated recurrent unit,GRU),与普通的循环神经网络之间的关键区别在于: 前者支持隐状态的门控。 这意味着模型有专门的机制来确定应该何时更新隐状态, 以及应该何时重置隐状态。 例如,如果第一个词元非常重要, 模型将学会在第一次观测之后不更新隐状态。 同样,模型也可以学会跳过不相关的临时观测。 最后,模型还将学会在需要的时候重置隐状态。
门控循环单元具有以下两个显著特征:
-
重置门有助于捕获序列中的短期依赖关系;
-
更新门有助于捕获序列中的长期依赖关系。
(5)实践
跟着教程,在魔搭上配好环境,跑代码,每次开始都需要重新pip install,费时间,而且跑了太长时间会自动中断,导致前面全白费,我好奇有没有什么可以接着上次继续训练的方法。这一部分因为训练集中选用的样本数量和训练轮数的设置问题导致不是训练不够就是耗时太久崩掉,结果均不理想。
三、Task3:基于Transformer解决机器翻译任务
(1)Transformer
基于循环或卷积神经网络的序列到序列建模方法是现存机器翻译任务中的经典方法。然而,它们在建模文本长程依赖方面都存在一定的局限性。
Transformer 在原论文中第一次提出就是将其应用到机器翻译领域,它的出现使得机器翻译的性能和效率迈向了一个新的阶段。它摒弃了循环结构,并完全通过注意力机制完成对源语言序列和目标语言序列全局依赖的建模。在抽取每个单词的上下文特征时,Transformer 通过自注意力机制(self-attention)衡量上下文中每一个单词对当前单词的重要程度。
在这个过程当中没有任何的循环单元参与计算。这种高度可并行化的编码过程使得模型的运行变得十分高效。当前几乎大部分的大语言模型都是基于 Transformer 结构。
Transformer的主要组件包括编码器(Encoder)、解码器(Decoder)和注意力层。其核心是利用多头自注意力机制(Multi-Head Self-Attention),使每个位置的表示不仅依赖于当前位置,还能够直接获取其他位置的表示。自从提出以来,Transformer模型在机器翻译、文本生成等自然语言处理任务中均取得了突破性进展,成为NLP领域新的主流模型。
Transformer 模型的基本架构:
① 嵌入表示层
对于输入文本序列,先通过一个输入嵌入层(Input Embedding)将每个单词转换为其相对应的向量表示。由于 Transfomer 模型不再使用基于循环的方式建模文本输入,序列中不再有任何信息能够提示模型单词之间的相对位置关系。在送入编码器端建模其上下文语义之前,一个非常重要的操作是在词嵌入中加入位置编码(Positional Encoding)这一特征。具体来说,序列中每一个单词所在的位置都对应一个向量。这一向量会与单词表示对应相加并送入到后续模块中做进一步处理。在训练的过程当中,模型会自动地学习到如何利用这部分位置信息。为了得到不同位置对应的编码,Transformer 模型使用不同频率的正余弦函数如下所示:
其中,pos表示单词所在的位置,2i 和 2i+1 表示位置编码向量中的对应维度,d则对应位置编码的总维度。
通过上面这种方式计算位置编码有这样几个好处:
-
首先,正余弦函数的范围是在 [-1,+1],导出的位置编码与原词嵌入相加不会使得结果偏离过远而破坏原有单词的语义信息。
-
其次,依据三角函数的基本性质,可以得知第pos+k 个位置的编码是第 pos 个位置的编码的线性组合,这就意味着位置编码中蕴含着单词之间的距离信息。
② 注意力层
自注意力(Self-Attention)操作是基于 Transformer 的机器翻译模型的基本操作,在源语言的编码和目标语言的生成中频繁地被使用以建模源语言、目标语言任意两个单词之间的依赖关系。给定由单词语义嵌入及其位置编码叠加得到的输入表示,为了实现对上下文语义依赖的建模,进一步引入在自注意力机制中涉及到的三个元素:查询 (Query),键
(Key),值
(Value)。在编码输入序列中每一个单词的表示的过程中,这三个元素用于计算上下文单词所对应的权重得分。直观地说,这些权重反映了在编码当前单词的表示时,对于上下文不同部分所需要的关注程度。
③ 前馈层
前馈层接受自注意力子层的输出作为输入,并通过一个带有 Relu 激活函数的两层全连接网络对输入进行更加复杂的非线性变换。实验证明,这一非线性变换会对模型最终的性能产生十分重要的影响。
④ 残差连接与层归一化
由 Transformer 结构组成的网络结构通常都是非常庞大。编码器和解码器均由很多层基本的Transformer 块组成,每一层当中都包含复杂的非线性映射,这就导致模型的训练比较困难。因此,研究者们在 Transformer 块中进一步引入了残差连接与层归一化技术以进一步提升训练的稳定性。具体来说,残差连接主要是指使用一条直连通道直接将对应子层的输入连接到输出上去,从而避免由于网络过深在优化过程中潜在的梯度消失问题,此外,为了进一步使得每一层的输入输出范围稳定在一个合理的范围内,层归一化技术被进一步引入到每个 Transformer 块中,层归一化技术可以有效地缓解优化过程中潜在的不稳定、收敛速度慢等问题。
⑤ 编码器和解码器结构
根据给出的网络架构,编码器端可以较为容易实现。但相比于编码器端,解码器端要更复杂一些。具体来说,解码器的每个 Transformer 块的第一个自注意力子层额外增加了注意力掩码,对应图中的掩码多头注意力(Masked Multi-Head Attention)部分。这主要是因为在翻译的过程中,编码器端主要用于编码源语言序列的信息,而这个序列是完全已知的,因而编码器仅需要考虑如何融合上下文语义信息即可。而解码端则负责生成目标语言序列,这一生成过程是自回归的,即对于每一个单词的生成过程,仅有当前单词之前的目标语言序列是可以被观测的,因此这一额外增加的掩码是用来掩盖后续的文本信息,以防模型在训练阶段直接看到后续的文本序列进而无法得到有效地训练。
此外,解码器端还额外增加了一个多头注意力(Multi-Head Attention)模块,使用交叉注意力(Cross-attention)方法,同时接收来自编码器端的输出以及当前 Transformer 块的前一个掩码注意力层的输出。查询是通过解码器前一层的输出进行投影的,而键和值是使用编码器的输出进行投影的。它的作用是在翻译的过程当中,为了生成合理的目标语言序列需要观测待翻译的源语言序列是什么。基于上述的编码器和解码器结构,待翻译的源语言文本,先经过编码器端的每个Transformer 块对其上下文语义的层层抽象,然后输出每一个源语言单词上下文相关的表示。解码器端以自回归的方式生成目标语言文本,即在每个时间步 t ,根据编码器端输出的源语言文本表示,以及前 t-1 个时刻生成的目标语言文本,生成当前时刻的目标语言单词。
(2)上分技巧
-
最简单的就是调参,将 epochs 调大一点,使用全部训练集,以及调整模型的参数,如head、layers等。如果数据量允许,增加模型的深度(更多的编码器/解码器层)或宽度(更大的隐藏层尺寸),这通常可以提高模型的表达能力和翻译质量,尤其是在处理复杂或专业内容时。
-
加入术语词典,这是在此竞赛中比较有效的方法,加入术语词典的方法策略也有很多,如:
-
在模型生成的翻译输出中替换术语,这是最简单的方法
-
整合到数据预处理流程,确保它们在翻译中保持一致
-
在模型内部动态地调整术语的嵌入,这涉及到在模型中加入一个额外的层,该层负责查找术语词典中的术语,并为其生成专门的嵌入向量,然后将这些向量与常规的词嵌入结合使用
-
-
认真做数据清洗,我们在 Task2 已经提到过当前训练集存在脏数据的问题,会影响我们的模型训练
-
数据扩增:
-
回译(back-translation):将源语言文本先翻译成目标语言,再将目标语言文本翻译回源语言,生成的新文本作为额外的训练数据
-
同义词替换:随机选择句子中的词,并用其同义词替换
-
使用句法分析和语义解析技术重新表述句子,保持原意不变
-
将文本翻译成多种语言后再翻译回原语言,以获得多样化翻译
-
-
采用更精细的学习率调度策略(baseline我们使用的是固定学习率):
-
Noam Scheduler:结合了warmup(预热)阶段和衰减阶段
-
Step Decay:最简单的一种学习率衰减策略,每隔一定数量的epoch,学习率按固定比例衰减
-
Cosine Annealing:学习率随周期性变化,通常从初始值下降到接近零,然后再逐渐上升
-
-
自己训练一个小的预训练模型,尽量选择 1B 以下小模型,对 GPU 资源要求比较高,仅仅使用魔搭平台可能就满足不了
-
将训练集上训练出来的模型拿到开发集(dev dataset)上 finetune 可以提高测试集(test dataset)的得分,因为开发集与测试集的分布比较相近
-
在开发集和测试集上训一个语言模型,用这个语言模型给训练集中的句子打分,选出一些高分句子
-
集成学习:训练多个不同初始化或架构的模型,并使用集成方法(如投票或平均)来产生最终翻译。这可以减少单一模型的过拟合风险,提高翻译的稳定性。
(3)实践
只做了简单的调参、数据清洗和加入术语词典,后续再尝试。
四、总结
感谢Datawhale AI 夏令营,给了我学习的契机与丰富的资源,这几天学到了一些基本的nlp知识与概念,对机器学习与深度学习有了粗糙的了解,还实践了一番,虽然有些地方还是不太清楚具体怎么做,但亲手实操总归有点落在实处的感觉,后续会继续深入的学习的,本笔记主要是基于Datawhale AI 夏令营提供的教程的学习记录,再次感谢!