定义一个 TransformerEncoder 类,它是一个标准的 Transformer 编码器的实现,通常用于自然语言处理(NLP)任务中。Transformer 是由 Vaswani 等人提出的模型,广泛用于许多序列到序列的任务,如机器翻译、文本生成、图像处理等:
1. 类说明
TransformerEncoder
是一个 nn.Module
的子类,表示 Transformer 的编码器部分。它由多个 TransformerEncoderLayer 组成,每个 EncoderLayer 都包括多头自注意力(Multi-Head Self-Attention)和前馈神经网络(Feed-Forward Network)。
2. 初始化方法 (__init__
)
def __init__(self, embed_dim, num_heads, layers, attn_dropout=0.0, relu_dropout=0.0, res_dropout=0.0,
embed_dropout=0.0, attn_mask=False):
参数:
embed_dim
:表示输入嵌入的维度(例如每个 token 的向量表示的维度)。num_heads
:多头自注意力机制中的头数,即MultiHeadAttention
中的注意力头数。layers
:Transformer 编码器层的数量。attn_dropout
:应用于注意力权重的 dropout 比例。relu_dropout
:应用于前馈网络的 ReLU 层的 dropout 比例。res_dropout
:应用于残差连接的 dropout 比例。embed_dropout
:应用于嵌入层的 dropout 比例。attn_mask
:是否使用注意力遮罩(通常用于屏蔽未来的单词)。
-
初始化嵌入层:
self.embed_dim
设置了嵌入维度。self.embed_scale = math.sqrt(embed_dim)
用来对输入进行缩放,通常是为了避免初始化时的值过大。self.embed_positions = SinusoidalPositionalEmbedding(embed_dim)
用于位置编码,增强模型对序列顺序的感知。
-
构建编码器层:
self.layers = nn.ModuleList([])
定义了一个空的ModuleList
用于存储多个 Transformer 编码器层。TransformerEncoderLayer
是每层编码器的实现,包含多头自注意力和前馈网络。- 每个编码器层的超参数(如
embed_dim
,num_heads
,attn_dropout
)从初始化方法传入。
-
规范化(LayerNorm):
self.layer_norm = LayerNorm(embed_dim)
定义了一个可选的 LayerNorm 层,通常用在网络的输出层,以稳定训练过程。
3. 前向传播方法 (forward
)
def forward(self, x_in, x_in_k = None, x_in_v = None):
参数:
x_in
:输入的嵌入张量,形状为(src_len, batch, embed_dim)
,即输入的序列长度、批次大小和嵌入维度。x_in_k
和x_in_v
:可选的键和值张量,通常用于交叉注意力(cross-attention)机制,这在多模态学习(例如图像与文本结合)中较为常见。
-
嵌入和位置编码:
x = self.embed_scale * x_in
:输入的嵌入张量会进行缩放,embed_scale
是为了对嵌入进行归一化,使其适应模型训练。x += self.embed_positions(x_in.transpose(0, 1)[:, :, 0]).transpose(0, 1)
:对输入x_in
加上位置编码,通过SinusoidalPositionalEmbedding
添加位置信息。transpose(0, 1)
交换序列和批次维度,以便位置编码可以正确应用。
-
Dropout:
x = F.dropout(x, p=self.dropout, training=self.training)
:对输入应用 dropout,以防止过拟合。
-
处理键(Key)和值(Value)(如果有):
x_k
和x_v
是可选的键和值,分别代表自注意力机制中的键和值部分。- 对于
x_in_k
和x_in_v
,同样进行嵌入和位置编码操作。
-
编码器层的堆叠:
for layer in self.layers
:对每一层 TransformerEncoderLayer 进行迭代。x = layer(x, x_k, x_v)
:如果x_in_k
和x_in_v
不为空,则传入这些值执行交叉注意力操作。否则,使用普通的自注意力机制。
-
归一化(可选):
- 如果
self.normalize
为True
,在最后应用 LayerNorm。 x = self.layer_norm(x)
:通过 LayerNorm 规范化输出。
- 如果
-
返回值:
- 返回处理后的输入
x
。
- 返回处理后的输入
4. 最大支持的输入长度 (max_positions
)
def max_positions(self):
"""Maximum input length supported by the encoder."""
if self.embed_positions is None:
return self.max_source_positions
return min(self.max_source_positions, self.embed_positions.max_positions())
该方法返回编码器支持的最大输入长度。如果有位置编码(embed_positions
),则返回位置编码支持的最大长度。否则,返回 max_source_positions
。
小结
该 TransformerEncoder
类实现了一个标准的 Transformer 编码器模块,可以通过堆叠多个 TransformerEncoderLayer
来处理序列数据。它包括:
- 输入嵌入和位置编码。
- 对输入应用 dropout。
- 通过多个编码器层(每层包含多头自注意力和前馈网络)处理输入数据。
- 可选的归一化层(LayerNorm)以稳定训练过程。
这种结构非常适合用于序列到序列的任务,如自然语言处理任务、机器翻译、图像处理等。
标签:编码器,嵌入,positions,self,TransformerEncoder,embed,dropout From: https://blog.csdn.net/weixin_44012667/article/details/144291053