news 2026/7/11 6:33:28

手撕多头注意力

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
手撕多头注意力

“手撕”:不依赖任何现成的库(比如nn.MultiheadAttention),让你在白板或者在线代码编辑器里把代码完整敲出来。

面试官想通过这个题目考察你两点:

  1. 你是否真正理解了 Transformer 的核心底层数学逻辑。

  2. 你对深度学习框架中张量维度的变换(如 view/reshape、transpose、维度广播)是否烂熟于心。这往往是大家最容易写错的地方。

import torch import torch.nn as nn import math class MultiHeadAttention(nn.Module): def __init__(self, d_model, num_heads): super(MultiHeadAttention, self).__init__() # 确保特征维度可以被头数整除 assert d_model % num_heads == 0, "d_model must be divisible by num_heads" self.d_model = d_model self.num_heads = num_heads self.d_k = d_model // num_heads # 每个头的维度 # 定义 Q, K, V 的线性变换矩阵 self.W_q = nn.Linear(d_model, d_model) self.W_k = nn.Linear(d_model, d_model) self.W_v = nn.Linear(d_model, d_model) # 定义最后的输出线性变换矩阵 self.W_o = nn.Linear(d_model, d_model) def forward(self, x, mask=None): # x 的维度通常是: (batch_size, seq_len, d_model) batch_size, seq_len, _ = x.size() # 1. 线性变换,并重塑维度来切分多头 # 维度变化: (batch_size, seq_len, d_model) -> (batch_size, seq_len, num_heads, d_k) # 然后交换维度 1和2 变成: (batch_size, num_heads, seq_len, d_k) Q = self.W_q(x).view(batch_size, seq_len, self.num_heads, self.d_k).transpose(1, 2) K = self.W_k(x).view(batch_size, seq_len, self.num_heads, self.d_k).transpose(1, 2) V = self.W_v(x).view(batch_size, seq_len, self.num_heads, self.d_k).transpose(1, 2) # 2. 计算 Scaled Dot-Product Attention # K 转置的最后两个维度,为了满足矩阵乘法: (..., seq_len, d_k) x (..., d_k, seq_len) scores = torch.matmul(Q, K.transpose(-2, -1)) / math.sqrt(self.d_k) # 3. 处理 Mask (可选,但面试时提一下会加分) if mask is not None: # 将 mask 中为 0 的位置替换为一个很小的负数,这样 softmax 之后就会变成 0 scores = scores.masked_fill(mask == 0, -1e9) # 4. Softmax 与 V 相乘 attention_weights = torch.softmax(scores, dim=-1) # 维度: (batch_size, num_heads, seq_len, seq_len) @ (batch_size, num_heads, seq_len, d_k) # 结果维度: (batch_size, num_heads, seq_len, d_k) context = torch.matmul(attention_weights, V) # 5. 拼接多头的结果 # 把维度换回来: (batch_size, seq_len, num_heads, d_k) # contiguous() 是为了保证内存连续,才能调用 view context = context.transpose(1, 2).contiguous().view(batch_size, seq_len, self.d_model) # 6. 最后的线性映射 output = self.W_o(context) return output
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/11 6:31:17

十天STM32裸机实战:从点灯到FreeRTOS的寄存器级攻坚路线

1. 这不是速成神话,而是一份被验证过的“十天STM32攻坚路线图”“十天学完STM32”——看到这个标题,我第一反应是皱眉。十年前刚带第一批实习生时,我也信过“七天入门单片机”的宣传语,结果第三天就有人对着LED不亮抓耳挠腮&#…

作者头像 李华
网站建设 2026/7/11 6:30:35

UE5语音识别通用方案:云端、离线与混合架构实战解析

1. 项目概述:为什么UE5需要一套通用的语音识别方案?在UE5项目开发中,尤其是涉及到交互叙事、虚拟培训、数字孪生或者无障碍功能时,语音输入正从一个“锦上添花”的特性,变成一个“雪中送炭”的核心交互层。想象一下&am…

作者头像 李华
网站建设 2026/7/11 6:30:16

终极暗黑破坏神2现代优化方案:D2DX技术深度解析与实战指南

终极暗黑破坏神2现代优化方案:D2DX技术深度解析与实战指南 【免费下载链接】d2dx D2DX is a complete solution to make Diablo II run well on modern PCs, with high fps and better resolutions. 项目地址: https://gitcode.com/gh_mirrors/d2/d2dx 在经典…

作者头像 李华
网站建设 2026/7/11 6:25:30

大数据毕设选题推荐:基于 Python 的高校招聘薪资数据统计分析系统的设计与实现 基于 Python 的高校岗位分类与智能分析平台【附源码、mysql、文档、调试+代码讲解+全bao等】

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

作者头像 李华
网站建设 2026/7/11 6:21:53

萝丽控制器 OLED 屏 SPI 接口适配指南:3步替换LCD并解决拖影问题

萝丽控制器 OLED 屏 SPI 接口适配指南:3步替换LCD并解决拖影问题在开源硬件社区中,萝丽控制器以其高性价比和模块化设计赢得了众多创客的青睐。然而原配的LCD屏幕在动态显示时普遍存在的拖影问题,常常影响用户体验。本文将手把手教你用SPI接口…

作者头像 李华
网站建设 2026/7/11 6:19:31

大数据毕设项目:基于 Python + 深度学习的短视频兴趣画像匹配系统的设计与实现 基于 Python + 深度学习的短视频内容检索与推荐系统 (源码+文档,讲解、调试运行,定制等)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

作者头像 李华