在深度学习的广阔宇宙中,Transformer 架构无疑是一颗耀眼的明星。它凭借其强大的并行计算能力和出色的序列建模能力,在自然语言处理、计算机视觉等众多领域取得了卓越的成就。今天,我们将一起探索如何使用 PyTorch 来实现 Transformer 架构,为你的深度学习之旅增添新的动力!
2025年Transformer必学:从零详解VIT、DETR、Loftr、BEVFormer、DeformableDetr一口气学爽
为了方便同学们快速开启人工智能学习计划,在学习过程中少走弯路用最快的效率入门Ai并开始实战项目。
我们整理了近200个Ai实战案例和项目,这些并不是网上搜集来的,而是我们这五年线上线下教学所开发和积累的案例。
可以说都是反复迭代更新出来的,适合同学们来进行循序渐进的学习与练手,下面是资料目录:
一、Transformer 在深度学习中的关键作用
Transformer 是由 Google 于 2017 年提出的一种基于注意力机制的深度学习架构,旨在解决传统循环神经网络(RNN)在处理长序列时的效率和性能问题。与 RNN 不同,Transformer 能够并行处理输入序列,大大提高了训练和推理的速度。
想象一下,你要处理一篇很长的文章。传统的 RNN 就像一个逐字阅读的读者,必须按顺序一个字一个字地处理,效率非常低。而 Transformer 则像是一个拥有超强记忆力和全局视野的读者,能够同时关注文章的各个部分,快速理解文章的整体含义。
在深度学习中,Transformer 就像是一把万能钥匙,能够打开各种复杂任务的大门。它可以用于机器翻译、文本生成、图像识别等多个领域,为解决实际问题提供了强大的工具。
二、Transformer 核心组件解密
多头注意力机制:全局视野的秘密武器
多头注意力机制是 Transformer 的核心组件之一,它允许模型在不同的表示子空间中并行地关注输入序列的不同部分。就像一群专家从不同的角度审视问题,能够更全面地捕捉序列中的信息。
在 PyTorch 中,我们可以使用 torch.nn.MultiheadAttention
模块来实现多头注意力机制。以下是一个简单的示例代码:
import torch
import torch.nn as nn
# 定义多头注意力层
multihead_attn = nn.MultiheadAttention(embed_dim=512, num_heads=8)
# 输入序列
query = torch.randn(10, 32, 512) # (seq_len, batch_size, embed_dim)
key = torch.randn(10, 32, 512)
value = torch.randn(10, 32, 512)
# 计算多头注意力
attn_output, attn_output_weights = multihead_attn(query, key, value)
前馈神经网络:信息处理的引擎
前馈神经网络(Feed Forward Neural Network,FFN)是 Transformer 中的另一个重要组件,它对每个位置的输入进行独立的非线性变换,增强模型的表达能力。
在 PyTorch 中,我们可以使用 torch.nn.Sequential
来构建前馈神经网络。以下是一个简单的示例代码:
class FeedForward(nn.Module):
def __init__(self, embed_dim, ff_dim):
super(FeedForward, self).__init__()
self.fc1 = nn.Linear(embed_dim, ff_dim)
self.relu = nn.ReLU()
self.fc2 = nn.Linear(ff_dim, embed_dim)
def forward(self, x):
x = self.fc1(x)
x = self.relu(x)
x = self.fc2(x)
return x
# 初始化前馈神经网络
ffn = FeedForward(embed_dim=512, ff_dim=2048)
# 输入序列
input_seq = torch.randn(10, 32, 512)
# 前向传播
output_seq = ffn(input_seq)
位置编码:序列顺序的记忆
由于 Transformer 本身不具备处理序列顺序的能力,因此需要引入位置编码来为输入序列中的每个位置添加位置信息。位置编码可以是固定的,也可以是可学习的。
在 PyTorch 中,我们可以使用以下代码实现固定位置编码:
import math
def positional_encoding(seq_len, embed_dim):
pe = torch.zeros(seq_len, embed_dim)
position = torch.arange(0, seq_len, dtype=torch.float).unsqueeze(1)
div_term = torch.exp(torch.arange(0, embed_dim, 2).float() * (-math.log(10000.0) / embed_dim))
pe[:, 0::2] = torch.sin(position * div_term)
pe[:, 1::2] = torch.cos(position * div_term)
return pe
# 生成位置编码
seq_len = 10
embed_dim = 512
pos_enc = positional_encoding(seq_len, embed_dim)
三、构建完整的 Transformer 模型
现在,我们已经了解了 Transformer 的核心组件,接下来可以使用 PyTorch 构建一个完整的 Transformer 模型。以下是一个简化的示例代码:
import torch
import torch.nn as nn
class TransformerModel(nn.Module):
def __init__(self, vocab_size, embed_dim, num_heads, ff_dim, num_layers):
super(TransformerModel, self).__init__()
self.embedding = nn.Embedding(vocab_size, embed_dim)
self.positional_encoding = positional_encoding(seq_len=512, embed_dim=embed_dim)
encoder_layer = nn.TransformerEncoderLayer(d_model=embed_dim, nhead=num_heads, dim_feedforward=ff_dim)
self.transformer_encoder = nn.TransformerEncoder(encoder_layer, num_layers=num_layers)
self.fc = nn.Linear(embed_dim, vocab_size)
def forward(self, src):
src = self.embedding(src)
src = src + self.positional_encoding[:src.size(0), :].unsqueeze(1)
output = self.transformer_encoder(src)
output = self.fc(output)
return output
# 初始化模型
vocab_size = 10000
embed_dim = 512
num_heads = 8
ff_dim = 2048
num_layers = 6
model = TransformerModel(vocab_size, embed_dim, num_heads, ff_dim, num_layers)
# 输入序列
input_seq = torch.randint(0, vocab_size, (10, 32))
# 前向传播
output = model(input_seq)
四、训练和评估 Transformer 模型
构建好模型后,我们需要对其进行训练和评估。以下是一个简单的训练和评估流程:
import torch
import torch.nn as nn
import torch.optim as optim
# 定义损失函数和优化器
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.0001)
# 训练模型
num_epochs = 10
for epoch in range(num_epochs):
optimizer.zero_grad()
output = model(input_seq)
loss = criterion(output.view(-1, vocab_size), input_seq.view(-1))
loss.backward()
optimizer.step()
print(f'Epoch {epoch+1}/{num_epochs}, Loss: {loss.item()}')
# 评估模型
with torch.no_grad():
output = model(input_seq)
_, predicted = torch.max(output.view(-1, vocab_size), 1)
accuracy = (predicted == input_seq.view(-1)).sum().item() / input_seq.numel()
print(f'Accuracy: {accuracy}')
看不够?📢 四大主题训练营火热上线🔥,精准匹配你的成长需求!无论你是想要突破瓶颈、提升技能,还是寻找新的成长方向,这里都有适合你的专属选择。