文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

终于把 Transformer 中的注意力机制搞懂了!!!

2024-11-28 16:24

关注

注意力机制是深度学习领域中广泛应用的技术,特别是在自然语言处理和计算机视觉任务中。它使模型能够有选择地关注输入数据的特定部分,以此提升模型的性能。

想象一下,当你读到 “The cat sat on the mat” 这句话时,人类可以立即理解单词之间的关系,可以知道 “sat” 与 “cat” 的关系比与“mat”的关系更密切。

注意力机制使机器能够捕捉类似的关系,帮助它们专注于输入数据的特定部分。

图片

Transformer 中的注意力机制

在 Transformer 模型中,注意力机制是其核心组件,它使得模型可以在处理输入序列的过程中关注到最重要的信息,从而大幅提高了模型在长序列中的表现。

图片

自注意力机制

在自注意力机制中,每个输入向量可以“关注”同一序列中的其他向量,这使得模型能够灵活地关注整个序列的不同部分。

图片图片

下面,我们一起来看一下如何使用代码来实现上述过程。

import numpy as np

word_embeddings = {
    'she':    np.array([0.2, 0.9, 0.1, 0.5]),
    'likes':  np.array([0.8, 0.3, 0.7, 0.2]),
    'coffee': np.array([0.4, 0.6, 0.3, 0.9])
}

X = np.vstack([word_embeddings['she'], 
               word_embeddings['likes'], 
               word_embeddings['coffee']])
               
W_q = np.array([[0.9, 0.1, 0.1, 0.1],
                [0.1, 0.9, 0.1, 0.1],
                [0.1, 0.1, 0.9, 0.1],
                [0.1, 0.1, 0.1, 0.9]])

W_k = np.array([[0.9, 0.1, 0.1, 0.1],
                [0.1, 0.9, 0.1, 0.1],
                [0.1, 0.1, 0.9, 0.1],
                [0.1, 0.1, 0.1, 0.9]])
W_v = np.array([[0.8, 0.2, 0.1, 0.1],
                [0.2, 0.8, 0.2, 0.1],
                [0.1, 0.2, 0.8, 0.1],
                [0.1, 0.1, 0.1, 0.9]])
                
Q = np.dot(X, W_q)
K = np.dot(X, W_k)
V = np.dot(X, W_v)

scores = np.dot(Q, K.T)

d_k = K.shape[1]
scaled_scores = scores / np.sqrt(d_k)

exp_scores = np.exp(scaled_scores)
attention_weights = exp_scores / exp_scores.sum(axis=1, keepdims=True)

output = np.dot(attention_weights, V)

print(output)

多头注意力机制(Multi-Head Attention)

多头注意力机制进一步扩展了自注意力的表达能力。

通过设置多个注意力头(head),每个头从不同的子空间中获取信息,最后将各头的结果拼接起来并进行线性变换。

这样模型可以更好地捕捉多维度的依赖关系,使其在复杂任务中表现更为优异。

图片图片

多头注意力的计算流程

多头注意力机制增加了模型的灵活性,能让模型从不同角度学习到序列中词汇间的关系。

class MultiHeadAttention(nn.Module):    
    
    def __init__(self, d_model, num_heads):
        super(MultiHeadAttention, self).__init__()
        # Ensure that the model dimension (d_model) is divisible by the number of heads
        assert d_model % num_heads == 0 
        
        # Initialize dimensions
        self.d_model = d_model # Model's dimension
        self.num_heads = num_heads # Number of attention heads
        self.d_k = d_model // num_heads # Dimension of each head's key, query, and value
        
        # Linear layers for transforming inputs
        self.W_q = nn.Linear(d_model, d_model) # Query transformation
        self.W_k = nn.Linear(d_model, d_model) # Key transformation
        self.W_v = nn.Linear(d_model, d_model) # Value transformation
        self.W_o = nn.Linear(d_model, d_model) # Output transformation
    
    # 缩放点积注意力机制
    def scaled_dot_product_attention(self, Q, K, V, mask=None):
        # Calculate attention scores
        attn_scores = torch.matmul(Q, K.transpose(-2, -1)) / math.sqrt(self.d_k)
        
        # Apply mask if provided (useful for preventing attention to certain parts like padding)
        if mask is not None:
            attn_scores = attn_scores.masked_fill(mask == 0, -1e9)
        
        # Softmax is applied to obtain attention probabilities
        attn_probs = torch.softmax(attn_scores, dim=-1)
        
        # Multiply by values to obtain the final output
        output = torch.matmul(attn_probs, V)
        return output
        
    def split_heads(self, x):
        # Reshape the input to have num_heads for multi-head attention
        batch_size, seq_length, d_model = x.size()
        return x.view(batch_size, seq_length, self.num_heads, self.d_k).transpose(1, 2)
        
    def combine_heads(self, x):
        # Combine the multiple heads back to original shape
        batch_size, _, seq_length, d_k = x.size()
        return x.transpose(1, 2).contiguous().view(batch_size, seq_length, self.d_model)
        
    def forward(self, Q, K, V, mask=None):
        # Apply linear transformations and split heads
        Q = self.split_heads(self.W_q(Q))
        K = self.split_heads(self.W_k(K))
        V = self.split_heads(self.W_v(V))
        
        # Perform scaled dot-product attention
        attn_output = self.scaled_dot_product_attention(Q, K, V, mask)
        
        # Combine heads and apply output transformation
        output = self.W_o(self.combine_heads(attn_output))
        return output
来源:程序员学长内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯