大模型入门必学!从RNN到Transformer的演化历程
文章详细介绍了从RNN到Transformer的演化历程。RNN存在顺序处理慢、梯度消失等问题;Attention机制允许模型关注输入序列中的重要部分;Transformer完全抛弃RNN结构,仅使用注意力机制,支持并行计算,对长文本处理更好。文章解释了Transformer的核心构件,如自注意力、多头注意力和位置编码,并通过代码示例对比了RNN和Transformer模型的实现。
文章详细介绍了从RNN到Transformer的演化历程。RNN存在顺序处理慢、梯度消失等问题;Attention机制允许模型关注输入序列中的重要部分;Transformer完全抛弃RNN结构,仅使用注意力机制,支持并行计算,对长文本处理更好。文章解释了Transformer的核心构件,如自注意力、多头注意力和位置编码,并通过代码示例对比了RNN和Transformer模型的实现。
为什么一开始我们用 RNN?
当咱们在看一部小说的时候,每一页的内容都和前面发生的事情有关。RNN(循环神经网络)就像一个人在读小说,每读一句话就记住重点,然后带着记忆去读下一句。它按顺序处理信息,一步一步来。
但是,问题来了:
- 你得一句一句等着看,不能跳着看,太慢了!
- 记忆力不好!前面发生的事容易忘记(梯度消失问题)。
Transformer 出现前的“革命”:Attention 机制
Attention(注意力机制)就像是咱们复习的时候,把小说的精彩段落划重点。你读当前这句话时,会回头看看其他关键句子,并决定“我现在需要关注谁”。
那 Transformer 是什么?
Transformer 直接放弃了 RNN,不再一句一句读,而是像一群学生一起读整本小说,然后互相交流看哪句最重要。这就是“Attention Is All You Need”,只要注意力机制就够了!
优点:
- 并行处理,速度快!
- 长距离依赖处理得好,记忆力强!
- 结构清晰,好训练!
逐步过渡:RNN → Attention → Transformer
1. RNN 的本质
-
每一步的输出依赖上一步的隐藏状态:
-
存在梯度消失、不能并行等问题。
2. Attention 的本质
Attention 是一种“加权平均”思想:我们不再只看上一个时间步,而是看所有的输入,并根据相关性赋予权重。
举个例子:
- 当前输入是“他”,
- 想知道“他”指的是谁,
- 我可以去翻“张三去了公园。后来他……”,
- 根据语义,“张三”和“他”最相关!
3. Transformer 的核心构件
Transformer 用的叫做 Self-Attention(自注意力),就是:
- 每个词都看其他所有词(包括自己),
- 计算他们之间的注意力权重。
同时,它丢掉了循环结构,用位置编码来补充顺序信息。
核心原理
1. Attention 基本公式
2. Self-Attention(自注意力)
3. 多头注意力(Multi-Head Attention)
4. Transformer Block 的结构
5. 位置编码(Positional Encoding)
为什么“Attention Is All You Need”?
因为 Transformer:
- 丢掉了 RNN 复杂的结构
- 用注意力机制完成所有信息交互
- 支持并行计算,更快训练
- 对长文本表现更好
所以,“Attention Is All You Need” !
完整案例
我们构造一个简单的字符级序列任务:输入是表示两位数字加法的字符序列(如 “12+34”),输出是其结果(如 “46”)。该任务便于模拟 Seq2Seq 场景,并能直观对比模型表现。
# comments: 数据集生成脚本
import random
def generate_example():
a = random.randint(0, 99)
b = random.randint(0, 99)
x = f"{a:02d}+{b:02d}"# 输入例如 "05+23"
y = str(a + b) # 输出 "28"
return x, y
# 生成数据集
dataset = [generate_example() for _ in range(10000)]
train_set = dataset[:8000]
valid_set = dataset[8000:9000]
test_set = dataset[9000:]
代码实现 Seq2Seq RNN 和 Transformer 模型~
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import Dataset, DataLoader
# comments: 定义字符映射
CHARS = ['0','1','2','3','4','5','6','7','8','9','+']
PAD_IDX = 0
CHAR2IDX = {c:i+1for i,c in enumerate(CHARS)}
IDX2CHAR = {i:c for c,i in CHAR2IDX.items()}
VOCAB_SIZE = len(CHAR2IDX) + 1# 包含 PAD
class SeqAdditionDataset(Dataset):
def __init__(self, data):
self.data = data
def __len__(self):
return len(self.data)
def __getitem__(self, idx):
x, y = self.data[idx]
x_idx = [CHAR2IDX[c] for c in x]
y_idx = [CHAR2IDX[c] for c in y]
return torch.tensor(x_idx), torch.tensor(y_idx)
# comments: collate_fn for padding
def collate_fn(batch):
xs, ys = zip(*batch)
xs = nn.utils.rnn.pad_sequence(xs, batch_first=True, padding_value=PAD_IDX)
ys = nn.utils.rnn.pad_sequence(ys, batch_first=True, padding_value=PAD_IDX)
return xs, ys
# RNN Encoder
class RNNEncoder(nn.Module):
def __init__(self, input_dim, emb_dim, hid_dim, n_layers):
super().__init__()
self.embedding = nn.Embedding(input_dim, emb_dim, padding_idx=PAD_IDX)
self.rnn = nn.GRU(emb_dim, hid_dim, n_layers, batch_first=True)
def forward(self, src):
embedded = self.embedding(src)
outputs, hidden = self.rnn(embedded)
return outputs, hidden
# RNN Decoder
class RNNDecoder(nn.Module):
def __init__(self, output_dim, emb_dim, hid_dim, n_layers):
super().__init__()
self.embedding = nn.Embedding(output_dim, emb_dim, padding_idx=PAD_IDX)
self.rnn = nn.GRU(emb_dim, hid_dim, n_layers, batch_first=True)
self.fc_out = nn.Linear(hid_dim, output_dim)
def forward(self, input, hidden):
# input: [batch]
input = input.unsqueeze(1)
embedded = self.embedding(input)
output, hidden = self.rnn(embedded, hidden)
prediction = self.fc_out(output.squeeze(1))
return prediction, hidden
# comments: Seq2Seq 包装
class Seq2SeqRNN(nn.Module):
def __init__(self, encoder, decoder, device):
super().__init__()
self.encoder = encoder
self.decoder = decoder
self.device = device
def forward(self, src, trg, teacher_forcing_ratio=0.5):
batch_size = src.size(0)
trg_len = trg.size(1)
trg_vocab_size = self.decoder.fc_out.out_features
outputs = torch.zeros(batch_size, trg_len, trg_vocab_size).to(self.device)
enc_outputs, hidden = self.encoder(src)
input = trg[:,0]
for t in range(1, trg_len):
output, hidden = self.decoder(input, hidden)
outputs[:,t] = output
teacher_force = random.random() < teacher_forcing_ratio
top1 = output.argmax(1)
input = trg[:,t] if teacher_force else top1
return outputs
到这里,大家可以完整体验从 RNN 到 Transformer 的设计理念,并通过可视化体验 Attention 带来的优势。
大家在真实项目中,可进一步结合 BERT、GPT 等预训练模型,实现更强大的性能提升!~
我们如何系统学习掌握AI大模型?
AI大模型作为人工智能领域的重要技术突破,正成为推动各行各业创新和转型的关键力量。抓住AI大模型的风口,掌握AI大模型的知识和技能将变得越来越重要。
学习AI大模型是一个系统的过程,需要从基础开始,逐步深入到更高级的技术。
这里给大家精心整理了一份
全面的AI大模型学习资源
,包括:AI大模型全套学习路线图(从入门到实战)、精品AI大模型学习书籍手册、视频教程、实战学习、面试题等,资料免费分享
!
1. 成长路线图&学习规划
要学习一门新的技术,作为新手一定要先学习成长路线图,方向不对,努力白费。
这里,我们为新手和想要进一步提升的专业人士准备了一份详细的学习成长路线图和规划。可以说是最科学最系统的学习成长路线。
2. 大模型经典PDF书籍
书籍和学习文档资料是学习大模型过程中必不可少的,我们精选了一系列深入探讨大模型技术的书籍和学习文档,它们由领域内的顶尖专家撰写,内容全面、深入、详尽,为你学习大模型提供坚实的理论基础。(书籍含电子版PDF)
3. 大模型视频教程
对于很多自学或者没有基础的同学来说,书籍这些纯文字类的学习教材会觉得比较晦涩难以理解,因此,我们提供了丰富的大模型视频教程,以动态、形象的方式展示技术概念,帮助你更快、更轻松地掌握核心知识。
4. 大模型行业报告
行业分析主要包括对不同行业的现状、趋势、问题、机会等进行系统地调研和评估,以了解哪些行业更适合引入大模型的技术和应用,以及在哪些方面可以发挥大模型的优势。
5. 大模型项目实战
学以致用 ,当你的理论知识积累到一定程度,就需要通过项目实战,在实际操作中检验和巩固你所学到的知识,同时为你找工作和职业发展打下坚实的基础。
6. 大模型面试题
面试不仅是技术的较量,更需要充分的准备。
在你已经掌握了大模型技术之后,就需要开始准备面试,我们将提供精心整理的大模型面试题库,涵盖当前面试中可能遇到的各种技术问题,让你在面试中游刃有余。
全套的AI大模型学习资源已经整理打包,有需要的小伙伴可以
微信扫描下方CSDN官方认证二维码
,免费领取【保证100%免费
】
更多推荐
所有评论(0)