参考:全面解析:从AI原理到模型演进及代码实践-CSDN博客
训练过程
Transformer仅一个Encoder模块就可以工作,可以处理信息抽取、识别、主体识别等任务,比如 BERT(Bidirectional Encoder Representations from Transformers)是只使用了Encoder,可以从给定的文本段落中找到并提取出回答问题的文本片段,目标是识别或检索信息,而不是生成新的文本序列。
实际上,只通过Encoder直接连接一个全连接层去求 f(x) 也不是不可以,但不连接其他模块性能会差很多,同时也没有办法实现并行训练(Teacher Forcing方式),所以又设计了Decoder模块,这两种模块的组合可以实现下面的场景:
-
文本分类(仅使用Encoder模块),label=f(tokens)
-
下一个token预测(仅使用Decoder模块),next_token=f(token)。比如给定一些词,做出下一个词的预测,而且是逐字向后推测
-
文本翻译(Encoder+Decoder模块),中文=f(英文)
下面从观察训练过程了解Decoder的构成。
整个训练过程还是求,即输入"LL、M、with、ban、z、ang"(此时的输入相比Encoder已经包含了token之间的相互关注信息),调整参数计算出结果和"大模型、与、半臧"比较,loss收敛后结束。
第一个是在训练时词序引入了,翻译是以“大”、“大模型”、“大模型与”、“大模型与半臧”这样的顺序进行输出的,这样token之间的注意力加上词序的训练,在翻译(预测)场景会更贴合上下文场景,变得准确。
但是在技术上,引入词序会导致训练任务必须得到前一个任务的输出结果做输入进行串行,无法并行执行,所以transformer引入mask来解决这个问题,具体是把本来串行的任务,通过直接将完整的预期结果按词序做了mask覆盖,分成多个可以并行执行的任务。
mask的主要实现就是对样本输入做了右上三角形的掩码(覆盖了一个非常小的数,可以让softmax归一后趋0),在做Decoder的QKV的时候忽略了。
任务并行后,同时任务也变成了“Teacher Forcing”方式,可以让loss收敛更快。
在机器学习和深度学习领域,“loss收敛”是指损失函数(loss function)的值随着训练过程的进行逐渐减少并趋于稳定。损失函数是用来量化模型预测值与真实目标值之间差异的一个指标,训练模型的目标通常是最小化这个损失函数。
收敛的过程
- 初始阶段:刚开始训练时,由于模型参数是随机初始化的,所以模型对数据的预测能力较差,损失值通常较高。
- 下降阶段:通过反向传播算法调整模型参数,使得每次迭代后损失函数的值逐渐减小。
- 接近最小值:随着训练的深入,损失函数的值越来越接近一个最小值(局部或全局)。当损失值的变化幅度变得非常小,几乎不再变化时,我们说模型达到了收敛状态。
- 收敛状态:在理想情况下,这意味着模型已经学到了从输入到输出的最佳映射关系。然而,在实践中,完全达到理论上的最小值往往难以实现,更多的是找到一个足够好的近似解。
影响收敛的因素
- 学习率:过高的学习率可能导致模型无法稳定地收敛;而过低的学习率则可能使训练过程极其缓慢。
- 优化器的选择:不同的优化器(如SGD、Adam等)对于不同问题可能有不同的表现,选择合适的优化器可以加速收敛。
- 正则化技术:L1/L2正则化、dropout等技术可以帮助防止过拟合,从而影响模型的收敛性。
- 数据质量与数量:高质量且充足的数据有助于模型更准确地学习到数据中的模式,促进收敛。
确保模型正确收敛是训练过程中的关键步骤之一,它直接关系到最终模型性能的好坏。如果模型没有很好地收敛,可能需要调整上述提到的一些参数或策略。
Teacher Forcing是一种在训练序列模型(如循环神经网络RNN、长短时记忆网络LSTM或Transformer等)时使用的技术。它的主要目的是加速模型的训练过程并提高模型的稳定性。
基本概念
在序列预测任务中,模型的目标是基于输入序列生成一个输出序列。例如,在语言翻译任务中,输入是一段源语言句子,而输出是对应的目标语言句子。在训练过程中,通常的做法是让模型在每一步都预测下一个词,并使用真实的目标序列中的实际词作为下一步的输入。这就是所谓的Teacher Forcing。
具体来说,在没有使用Teacher Forcing的情况下,模型会使用其上一步预测出的词作为下一步的输入。而在使用Teacher Forcing时,无论模型上一步预测的结果是什么,都会将正确答案(即训练数据中的实际目标词)作为下一步的输入给到模型。这样做的好处是可以使得训练过程更加稳定,因为模型每次都能接收到正确的输入信息,从而有助于更快地学习到正确的模式。
优点与缺点
优点:
- 加速收敛:由于模型总是接收正确的前序输入,因此可以更快速地学习到正确的输出。
- 提升稳定性:减少因错误累积导致的偏差,尤其是在早期训练阶段,这有助于提高训练过程的稳定性。
缺点:
- 暴露偏差(Exposure Bias):在训练期间,模型习惯于依赖真实的前序单词,但在推理(inference)阶段,它必须基于自己之前的预测进行操作。这种差异可能导致模型在处理未见过的数据时表现不佳。
- 缺乏鲁棒性:长期依赖Teacher Forcing可能会使模型变得不够健壮,因为它没有机会学会如何从自身的错误中恢复。
为了解决这些问题,一些方法如Scheduled Sampling被提出,这种方法在训练过程中逐步减少Teacher Forcing的比例,使得模型能够逐渐适应在推理时遇到的情况。通过这种方式,可以在一定程度上缓解暴露偏差的问题,同时保留Teacher Forcing带来的训练效率和稳定性的优势。
RNN中的Teacher Forcing
在RNN中,如果没有Teacher Forcing,模型会基于它之前预测出的词来预测下一个词。这意味着如果模型在一个时间步骤上做出了错误的预测,这个错误可能会“传播”到后续的时间步骤,导致误差累积,使得loss难以收敛。例如,在你的例子中,“大”->["模型"(90%)、“小”(4%)],如果模型错误地选择了“小”,那么接下来的预测可能会越来越偏离正确路径。
- 采用Teacher Forcing后,即使模型预测出了“小”,在下一个时间步骤中,我们仍然给模型提供正确的词(即应该跟随“大”的那个正确词),这样可以避免因为早期的错误预测而导致后续预测完全偏离轨道的问题。
Transformer中的Teacher Forcing
虽然Transformer架构不同于RNN系列模型(因为它不依赖于序列顺序进行计算,允许并行化处理),但在训练阶段,Teacher Forcing的概念同样适用。
- 在训练过程中,尽管Transformer能够并行处理整个token序列,但为了模拟推理时的情况(即每次只能根据已有的信息预测下一个词),我们会对每个位置的token进行mask操作,隐藏未来的信息。这确保了模型在训练期间只基于前面的上下文进行预测。
- Teacher Forcing在Transformer中的应用就是在这个masked自注意力机制的基础上,对于每个位置,除了使用真实的前序tokens作为输入外,还直接使用目标序列中的实际token来预测当前位置的输出。这与RNN中Teacher Forcing的思想是一致的:即在训练时总是提供正确的前序信息,以帮助模型学习更准确的表示。
在transformer中,完整token序列参与训练,但屏蔽每个token后面信息,形成可并行执行任务,每个token序列推测过程无视其他任务推测结果,采用训练样本值进行前序context推测下个token。
另外一个特别点是Decoder含有两层注意力,第一层是和Encoder一样的实现(自注意力),接受来自训练文本的真实输出,形成token的相互关注信息,第二层注意力QKV中Q来自上一个Decoder,KV并非由上一层Decoder结果计算来的,而是来自Encoder的KV结果(非同源,非自注意力),这样的设计是将来自Encoder的训练文本输入和训练真实输出(按词序mask)的相互关注都整合在一起预测被mask的值。
论文中Encoder和Decoder是可以堆叠的,即输入通过堆叠n层Encoder(论文中使用了2/4/6/8层,只有6层效果最好,但实际在只有一行训练样本场景下,n_layers=1是效果最好的)处理后在传递到n层Deocder继续处理,同时每层Deocder的KV都来自最后一层的Encoder的输出。
深度学习模型中Encoder-Decoder架构的一种实现方式,特别是在处理序列到序列(sequence-to-sequence, seq2seq)任务时。这种架构通常用于自然语言处理任务,比如机器翻译、文本摘要等。下面是对这段话的详细解释:
Encoder-Decoder架构
-
Encoder:输入序列通过堆叠的多层Encoder进行编码。每层Encoder都会对输入数据进行抽象和转换,捕捉输入的不同层次的特征表示。在你的例子中,论文尝试了不同层数的Encoder(2层、4层、6层、8层),发现6层的效果最佳。
-
Decoder:编码后的信息被传递给Decoder,Decoder同样由若干层组成(n层)。Decoder的任务是基于Encoder生成的高级特征表示来生成目标序列。
关键点解析
-
堆叠的层数(n_layers):
- 在实验中,不同的Encoder和Decoder层数(如2层、4层、6层、8层)被用来测试效果。结果显示,在一般情况下,使用6层Encoder和Decoder的模型表现最好。然而,在特定场景下(例如只有一行训练样本的情况下),仅使用单层(n_layers=1)的模型反而效果最佳。这表明模型复杂度需要根据具体应用场景和数据集大小进行调整。
-
KV来自最后一层Encoder:
- 在Decoder中,每一层都会使用“K(Key)”和“V(Value)”这两个概念,它们是从Encoder的最后一层输出得到的。这是指在注意力机制(Attention Mechanism)中,Decoder会参考Encoder最后一层产生的隐藏状态来计算注意力权重。这样做可以让Decoder更好地关注到输入序列中的重要部分,从而生成更准确的输出序列。
-
应用情景考虑:
- 当处理的数据集非常简单或规模很小时(如只有一个训练样本的情况),过于复杂的模型可能会导致过拟合。因此,在这样的场景下,简化模型(例如减少为单层)可以避免模型过度学习训练数据的细节,提高泛化能力。
整个训练过程如下:
1. 训练文本(输入/输出)['LLM with banzang', '大模型和半臧']的输入['LLM with banzang']进行分词和embedding
2. Encoder计算训练文本输入X的Self-AttentionScore,形成输入X的token间关注信息带入Decoder
3. 训练文本(输入/输出)['LLM with banzang', '大模型和半臧']的输出['大模型和半臧']进行分词和embedding
4. 第一层Decoder对训练文本输出X'进行右上三角形MASK遮盖操作后进行Self-AttentionScore,形成输出X'从左往右词序的token间关注信息(即只能了解过去信息,无法提前知道未来词序,因为要预测),事实上形成了训练输出长度为m()的并行任务
5. 第二层Decoder将第一层Deocder输出的结果做为输入Q,使用Encoder的KV参数,拼接训练输入和输出再次做AttentionScore
6. 预测下一个结果和训练输出对比后,反向传播调整各层参数,直到Loss收敛到预期结果。
小结一下流程:
预测过程
相比训练过程,切换到预测模式后,原本训练的并行输入由最后一个Decoder输出取代,然后开始串行循环,直至<EOS>标记结束。就和RNN一样,逐一预测到底,例如:
LL -> LLM
LLM -> LLM with
LLM with -> LLM with ban
LLM with ban -> LLM with banz
LLM with banz -> LLM with banzang
实际上预测下一个token是按照softmax后概率挑选的,在串行循环时,选取不同概率的词会形成不同的预测分支,例如:
预测结果因概率挑选以及前馈层的非线性激活函数,将整个预测变的更加丰富,有点像基因突变,可能未来会产生艺术创造的价值,当前基于transfomer的各个模型都有会有多个预测输出分支待采用。
输出的处理
当输入X被Encoder和Decoder*2处理完后,形成token_size*embedding_size大小的矩阵,每行代表着一个token,每列是这个token在不同维度的某个magic number,最后再经过一个全连接层(Linear Layer)
对输入矩阵做线形变化成token_size*logits_size,同时引入训练参数做拟合,再经过一个softmax归一,拟合每个token在字典表中最高概率的index,拿index还原最终token。
在深度学习中,线性层(Linear Layer),也常被称为全连接层(Fully Connected Layer)或密集层(Dense Layer),是神经网络的基本构建块之一。线性层对输入数据执行线性变换,其操作可以简单理解为矩阵乘法加上一个偏置项。
线性层的工作原理
给定一个输入向量 x,线性层通过以下公式计算输出:y=Wx+b
其中:
W 是权重矩阵,
x 是输入向量,
b 是偏置向量,
y 是输出向量。
特点与用途
线性变换:线性层的主要作用是对输入进行线性组合,它不改变输入的维度结构,但可以通过调整权重和偏置来学习输入数据中的模式。
特征映射:在线性层中,每个输出神经元都连接到所有输入神经元,这种全连接方式允许模型学习输入之间的复杂关系,并将这些关系映射到新的特征空间中。
灵活性:线性层通常与其他类型的层(如卷积层、循环层等)结合使用,以构建更复杂的模型。例如,在卷积神经网络(CNN)中,线性层经常被用作最后几层,用于将卷积层提取的特征映射到分类器或回归器的输出上。
激活函数:单独的线性层只能表示线性关系,因此通常会在其后添加非线性激活函数(如ReLU、Sigmoid、Tanh等),使得整个模型能够学习到输入数据中的非线性模式。
应用场景
分类任务:在图像分类、文本分类等任务中,线性层常用于网络的最后一层,用来产生最终的分类得分。
回归任务:在预测连续值的任务中,线性层可以直接输出预测结果。
序列建模:虽然RNN、LSTM、GRU等更适合处理序列数据,但在某些情况下,线性层也可用于处理序列数据的特定部分,比如在Transformer架构中,线性层用于计算注意力权重。
总之,线性层是一个非常基础且重要的组件,几乎所有的深度学习模型都会包含至少一层线性层。它们对于将高维数据映射到低维空间或者相反的过程特别有用。
至此Transformer整个工作流程全部结束