transformer编码器前置和后置
时间: 2025-01-14 20:14:20 浏览: 40
### Transformer编码器前置与后置操作区别
在Transformer架构中,层规范化的位置可以位于子层之前(前置)或之后(后置)。这两种方法的主要差异在于数据流经网络的方式以及如何应用规范化。
#### 后置层规范化
当采用后置层规范化时,在完成自注意力机制或多头注意力计算并加上前馈神经网络的操作之后再执行层规范化。这意味着先让信息通过整个编码单元,然后再对其进行标准化处理[^1]。具体来说:
- 数据经过多头自注意机制;
- 添加残差连接至原始输入;
- 应用第一个层规范化;
- 输入到前馈全连接层;
- 又一次添加残差连接;
- 进行第二次层规范化作为该层的最终输出。
这种方式有助于稳定训练过程中的梯度传播,并且保持每一层激活值分布的一致性。
#### 前置层规范化
对于前置层规范化,则是在任何其他运算发生之前立即对输入特征进行标准化。因此,在每次进入新的子层之前都会先调用LayerNorm函数来调整张量特性[^2]。流程如下所示:
- 对即将送入自注意力模块的数据实施层规范化;
- 执行多头自注意机制;
- 经过线性变换和非线性激活组成的两层感知机结构;
- 输出端同样存在一条未被修改过的捷径用于构建残差链接;
这种方法理论上可以使优化更加平滑,因为每一步都基于已经正则化的信号工作,减少了内部协变量偏移的影响。
```python
class EncoderLayer(nn.Module):
def __init__(self, d_model, num_heads, ff_dim, dropout_rate=0.1):
super().__init__()
self.layernorm1 = nn.LayerNorm(d_model)
self.mha = MultiHeadAttention(num_heads=num_heads, key_dim=d_model)
self.dropout1 = nn.Dropout(dropout_rate)
self.layernorm2 = nn.LayerNorm(d_model)
self.ffn = FeedForwardNetwork(ff_dim, d_model)
self.dropout2 = nn.Dropout(dropout_rate)
def forward(self, inputs):
# Post-LN (After each sub-layer)
attn_output = self.mha(inputs, inputs, inputs)
out1 = self.layernorm1(inputs + self.dropout1(attn_output))
ffn_output = self.ffn(out1)
output = self.layernorm2(out1 + self.dropout2(ffn_output))
return output
def pre_forward(self, inputs):
# Pre-LN (Before each sub-layer)
normed_inputs = self.layernorm1(inputs)
attn_output = self.mha(normed_inputs, normed_inputs, normed_inputs)
out1 = inputs + self.dropout1(attn_output)
normed_out1 = self.layernorm2(out1)
ffn_output = self.ffn(normed_out1)
output = out1 + self.dropout2(ffn_output)
return output
```
阅读全文
相关推荐

















