基础概念
向量
有大小和方向的值
大小(Magnitude):向量的长度或大小,表示向量所代表的量的强度。
方向(Direction):向量所指向的方向,表示量的方向性。
几何表示: 在平面上,向量可以用一个有向线段表示,线段的起点和终点分别代表向量的起始点和终点。 在三维空间中,向量通常用箭头表示,从原点指向某个点。
代数表示: 向量可以用坐标表示。
矩阵
矩阵是一个由数字或其他数学对象排列成的矩形阵列。
矩阵的定义
一个矩阵通常用大写字母表示,例如 矩阵的元素可以是实数、复数或其他数学对象。矩阵的行数和列数决定了它的维度。
维度
数学和理论物理中的概念
维度可以用来描述数据集的特征数。例如,一个包含多个特征的数据集(如机器学习中的样本)可以被视为在高维空间中存在。
特征
特征是数据集中每个样本的一个具体属性,可以是数值型、类别型或其他类型的数据。特征可以是直接从原始数据中提取的,也可以是通过某种转换或组合生成的。
模型介绍
引言
2017年谷歌翻译团队发表论文《Attention Is All You Need》,引发了大家广泛的关注。大家所熟知的GPT也是基于注意力模型的开发的,但它并不仅仅使用了注意力模型,这里不深入讨论。注意力是一个有助于提高神经机器翻译应用性能的概念。今天我们将介绍 Transformer--一种利用注意力提高模型训练速度的模型。它最大的优势来自于 Transformer 可以实现并行化。谷歌云建议将它作为使用其云产品的参考模型。
概括
首先,让我们把模型看作一个单一的黑盒。在机器翻译应用中,它会接收一个句子,并输出译文。
再深入一些,是这样的:一个编码器一个解码器以及数据传递方向
编码部分是一堆编码器,处理输入序列并生成一个上下文相关的编码;
解码组件是一堆相同数字的解码器,根据编码器生成的上下文向量,逐步生成目标序列。
编码器的结构完全相同(但不共享权重)。
每个编码器内部又分为两个子层:
编码器的输入首先进入自我注意层,该层帮助编码器在编码特定单词时查看输入句子中的其他单词。
(后面我们再重点介绍自我注意层)它的输出被送入前馈神经网络
前馈神经网络
输入层:接收输入数据。
隐藏层:一个或多个层,负责处理和学习特征。每个隐藏层由多个神经元(节点)组成。
输出层:生成最终的预测或分类结果
主要用来分类
完全相同的前馈网络被独立应用于每个位置。
解码器拥有这两个层,但在它们之间还有一个注意力层 (在处理输入序列时,模型不需要均匀地关注所有输入,而是可以根据特定的任务或上下文动态地调整关注的重点。这样,模型可以更有效地提取有用的信息)帮助解码器专注于输入句子的相关部分。
引入张量
既然我们已经了解了模型的主要组成部分,那么我们就来看看各种向量/张量,以及它们是如何在这些组成部分之间流动,从而将训练有素的模型输入转化为输出的。
一般自然语言处理都会用嵌入算法将每个输入词转化为向量。
主要用来将复杂无序的数据表示为低维向量
每个单词都被嵌入一个大小为 512 的向量中。我们将用这些简单的方框来表示这些向量。
嵌入只发生在最底层的编码器中。所有编码器都有一个共同的抽象概念,那就是编码器会收到一个向量列表,每个向量的大小为 512,在最底层的编码器中,这个向量就是单词嵌入,而在其他编码器中,这个向量就是正下方编码器的输出。这个列表的大小是我们可以设置的超参数,基本上就是训练数据集中最长句子的长度。
在输入序列中嵌入单词后,每个单词都会分别流经编码器的两个层。
在这里,我们开始看到Transformer的一个关键特性,每个位置上的单词在编码器中都有自己的流动路径。在自注意层中,这些路径之间存在依赖关系。而前馈层不存在这些依赖关系(因为它是一个输入对应一个输出,单向的),因此在流经前馈层时,各个路径可以并行执行,执行速度会比较快。
接下来,我们将把例子换成一个较短的句子,并看看编码器的每个子层都发生了什么。
开始编码
正如我们已经提到的,编码器接收一个向量列表作为输入。它在处理这个列表时,会将这些向量传入一个 “自我注意 ”层,然后再传入一个前馈神经网络,最后将输出向上发送给下一个编码器。
每个位置上的单词都要经过一个自我注意过程。然后,它们分别通过一个前馈神经网络--完全相同的网络,每个矢量分别流经它。
自注意力机制
自注意力这个词是《Attention Is All You Need》一文中提出来的一个比较重要的概念。 简单介绍下,
假设下面这句话是我们要翻译的输入句:
“动物没有过马路,因为它太累了。
这句话中的 “它 ”指的是什么?是指街道还是指动物?这个问题对人类来说很简单,但对算法来说就不那么简单了。
当模型在处理 “它 ”这个词时,自我注意力会让它把 “它 ”和 “动物 ”联系起来。
当模型处理每个单词(输入序列中的每个位置)时,自注意力会让它去查看输入序列中的其他位置,以寻找线索,从而为这个单词进行更好的编码。
注意力就是Transformer用来对其他相关单词的 “理解 ”融入到当前处理的单词中的方法。
5 号编码器中对单词 “it ”进行编码时,注意力机制的一部分正集中在 “The Animal ”上,并将其部分表征嵌入到 “it ”的编码中
自注意力的具体的数学推导这里不详细展开,主要是通过向量矩阵计算出每个值在当前位置的概率分布。
具体公式见下图
如果我们将与自我关注相关的向量和层规范运算可视化,它将看起来像这样:
解码器的里面也是如此。
如果我们把两个叠加的编码器和解码器看成一个Transformer,它看起来会是这样的:
解码器方面
完成编码阶段后,我们开始解码阶段。就像对编码器输入所做的那样,我们在解码器输入中嵌入并添加位置编码,表示每个字的位置。
最终线性层和softmax层
解码器堆栈会输出一个浮点矢量。如何将其转化为单词?这就是最后的线性层的工作,线性层之后是softmax层。
线性层是一个简单的全连接神经网络(处理文本的向量表示),它将解码器堆栈产生的向量投射到一个更大的向量中,这个向量被称为对数向量。
假设我们的模型知道 10,000 个独特的英语单词(我们模型的 “输出词汇”),这些单词是它从训练数据集中学习到的。这样,logits 向量就有 10,000 个单元--每个单元对应一个独特单词的得分。这就是我们在线性层之后对模型输出的解释。
然后,softmax 层会将这些分数转化为概率。概率最高的单元格将被选中,与之相关的单词将作为该步骤的输出结果。
总结
在训练过程中,未经训练的模型会经历完全相同的前向传递过程。但是,由于我们是在有标签的训练数据集上对其进行训练,因此我们可以将其输出与实际的正确输出进行比较。
为了直观地说明这一点,假设我们的输出词汇表只包含六个单词(“a”、“am”、“i”、“thanks”、“student ”和“”(“句末 ”的缩写))。
一旦我们定义了输出词汇,我们就可以使用宽度相同的向量来表示词汇中的每个单词,也就是我们确定每次的输出值。
损失函数
假设我们正在训练模型。假设这是训练阶段的第一步,我们在一个简单的例子上进行训练--将 “merci ”翻译成 “thanks”。
这意味着,我们希望输出是一个表示 “谢谢 ”一词的概率分布。但由于这个模型还没有经过训练,所以现在还不太可能实现。
由于模型的参数(权重)都是随机初始化的,因此(未经训练的)模型会为每个单元格/单词生成一个具有任意值的概率分布。我们可以将其与实际输出进行比较,然后使用反向传播调整模型的所有权重,使输出更接近预期输出。
反向传播(Backpropagation)用于训练神经网络的重要算法。
它的主要作用是通过计算损失函数相对于网络中每个参数的梯度,来调整模型的权重和偏置,从而最小化损失函数
但请注意,这只是一个过于简化的例子。更现实的情况是,我们会使用一个比一个单词更长的句子。例如--输入 je suis étudiant“,预期输出:”我是一名学生": “我是一名学生"。这实际上意味着,我们希望我们的模型能连续输出概率分布,其中:
每个概率分布都由一个宽度为 vocab_size 的向量表示(在我们的玩具示例中为 6,但更现实的数字是 30,000 或 50,000)。 第一个概率分布在与单词 “i ”相关的单元格中概率最高 第二个概率分布在与单词 “am ”相关的单元格中的概率最高 以此类推,直到第五个输出分布显示“<句子结束>”符号,它也与 10,000 个元素词汇表中的一个单元格相关联。
引用: