深度学习进阶(三)Transformer Block
先简单概括一下 Transformer Block 的整体传播如下:
接下来我们逐步拆解这个过程。
1.位置编码(Positional Encoding, PE)#
在开始 Transformer Block 之前,首先要说明的是它的输入细节。
在前面的自注意力机制中,我们了解了自注意力相对 RNN 实现了信息关联间的全局建模、并行建模。
但实际上,其并非十全十美,一个关键的问题在于:自注意力本身并不能隐式建模序列的顺序信息。
回想 RNN ,它的计算是按时间步递归的:
关键点在于信息是按时间顺序一层层传递的,这意味着输入顺序不能打乱,也就是说模型本身就“知道”谁在前、谁在后,顺序是通过计算路径自然体现的。
而Transformer 的 Attention 是这样的:
所有 token 同时参与计算,没有“先后处理顺序”的结构约束。
也就是说,在原始的词嵌入逻辑中,我们虽然可以通过注意力计算得到 token 间的相关性,但这个相关性里是不包括顺序成分的。
除非我们想办法把一个序列中的顺序信息也加入每个 token 的词向量中。
这就是位置编码的由来。
于是,Transformer 原论文提出了一种位置编码机制,将位置信息显式注入到输入表示中。
其具体做法是:对每个 token 的词向量 ,加入一个与其位置相关的向量 ,从而得到最终输入表示:
其中 即为位置编码。
原文中设计了一种基于正弦和余弦函数的固定位置编码方法如下:
对于位置 和维度索引 ,其定义如下:
其中:
- 表示 token 在序列中的位置(从 0 开始)。
- 表示 embedding 的维度。
- 表示维度索引。
公式看起来略显复杂,我们举个例子,假定信息如下:
- 序列:我 / 爱 / 你
- 位置:
- 维度:
注意,实际实现中词向量维度通常为偶数,这里简化来演示,计算过程如下:
| 位置 pos | token | 维度 | 计算公式 | 数值 |
|---|---|---|---|---|
| 0 | 我 | PE₀ | ||
| 0 | 我 | PE₁ | ||
| 0 | 我 | PE₂ | ||
| 1 | 爱 | PE₀ | ||
| 1 | 爱 | PE₁ | ||
| 1 | 爱 | PE₂ | ||
| 2 | 你 | PE₀ | ||
| 2 | 你 | PE₁ | ||
| 2 | 你 | PE₂ |
最终得到三个 token 的 PE :
现在,我们再来理解一下这种设计思路,这其实涉及一些信号处理的知识:
从本质上看,正弦和余弦函数可以被视为一种周期信号。当我们用不同频率的正弦/余弦函数去对同一个位置进行编码时,相当于在多个“频率通道”上对该位置进行投影。
而不同频率就是通过指数缩放项 来实现的,而同时使用正弦和余弦也能避免不同的频率可能得到相同的值的情况。
而且,不同位置之间的“距离信息”,可以在这些周期函数的相位差中体现出来。 这样,位置之间的相对关系就可以被隐式表达。
编辑
通过 PE 的设计,我们就完善了对输入数据的顺序信息的建模。
在更近的研究中,对 PE 的获取方法也在不断地创新发展,一个很容易想到的方向就是可学习位置编码,我们之后再详细展开。
2. Attention 块#
2.1 多头自注意力子层#
对于经过嵌入层、注入 PE 后的序列信息 (向量化),它在 Transformer Block 中的第一步就是应用多头注意力机制进行信息增强。
这一部分我们已经详细展开过,其作用是:在序列内部建模任意位置之间的依赖关系,实现全局信息交互。
本次的输入与输出保持维度一致,如下:
这种设计方便了下面的残差学习。
2.2 残差连接#
Attention 块到这里并没有结束,Transformer Block 在每个子层还增加了残差连接和归一化的步骤。
展开来说,首先对于注意力子层的输出 ,我们直接把它和输入 相加:
这涉及到残差学习的基本原理,我们在很早之前有所介绍:残差网络
再简单概述一下:我们知道 是由可学习的参数决定的,而这种对输出的建模方式会让学习目标从 “直接学习从输入到输出的映射” 转变为 “学习在输入基础上的改变量”,从而改善梯度现象,支撑更深层的网络。
2.3 LayerNorm#
然后,下一步处理就是归一化:
同样在前面的吴恩达深度学习内容中,我们介绍过归一化的基本内容,并在此基础上拓展了Batch Norm。
而这里的 LayerNorm 和 Batch Norm 其实只是数据的选择方向不同。
公式如下:
其中:
- 是均值
- 是标准差
- 为可学习参数
显然,不同于 Batch Norm 对一批次样本的逐个特征做归一化,LayerNorm 是对每个样本自身的所有特征做归一化。
来简单举个例子:
假设我们有如下特征向量(设 ):
计算均值和标准差如下:
代入计算:
现在,该向量均值为 ,方差为 。
接下来再通过学习平移和缩放参数 :
这一步的作用是:在完成标准化之后,让模型再特化学习“什么样的分布是最合适的”。
可以这样理解 LayerNorm 的作用: 它可以保持特征的相对结构,同时将整体数值尺度归一到稳定范围。
这样做使得每一个 token 的表示都被拉回到一个稳定的数值范围,从而避免在深层网络中出现数值分布不断偏移的问题。
你可能还有这样一个问题:
更多推荐

所有评论(0)