模型一共三个大类 一个方法
DTransformer
DTransformerLayer
MultiHeadAttention
attention(方法)
attention
一个注意力方法
感兴趣的有几个
1 | arange().float() |
MultiHeadAttention 类
感兴趣的
1 | nn.Parameter(torch.zeros(n_heads, 1, 1)) |
DTransformerLayer 类
1 | def forward(self, query, key, values, lens, peek_cur=False): |
def device(self):
:这是一个方法的定义,功能是获取当前模型所在的设备。我们之前已经解释过这个方法的作用。def forward(self, query, key, values, lens, peek_cur=False):
:这是DTransformerLayer
类的前向传播方法。在 PyTorch 中,模型的前向传播通过定义forward
方法来完成。在这个方法中,将输入数据query
、key
、values
以及其他参数进行处理,并计算输出结果。seqlen = query.size(1)
:这里获取输入张量query
的序列长度seqlen
,即输入序列的第二个维度大小。mask = torch.ones(seqlen, seqlen).tril(0 if peek_cur else -1)
:这里创建一个二维张量mask
,用于构造自注意力层的掩码(mask)。tril(0 if peek_cur else -1)
是对这个张量进行三角下掩码操作,如果peek_cur
为 True,则保留对角线和对角线以下的元素,否则保留对角线以上的元素。mask = mask.bool()[None, None, :, :].to(self.device())
:将掩码mask
转换为布尔类型,并通过to(self.device())
将其移动到与模型的参数相同的设备上。if self.training:
:这是一个条件判断,检查当前是否处于模型训练状态。mask = mask.expand(query.size(0), -1, -1, -1).contiguous()
:在训练状态下,将掩码mask
扩展为与输入张量query
相同的大小,以便用于对每个样本进行掩码操作。- 通过随机采样的方式对掩码进行操作。在训练过程中,每个样本的掩码会被随机设置为0,以实现dropout效果。这个部分的具体实现逻辑不太清楚,可能涉及一些特定的应用场景或任务需求。根据代码中的注释,如果样本的序列长度
lens[b]
小于某个阈值MIN_SEQ_LEN
,则会跳过对该样本的掩码操作。 query_, scores = self.masked_attn_head(query, key, values, mask, maxout=not peek_cur)
:应用多头注意力机制,计算注意力得分scores
并得到加权后的query_
。query = query + self.dropout(query_)
:对加权后的query_
应用 dropout 操作,然后与原始的输入query
进行相加。这是残差连接的一部分。return self.layer_norm(query), scores
:对加权后的query
应用 Layer Normalization 操作,并将其与注意力得分scores
一起作为输出返回。
总结:这个自定义的 Transformer 层接受输入的 query
、key
、values
张量,并根据 peek_cur
参数进行自注意力计算。同时,它还通过dropout和Layer Normalization对计算结果进行正则化和归一化处理。这个类的具体实现可能与某个特定任务相关,在实际使用中可以根据需要进行相应的调整和修改。