手撕Transformer编码器:从Self-Attention到Positional Encoding的PyTorch逐行实现
Transformer 编码器深度解读 + 代码实战
1. 编码器核心作用
Transformer 编码器的核心任务是将输入序列(如文本、语音)转换为富含上下文语义的高维特征表示。它通过多层自注意力(Self-Attention)和前馈网络(FFN),逐步建模全局依赖关系,解决传统RNN/CNN的长距离依赖缺陷。
2. 编码器单层结构详解
每层编码器包含以下模块(附 PyTorch 代码):
2.1 多头自注意力(Multi-Head Self-Attention)
class MultiHeadAttention(nn.Module):def __init__(self, embed_size, heads):super().__init__()self.embed_size = embed_sizeself.heads = headsself.head_dim = embed_size // heads# 线性变换层生成 Q, K, Vself.to_qkv = nn.Linear(embed_size, embed_size * 3) # 同时生成 Q/K/Vself.scale = self.head_dim ** -0.5 # 缩放因子# 输出线性层self.to_out = nn.Linear(embed_size, embed_size)def forward(self, x, mask=None):batch_size, seq_len, _ = x.shape# 生成 Q, K, V 并分割多头qkv = self.to_qkv(x).chunk(3, dim=-1) # 拆分为 [Q, K, V]q, k, v = map(lambda t: t.view(batch_size, seq_len, self.heads, self.head_dim), qkv)# 计算注意力分数 (QK^T / sqrt(d_k))attn = torch.einsum('bhid,bhjd->bhij', q, k) * self.scale# 掩码(编码器通常不需要,但保留接口)if mask is not None:attn = attn.masked_fill(mask == 0, -1e10)# Softmax 归一化attn = torch.softmax(attn, dim=-1)# 加权求和out = torch.einsum('bhij,bhjd->bhid', attn, v)out = out.reshape(batch_size, seq_len, self.embed_size)# 输出线性变换return self.to_out(out)
代码解析:
nn.Linear生成 Q/K/V 矩阵,通过chunk分割。einsum实现高效矩阵运算,计算注意力分数。- 支持掩码(虽编码器通常不用,但为兼容性保留)。
2.2 前馈网络(Feed-Forward Network)
class FeedForward(nn.Module):def __init__(self, embed_size, expansion=4):super().__init__()self.net = nn.Sequential(nn.Linear(embed_size, embed_size * expansion), # 扩展维度nn.GELU(), # 更平滑的激活函数(比ReLU效果更好)nn.Linear(embed_size * expansion, embed_size) # 压缩回原维度)def forward(self, x):return self.net(x)
代码解析:
- 典型结构:扩展维度(如512→2048)→激活→压缩回原维度。
- 使用
GELU替代ReLU(现代Transformer的常见选择)。
2.3 残差连接 + 层归一化(Add & Norm)
class TransformerEncoderLayer(nn.Module):def __init__(self, embed_size, heads, dropout=0.1):super().__init__()self.attn = MultiHeadAttention(embed_size, heads)self.ffn = FeedForward(embed_size)self.norm1 = nn.LayerNorm(embed_size)self.norm2 = nn.LayerNorm(embed_size)self.dropout = nn.Dropout(dropout)def forward(self, x):# 自注意力子层attn_out = self.attn(x)x = x + self.dropout(attn_out) # 残差连接x = self.norm1(x)# 前馈子层ffn_out = self.ffn(x)x = x + self.dropout(ffn_out) # 残差连接x = self.norm2(x)return x
代码解析:
- 每个子层后执行
x = x + dropout(sublayer(x)),再层归一化。 - 残差连接确保梯度稳定,层归一化加速收敛。
3. 位置编码(Positional Encoding)
class PositionalEncoding(nn.Module):def __init__(self, embed_size, max_len=5000):super().__init__()pe = torch.zeros(max_len, embed_size)position = torch.arange(0, max_len).unsqueeze(1)div_term = torch.exp(torch.arange(0, embed_size, 2) * (-math.log(10000.0)/embed_size)pe[:, 0::2] = torch.sin(position * div_term) # 偶数位置pe[:, 1::2] = torch.cos(position * div_term) # 奇数位置self.register_buffer('pe', pe.unsqueeze(0)) # (1, max_len, embed_size)def forward(self, x):return x + self.pe[:, :x.size(1)] # 自动广播到 (batch_size, seq_len, embed_size)
代码解析:
- 通过正弦/余弦函数编码绝对位置。
register_buffer将位置编码注册为模型常量(不参与训练)。
4. 完整编码器实现
class TransformerEncoder(nn.Module):def __init__(self, vocab_size, embed_size, layers, heads, dropout=0.1):super().__init__()self.embedding = nn.Embedding(vocab_size, embed_size)self.pos_encoding = PositionalEncoding(embed_size)self.layers = nn.ModuleList([TransformerEncoderLayer(embed_size, heads, dropout)for _ in range(layers)])def forward(self, x):# 输入x形状: (batch_size, seq_len)x = self.embedding(x) # (batch_size, seq_len, embed_size)x = self.pos_encoding(x)for layer in self.layers:x = layer(x)return x # (batch_size, seq_len, embed_size)
5. 实战测试
# 参数设置
vocab_size = 10000 # 假设词表大小
embed_size = 512 # 嵌入维度
layers = 6 # 编码器层数
heads = 8 # 注意力头数# 初始化模型
encoder = TransformerEncoder(vocab_size, embed_size, layers, heads)# 模拟输入(batch_size=32, seq_len=50)
x = torch.randint(0, vocab_size, (32, 50)) # 随机生成句子# 前向传播
output = encoder(x)
print(output.shape) # 预期输出: torch.Size([32, 50, 512])
相关文章:
手撕Transformer编码器:从Self-Attention到Positional Encoding的PyTorch逐行实现
Transformer 编码器深度解读 代码实战 1. 编码器核心作用 Transformer 编码器的核心任务是将输入序列(如文本、语音)转换为富含上下文语义的高维特征表示。它通过多层自注意力(Self-Attention)和前馈网络(FFN&#x…...
Webpack和Vite插件的开发与使用
在现代开发中一般各公司都有自己的监控平台,对前端而言如果浏览器报错的话就可以通过埋点收集错误日志,再结合sourcemap文件可以帮助我们定位到错误代码,帮助我们排查问题。这里就记录一下之前在webpack和vite两个环境中的插件开发࿰…...
HTTP的状态码
HTTP 状态码 当浏览者访问一个网页时,浏览者的浏览器会向网页所在服务器发出请求。当浏览器接收并显示网页前,此网页所在的服务器会返回一个包含 HTTP 状态码的信息头(server header)用以响应浏览器的请求。 常见的HTTP状态码 …...
Python函数-装饰器
装饰器 写好的函数,不做任何修改,就可以改变执行内容,在其头或尾部加入新的流程代码本质上就是使用函数嵌套,在内部嵌套定义的函数中调用原函数,从而可读在前或后加入新的代码使用的关键: 将原函数作为参数…...
【数据可视化-17】基于pyecharts的印度犯罪数据可视化分析
🧑 博主简介:曾任某智慧城市类企业算法总监,目前在美国市场的物流公司从事高级算法工程师一职,深耕人工智能领域,精通python数据挖掘、可视化、机器学习等,发表过AI相关的专利并多次在AI类比赛中获奖。CSDN…...
HTTP请求报文头和相应报文头
一、HTTP请求报文头 HTTP请求报文由请求行、请求头和请求体组成。请求头包含客户端向服务器发送的附加信息。 1.1 请求行 格式: 方法 请求URI HTTP/版本示例: GET /index.html HTTP/1.1 方法: 请求类型,如GET、POST、PUT、DELETE等。 请求URI: 请求的资源…...
19.4.9 数据库方式操作Excel
版权声明:本文为博主原创文章,转载请在显著位置标明本文出处以及作者网名,未经作者允许不得用于商业目的。 本节所说的操作Excel操作是讲如何把Excel作为数据库来操作。 通过COM来操作Excel操作,请参看第21.2节 在第19.3.4节【…...
BFS 走迷宫
#include<bits/stdc.h> using namespace std; int a[100][100],v[100][100];//访问数组 n,m<100 struct point {int x;int y;int step; }; queue<point> r;//申请队列 int dx[4]{0,1,0,-1};//四个方向 右下左上 int dy[4]{1,0,-1,0}; int main() { /* 5 4 1 …...
【Linux系统】—— 简易进度条的实现
【Linux系统】—— 简易进度条的实现 1 回车和换行2 缓冲区3 进度条的准备代码4 第一版进度条5 第二版进度条 1 回车和换行 先问大家一个问题:回车换行是什么,或者说回车和换行是同一个概念吗? 可能大家对回车换行有一定的误解࿰…...
Qt 中使用 SQLite 数据库的完整指南
SQLite 是一款轻量级、嵌入式的关系型数据库,无需独立的服务器进程,数据以文件形式存储,非常适合桌面和移动端应用的本地数据管理。Qt 通过 Qt SQL 模块提供了对 SQLite 的原生支持,开发者可以轻松实现数据库的增删改查、事务处理…...
数智化时代的工单管理:从流程驱动到数据驱动-亿发
在数智化时代,工单管理系统已从简单的任务分发工具演变为企业运营的智能中枢。传统工单系统关注流程的线性推进,而现代工单管理系统则强调数据的全生命周期管理,通过智能算法实现工单的自动分配、优先级判定和效能优化。这种转变不仅提升了运…...
Large Language Model Distilling Medication Recommendation Model
摘要:药物推荐是智能医疗系统的一个重要方面,因为它涉及根据患者的特定健康需求开具最合适的药物。不幸的是,目前使用的许多复杂模型往往忽视医疗数据的细微语义,而仅仅严重依赖于标识信息。此外,这些模型在处理首次就…...
floodfill算法系列一>被围绕的区域
目录 整体思想:代码设计:代码呈现: 整体思想: 代码设计: 代码呈现: class Solution {int m,n;int[] dx {0,0,-1,1};int[] dy {-1,1,0,0};public void solve(char[][] board) {m board.length;n board[…...
Redis 01 02章——入门概述与安装配置
一、入门概述 (1)是什么 Redis:REmote Dictionary Server(远程字典服务器)官网解释:Remote Dictionary Server(远程字典服务)是完全开源的,使用ANSIC语言编写遵守BSD协议,是一个高…...
windows基于cpu安装pytorch运行faster-whisper-large-v3实现语音转文字
1.创建虚拟环境 conda create -n faster-whisper python3.10 conda activate faster-whisper 2.安装cpu版本的pytorch pip3 install torch torchvision torchaudio -i https://pypi.tuna.tsinghua.edu.cn/simple 3.验证pytorch安装结果 (faster-whisper) H:\big-model\faste…...
AI大模型(如GPT、BERT等)可以通过自然语言处理(NLP)和机器学习技术,显著提升测试效率
在软件测试中,AI大模型(如GPT、BERT等)可以通过自然语言处理(NLP)和机器学习技术,显著提升测试效率。以下是几个具体的应用场景及对应的代码实现示例: 1. 自动生成测试用例 AI大模型可以根据需求文档或用户故事自动生成测试用例。 代码示例(使用 OpenAI GPT API): …...
【Prometheus】prometheus黑盒监控balckbox全面解析与应用实战
✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全…...
CSS实现单行、多行文本溢出显示省略号(…)
在网页设计中,我们常常遇到这样的情况:文本内容太长,无法完全显示在一个固定的区域内。为了让界面看起来更整洁,我们可以使用省略号(…)来表示内容溢出。这不仅能提升用户体验,还能避免内容溢出…...
服务器中部署大模型DeepSeek-R1 | 本地部署DeepSeek-R1大模型 | deepseek-r1部署详细教程
0. 部署前的准备 首先我们需要足够算力的机器,这里我在vultr中租了有一张A16显卡一共16GB显存的服务器作为演示。部署的模型参数为14b的。如果需要部署满血版本671b的,需要更大的算力支持,这里由于是个人资金有限,就演示14b的部署…...
元学习之孪生网络Siamese Network
简介:元学习是一种思想,一般以神经网络作为特征嵌入的工具,实现对数据特征的提取,然后通过构造某种指标以引导优化器对模型参数进行优化。而最小化距离是最常见的学习目标,这就是熟知的度量学习,度量学习里…...
【杂谈】-递归进化:人工智能的自我改进与监管挑战
递归进化:人工智能的自我改进与监管挑战 文章目录 递归进化:人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管?3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...
可靠性+灵活性:电力载波技术在楼宇自控中的核心价值
可靠性灵活性:电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中,电力载波技术(PLC)凭借其独特的优势,正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据,无需额外布…...
【网络安全产品大调研系列】2. 体验漏洞扫描
前言 2023 年漏洞扫描服务市场规模预计为 3.06(十亿美元)。漏洞扫描服务市场行业预计将从 2024 年的 3.48(十亿美元)增长到 2032 年的 9.54(十亿美元)。预测期内漏洞扫描服务市场 CAGR(增长率&…...
MMaDA: Multimodal Large Diffusion Language Models
CODE : https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA,它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构…...
【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)
骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术,它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton):由层级结构的骨头组成,类似于人体骨骼蒙皮 (Mesh Skinning):将模型网格顶点绑定到骨骼上,使骨骼移动…...
基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解
JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用,结合SQLite数据库实现联系人管理功能,并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能,同时可以最小化到系统…...
回溯算法学习
一、电话号码的字母组合 import java.util.ArrayList; import java.util.List;import javax.management.loading.PrivateClassLoader;public class letterCombinations {private static final String[] KEYPAD {"", //0"", //1"abc", //2"…...
python爬虫——气象数据爬取
一、导入库与全局配置 python 运行 import json import datetime import time import requests from sqlalchemy import create_engine import csv import pandas as pd作用: 引入数据解析、网络请求、时间处理、数据库操作等所需库。requests:发送 …...
Linux系统部署KES
1、安装准备 1.版本说明V008R006C009B0014 V008:是version产品的大版本。 R006:是release产品特性版本。 C009:是通用版 B0014:是build开发过程中的构建版本2.硬件要求 #安全版和企业版 内存:1GB 以上 硬盘…...
HybridVLA——让单一LLM同时具备扩散和自回归动作预测能力:训练时既扩散也回归,但推理时则扩散
前言 如上一篇文章《dexcap升级版之DexWild》中的前言部分所说,在叠衣服的过程中,我会带着团队对比各种模型、方法、策略,毕竟针对各个场景始终寻找更优的解决方案,是我个人和我司「七月在线」的职责之一 且个人认为,…...
