多头注意力机制是一种常用的神经网络结构,主要用于处理序列数据。在该结构中,输入数据经过多个注意力头和线性变换后,得到多个输出结果。这种结构可以提高模型的表达能力,提高模型的性能。

下面是使用 PyTorch 实现多头注意力机制的示例代码:

import torch
import torch.nn as nn

class MultiHeadAttention(nn.Module):
    def __init__(self, d_model, n_heads):
        super(MultiHeadAttention, self).__init__()
        self.d_model = d_model
        self.n_heads = n_heads
        self.d_k = d_model // n_heads
        
        # 定义线性层
        self.query_linear = nn.Linear(d_model, d_model)
        self.key_linear = nn.Linear(d_model, d_model)
        self.value_linear = nn.Linear(d_model, d_model)
        self.out_linear = nn.Linear(d_model, d_model)
        
    def forward(self, x, mask=None):
        batch_size = x.size(0)
        
        # 分别对输入数据进行线性变换
        query = self.query_linear(x).view(batch_size, -1, self.n_heads, self.d_k).transpose(1,2)
        key = self.key_linear(x).view(batch_size, -1, self.n_heads, self.d_k).transpose(1,2)
        value = self.value_linear(x).view(batch_size, -1, self.n_heads, self.d_k).transpose(1,2)
        
        # 计算注意力分数
        scores = torch.matmul(query, key.transpose(-2, -1)) / torch.sqrt(torch.tensor(self.d_k).float())
        if mask is not None:
            mask = mask.unsqueeze(1)
            scores = scores.masked_fill(mask == 0, -1e9)
        attn_weights = nn.functional.softmax(scores, dim=-1)
        
        # 计算注意力输出
        attn_output = torch.matmul(attn_weights, value)
        attn_output = attn_output.transpose(1, 2).contiguous().view(batch_size, -1, self.d_model)
        
        # 对输出结果进行线性变换
        output = self.out_linear(attn_output)
        return output, attn_weights

该代码实现了一个 MultiHeadAttention 类,其中 d_model 表示输入数据的维度,n_heads 表示注意力头的个数。在 forward 函数中,首先对输入数据进行线性变换,然后计算注意力分数,最后计算注意力输出并进行线性变换。

在计算注意力分数时,可以通过 mask 参数来控制注意力权重的计算,例如在机器翻译中,可以通过 mask 来掩盖掉目标语言中未来的词。

在使用多头注意力机制时,可以通过将多个 MultiHeadAttention 模块串联起来来实现,例如:

class TransformerBlock(nn.Module):
    def __init__(self, d_model, n_heads, dropout=0.1):
        super(TransformerBlock, self).__init__()
        self.attention = MultiHeadAttention(d_model, n_heads)
        self.dropout1 = nn.Dropout(dropout)
        self.norm1 = nn.LayerNorm(d_model)
        self.linear1 = nn.Linear(d_model, 4*d_model)
        self.dropout2 = nn.Dropout(dropout)
        self.linear2 = nn.Linear(4*d_model, d_model)
        self.norm2 = nn.LayerNorm(d_model)
        
    def forward(self, x, mask=None):
        attn_output, attn_weights = self.attention(x, mask)
        x = self.norm1(x + self.dropout1(attn_output))
        linear_output = self.linear2(self.dropout2(nn.functional.relu(self.linear1(x))))
        output = self.norm2(x + self.dropout2(linear_output))
        return output

该代码实现了一个 TransformerBlock 类,其中包含了一个 MultiHeadAttention 模块和两个线性变换层。在 forward 函数中,首先使用 MultiHeadAttention 计算注意力输出,然后进行残差连接和归一化操作,接着对注意力输出进行线性变换,最后再进行残差连接和归一化操作。通过将多个 TransformerBlock 串联起来,可以构建一个完整的 Transformer 模型。

PyTorch 多头注意力机制实现详解及代码示例

原文地址: https://www.cveoy.top/t/topic/ocZC 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录