第4讲:GPT系列——“预测下一个词“的生成天才
第4讲:GPT系列——"预测下一个词"的生成天才
一、从一个手机输入法开始
1.1 你每天在用GPT(的雏形)
打开手机,输入"今天天气":
输入法预测:
今天天气 → "很好"(概率85%)
今天天气 → "不错"(概率10%)
今天天气 → "糟糕"(概率5%)
你点了"很好",输入法继续预测:
今天天气很好 → ","(概率90%)
今天天气很好, → "我们"(概率40%)
今天天气很好,我们 → "去"(概率60%)
今天天气很好,我们去 → "公园"(概率50%)
这就是"自回归生成":每次只预测下一个词,然后把预测结果接回输入,继续预测再下一个。
GPT就是这个原理,只是模型更大、数据更多、预测更准。
二、GPT的核心机制:三个关键词
2.1 自回归生成(Autoregressive Generation)
"自回归" = 用自己预测自己
过程像"滚雪球":
输入:"今天"
预测下一个:"天气" → 接到后面
输入变成:"今天天气"
预测下一个:"很好" → 接到后面
输入变成:"今天天气很好"
预测下一个:"," → 接到后面
...
直到生成结束标记[END]
可视化流程:
时间步1: [今天] [PAD] [PAD] [PAD] → 预测 "天气"
时间步2: [今天] [天气] [PAD] [PAD] → 预测 "很好"
时间步3: [今天] [天气] [很好] [PAD] → 预测 ","
时间步4: [今天] [天气] [很好] [,] → 预测 "我们"
...
关键特征:生成是串行的,必须一个词一个词来,不能并行。
2.2 Decoder-only:只用Transformer的解码器
回忆BERT(第3讲):
- BERT用Encoder(双向编码器)
- 能看到左边和右边的所有词
GPT用Decoder(单向解码器):
- 只能看到左边已经生成的词
- 右边的词被"遮住"(还没生成,不能偷看)
BERT处理"今天天气很好":
今 ←→ 天 ←→ 气 ←→ 很 ←→ 好
(每个词都能看到所有其他词)
GPT处理"今天天气很好"(生成"天"时):
今 ─→ 天
("天"只能看到"今",看不到后面的"气很好")
GPT处理"今天天气很好"(生成"气"时):
今 ─→ 天 ─→ 气
("气"能看到"今天",看不到"很好")
这种"只能看左边"的约束,通过**因果掩码(Causal Mask)**实现。
2.3 因果掩码(Causal Mask):防止"偷看未来"
什么是掩码?
想象一个下三角形的遮罩:
要预测的位置: 今 天 气 很 好
─────────────────────────
今(预测天): ✅ ❌ ❌ ❌ ❌ ← 只能看自己
天(预测气): ✅ ✅ ❌ ❌ ❌ ← 能看到"今天"
气(预测很): ✅ ✅ ✅ ❌ ❌ ← 能看到"今天天"
很(预测好): ✅ ✅ ✅ ✅ ❌ ← 能看到"今天天气"
好(结束): ✅ ✅ ✅ ✅ ✅ ← 能看到全部(生成结束)
矩阵表示(注意力权重矩阵):
今 天 气 很 好
┌─────┬─────┬─────┬─────┬─────┐
今 │ 1.0 │ 0.0 │ 0.0 │ 0.0 │ 0.0 │ ← 预测"天"时,只看"今"
├─────┼─────┼─────┼─────┼─────┤
天 │ 0.5 │ 0.5 │ 0.0 │ 0.0 │ 0.0 │ ← 预测"气"时,看"今"和"天"
├─────┼─────┼─────┼─────┼─────┤
气 │ 0.3 │ 0.3 │ 0.4 │ 0.0 │ 0.0 │ ← 预测"很"时,看"今天天"
├─────┼─────┼─────┼─────┼─────┤
很 │ 0.2 │ 0.2 │ 0.3 │ 0.3 │ 0.0 │ ← 预测"好"时,看"今天天气"
├─────┼─────┼─────┼─────┼─────┤
好 │ 0.2 │ 0.2 │ 0.2 │ 0.2 │ 0.2 │ ← 结束,看全部
└─────┴─────┴─────┴─────┴─────┘
代码实现(核心逻辑):
# 构造因果掩码
def create_causal_mask(seq_len):
"""
生成下三角矩阵:上三角(包括对角线以上)为0,下三角为1
"""
mask = torch.tril(torch.ones(seq_len, seq_len)) # tril = lower triangular
# 结果:
# [[1, 0, 0, 0, 0],
# [1, 1, 0, 0, 0],
# [1, 1, 1, 0, 0],
# [1, 1, 1, 1, 0],
# [1, 1, 1, 1, 1]]
return mask
# 在注意力计算中使用
scores = Q @ K.T / sqrt(d_k) # 原始分数
causal_mask = create_causal_mask(n) # 因果掩码
scores = scores.masked_fill(causal_mask == 0, float('-inf')) # 上三角变负无穷
attn_weights = softmax(scores) # Softmax后,被遮住的位置变0
负无穷经过Softmax后变成0,所以模型完全看不到未来的词。
三、GPT的演进:从"小学生"到"大学生"
3.1 GPT-1(2018):证明预训练有效
规模:
参数量:1.17亿(和BERT-base差不多)
训练数据:BookCorpus(约800M词)
层数:12层Decoder
核心思想:
"先在大规模无标注文本上预训练,再在下游任务上微调"
革命性:
之前NLP是每个任务从头训练 → GPT-1证明"预训练+微调"可行
类比:
就像先让小孩读遍图书馆的书(预训练),再专门学写作文(微调)。
3.2 GPT-2(2019):规模带来质变
规模:
参数量:15亿(×13倍)
训练数据:WebText(约10B词,从Reddit外链筛选)
层数:48层Decoder
惊人发现:
不做微调,直接用预训练模型做零样本(Zero-shot)任务,
效果居然也不错!
关键论文标题:“Language Models are Unsupervised Multitask Learners”
语言模型就是无监督的多任务学习器——不需要专门训练,模型从文本中"学会"了各种任务。
例子(零样本翻译):
输入:"翻译:英语→法语
你好 → Bonjour
谢谢 → Merci
再见 →"
GPT-2输出:"Au revoir"
模型从训练数据中的翻译网页"学会"了翻译,不需要专门训练!
3.3 GPT-3(2020):规模即智能?
规模:
参数量:1750亿(×100倍)
训练数据:Common Crawl + WebText + 书籍(约300B词)
层数:96层Decoder
核心能力:
Few-shot Learning(少样本学习):给几个例子,模型就能模仿
Few-shot示例:
输入:"把以下句子翻译成法语:
你好 → Bonjour
谢谢 → Merci
再见 →"
GPT-3输出:"Au revoir"
只给3个例子,模型就"懂"了任务规则。这是GPT-3的突破性能力——In-context Learning(上下文学习)。
3.4 GPT-4(2023):多模态与对齐
突破:
多模态:能看懂图片(不只是文字)
可靠性:幻觉减少,推理能力大幅提升
安全性:RLHF强化,更少生成有害内容
训练方法:
预训练 → SFT(监督微调)→ RLHF(人类反馈强化学习)
四、关键技术详解
4.1 Prompt Engineering:和AI"说话的艺术"
为什么需要Prompt?
GPT是"预测下一个词"的机器。你输入什么,它就接着写什么。
差Prompt:
"写一篇文章"
GPT输出:可能很泛泛,不知道写什么主题
好Prompt:
"请以'人工智能对未来教育的影响'为题,写一篇800字的议论文。
要求:1. 有具体案例 2. 有正反两面观点 3. 结尾给出建议"
GPT输出:结构清晰、内容充实的文章
Prompt的核心技巧
| 技巧 | 说明 | 示例 |
|---|---|---|
| 角色设定 | 让AI扮演专家 | “你是一位资深营养师…” |
| 分步骤 | 复杂任务拆解 | “第一步…第二步…” |
| 给示例 | Few-shot示范 | “例子1:… 例子2:… 现在轮到:” |
| 明确格式 | 指定输出结构 | “用JSON格式输出,包含name和age字段” |
| 设定边界 | 告诉AI什么不该做 | “不要给出医疗建议,只提供一般信息” |
4.2 In-context Learning:从例子中"领悟"
三种学习模式对比
Zero-shot(零样本):
输入:"翻译:猫"
输出:"cat"
→ 模型直接"知道"怎么做,无需例子
One-shot(单样本):
输入:"翻译:狗 → dog。现在翻译:猫"
输出:"cat"
→ 给一个例子,模型模仿
Few-shot(少样本):
输入:"翻译:狗 → dog,猫 → cat,鸟 → bird。现在翻译:鱼"
输出:"fish"
→ 给几个例子,模型总结规律
为什么有效?
GPT在预训练时见过海量"问题→答案"的文本模式。当你给出"翻译:X → Y"的格式,模型激活了记忆中的相关模式,"回忆"起类似任务的解法。
注意:这不是真正的"学习"(参数没更新),而是检索和组合已有知识。
4.3 RLHF:让GPT"说人话"
问题:预训练模型会生成什么?
用户问:"怎么制作炸弹?"
预训练模型(诚实但危险):
"你需要准备以下材料:1. 硝酸甘油 2. 雷管 3. ..."
这显然不行!需要让模型学会:
1. 拒绝有害请求
2. 给出有帮助且安全的回答
3. 语气友好、诚实
RLHF三步走
┌─────────────────────────────────────────────────────────────┐
│ 步骤1:SFT(监督微调) │
│ ─────────────────── │
│ 收集高质量的人工编写的"问题-答案"对 │
│ 用这些数据微调预训练模型 │
│ 效果:模型学会"回答问题"的基本格式和礼貌语气 │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ 步骤2:训练奖励模型(Reward Model) │
│ ─────────────────────────────── │
│ 对同一个问题,生成多个答案 │
│ 人工标注:哪个答案更好(排名) │
│ 训练一个"评分员"模型:输入(问题,答案),输出"好分数" │
│ 效果:模型学会判断"什么是好回答" │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ 步骤3:PPO强化学习优化 │
│ ─────────────────── │
│ 用奖励模型给GPT生成的回答打分 │
│ 好的回答 → 鼓励(提高生成概率) │
│ 差的回答 → 惩罚(降低生成概率) │
│ 效果:GPT学会"讨好"奖励模型,生成人类喜欢的回答 │
└─────────────────────────────────────────────────────────────┘
通俗比喻:
步骤1 = 老师教学生基本礼貌
步骤2 = 训练一个"评委"懂什么是好作文
步骤3 = 学生不断写作文,评委打分,学生根据分数改进
五、动手实验:用GPT-2做文本续写
5.1 实验1:基础文本生成
from transformers import GPT2Tokenizer, GPT2LMHeadModel
import torch
# ============================================
# 步骤1:加载GPT-2模型和分词器
# ============================================
print("正在加载GPT-2(约500MB)...")
tokenizer = GPT2Tokenizer.from_pretrained("gpt2")
model = GPT2LMHeadModel.from_pretrained("gpt2")
# GPT-2没有pad_token,用eos_token代替
tokenizer.pad_token = tokenizer.eos_token
# 设置设备
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = model.to(device)
model.eval()
print(f"✅ GPT-2加载完成!使用设备:{device}")
print(f"模型参数量:{sum(p.numel() for p in model.parameters()) / 1e6:.1f}M")
# ============================================
# 步骤2:基础生成函数
# ============================================
def generate_text(prompt, max_length=50, temperature=1.0, top_k=50):
"""
生成文本的核心函数
参数:
prompt: 输入提示文本
max_length: 生成最大长度
temperature: 温度(控制随机性)
top_k: 只从概率最高的k个词中选
"""
# 编码输入
input_ids = tokenizer.encode(prompt, return_tensors="pt").to(device)
# 生成
with torch.no_grad():
output = model.generate(
input_ids,
max_length=len(input_ids[0]) + max_length,
temperature=temperature,
top_k=top_k,
do_sample=True, # 采样模式(非贪婪)
pad_token_id=tokenizer.eos_token_id
)
# 解码
generated_text = tokenizer.decode(output[0], skip_special_tokens=True)
return generated_text
# ============================================
# 实验1:不同Prompt的生成效果
# ============================================
print("\n" + "=" * 60)
print("【实验1】不同Prompt的生成效果")
print("=" * 60)
prompts = [
"Once upon a time, in a distant galaxy,",
"The future of artificial intelligence is",
"In the year 2050, humans will",
"The secret to happiness is",
]
for prompt in prompts:
print(f"\n📝 Prompt: '{prompt}'")
result = generate_text(prompt, max_length=30, temperature=0.8)
# 只显示生成的部分(去掉prompt)
generated = result[len(prompt):].strip()
print(f" 生成: {generated}")
print("-" * 50)
5.2 实验2:Temperature参数的影响
import matplotlib.pyplot as plt
import numpy as np
print("\n" + "=" * 60)
print("【实验2】Temperature参数对生成的影响")
print("=" * 60)
prompt = "The weather today is"
temperatures = [0.3, 0.7, 1.0, 1.5, 2.0]
results = {}
for temp in temperatures:
print(f"\n🌡️ Temperature = {temp}")
texts = []
for _ in range(3): # 每个温度生成3次,观察随机性
result = generate_text(prompt, max_length=20, temperature=temp, top_k=50)
generated = result[len(prompt):].strip()
texts.append(generated)
print(f" 生成{_+1}: {generated}")
results[temp] = texts
# 可视化温度对概率分布的影响
def visualize_temperature_effect():
"""
演示Temperature如何改变Softmax概率分布
"""
# 模拟一个词的logits(模型原始输出)
logits = torch.tensor([2.0, 1.5, 1.0, 0.5, 0.1, -0.5, -1.0, -2.0])
words = ["the", "a", "an", "this", "that", "one", "some", "any"]
fig, axes = plt.subplots(1, 3, figsize=(15, 5))
temps = [0.5, 1.0, 2.0]
for idx, temp in enumerate(temps):
# Temperature缩放:logits / temperature
scaled_logits = logits / temp
probs = torch.softmax(scaled_logits, dim=-1)
ax = axes[idx]
colors = plt.cm.hot(probs.numpy())
bars = ax.bar(words, probs.numpy(), color=colors)
ax.set_ylim(0, 1)
ax.set_title(f'Temperature = {temp}\n{"确定性高" if temp < 1 else "随机性强" if temp > 1 else "平衡"}',
fontsize=12)
ax.set_ylabel('Probability')
# 标注数值
for bar, prob in zip(bars, probs):
height = bar.get_height()
ax.text(bar.get_x() + bar.get_width()/2., height,
f'{prob:.2%}', ha='center', va='bottom', fontsize=9)
plt.suptitle('Temperature Effect on Probability Distribution', fontsize=14)
plt.tight_layout()
plt.savefig('/mnt/agents/output/gpt_temperature_effect.png', dpi=150)
plt.show()
print("\n📊 概率分布图已保存!")
print("""
解读:
- Temperature < 1(如0.5):概率更"尖锐",高概率词更突出 → 生成更保守、确定
- Temperature = 1:原始概率分布 → 平衡
- Temperature > 1(如2.0):概率更"平坦",随机性增加 → 生成更有创意、但可能混乱
""")
visualize_temperature_effect()
5.3 实验3:Top-k和Top-p采样
print("\n" + "=" * 60)
print("【实验3】Top-k vs Top-p(Nucleus)采样")
print("=" * 60)
def generate_with_sampling(prompt, method="top_k", k=50, p=0.9, temperature=1.0):
"""
展示不同采样策略的效果
"""
input_ids = tokenizer.encode(prompt, return_tensors="pt").to(device)
with torch.no_grad():
if method == "top_k":
# Top-k:只从概率最高的k个词中采样
output = model.generate(
input_ids,
max_length=len(input_ids[0]) + 20,
do_sample=True,
top_k=k,
top_p=1.0, # 不启用top_p
temperature=temperature
)
elif method == "top_p":
# Top-p(Nucleus):从累积概率达到p的最小词集中采样
output = model.generate(
input_ids,
max_length=len(input_ids[0]) + 20,
do_sample=True,
top_k=0, # 不启用top_k
top_p=p,
temperature=temperature
)
else: # greedy
output = model.generate(
input_ids,
max_length=len(input_ids[0]) + 20,
do_sample=False # 贪婪解码
)
return tokenizer.decode(output[0], skip_special_tokens=True)
prompt = "In the beginning, the universe was"
print(f"\nPrompt: '{prompt}'\n")
# 贪婪解码(最确定,但可能重复)
print("🔒 贪婪解码(Greedy):")
result = generate_with_sampling(prompt, method="greedy")
print(f" {result}")
# Top-k采样
print(f"\n🎲 Top-k采样(k=10):")
for i in range(3):
result = generate_with_sampling(prompt, method="top_k", k=10)
print(f" 生成{i+1}: {result}")
# Top-p采样
print(f"\n🎯 Top-p采样(p=0.9):")
for i in range(3):
result = generate_with_sampling(prompt, method="top_p", p=0.9)
print(f" 生成{i+1}: {result}")
print("""
采样策略对比:
贪婪解码:
✅ 确定性最高,每次结果一样
❌ 容易陷入重复循环(如"非常非常非常...")
Top-k采样:
✅ 限制候选词数量,避免选到离谱的低概率词
❌ k值难调:固定k可能包含很多垃圾词,或漏掉好词
Top-p(Nucleus)采样:
✅ 动态调整:根据概率分布自适应选择候选集
✅ 更灵活,通常效果最好
原理:按概率排序,累加到p(如90%),只在这部分词中采样
""")
5.4 实验4:理解GPT的"下一个词预测"本质
print("\n" + "=" * 60)
print("【实验4】观察GPT如何'逐词'预测")
print("=" * 60)
def show_token_by_token_generation(prompt, max_new_tokens=10):
"""
逐步展示GPT的生成过程,看每个位置的概率分布
"""
input_ids = tokenizer.encode(prompt, return_tensors="pt").to(device)
print(f"Prompt: '{prompt}'")
print(f"Token IDs: {input_ids[0].tolist()}")
print(f"Tokens: {tokenizer.convert_ids_to_tokens(input_ids[0])}")
print("\n逐步生成:\n")
generated_ids = input_ids.clone()
for step in range(max_new_tokens):
# 只取前一步的输入
with torch.no_grad():
outputs = model(generated_ids)
# 取最后一个位置的logits
next_token_logits = outputs.logits[0, -1, :] # [vocab_size]
# 应用temperature
temperature = 0.8
probs = torch.softmax(next_token_logits / temperature, dim=-1)
# 取Top-5看看候选词
top_5_probs, top_5_indices = torch.topk(probs, 5)
# 采样下一个词
next_token_id = torch.multinomial(probs, num_samples=1)
# 解码
next_word = tokenizer.decode([next_token_id.item()])
top_candidates = [
(tokenizer.decode([idx.item()]), prob.item())
for idx, prob in zip(top_5_indices, top_5_probs)
]
print(f"步骤 {step+1}:")
print(f" 当前序列: '{tokenizer.decode(generated_ids[0])}'")
print(f" Top-5候选: ", end="")
for word, prob in top_candidates:
print(f"{word}({prob:.1%}) ", end="")
print()
print(f" → 选中: '{next_word}' (概率: {probs[next_token_id].item():.1%})")
print()
# 接到序列后面
generated_ids = torch.cat([generated_ids, next_token_id.unsqueeze(0)], dim=1)
# 检查是否生成了结束标记
if next_token_id.item() == tokenizer.eos_token_id:
print(" [生成结束]")
break
final_text = tokenizer.decode(generated_ids[0], skip_special_tokens=True)
print(f"\n最终生成: '{final_text}'")
# 运行
show_token_by_token_generation("The future of AI is", max_new_tokens=8)
5.5 实验5:中文生成(使用中文GPT)
print("\n" + "=" * 60)
print("【实验5】中文文本生成")
print("=" * 60)
# 使用中文预训练模型(如IDEA的姜子牙系列,或直接用多语言模型)
# 这里用GPT-2的多语言版本做演示
model_name_zh = "uer/gpt2-chinese-cluecorpussmall"
try:
tokenizer_zh = GPT2Tokenizer.from_pretrained(model_name_zh)
model_zh = GPT2LMHeadModel.from_pretrained(model_name_zh)
model_zh = model_zh.to(device)
model_zh.eval()
print(f"✅ 中文GPT加载完成")
prompts_zh = [
"人工智能的未来发展",
"春天来了,",
"在一个遥远的星球上,",
]
for prompt in prompts_zh:
print(f"\n📝 Prompt: '{prompt}'")
input_ids = tokenizer_zh.encode(prompt, return_tensors="pt").to(device)
with torch.no_grad():
output = model_zh.generate(
input_ids,
max_length=len(input_ids[0]) + 30,
temperature=0.8,
top_k=50,
top_p=0.95,
do_sample=True,
pad_token_id=tokenizer_zh.eos_token_id,
repetition_penalty=1.2 # 惩罚重复,避免"的的地"循环
)
result = tokenizer_zh.decode(output[0], skip_special_tokens=True)
generated = result[len(prompt):].strip()
print(f" 生成: {generated}")
except Exception as e:
print(f"中文模型加载失败(可能需要科学上网或本地缓存): {e}")
print("可用英文GPT-2继续实验")
六、面试重点深度解析
6.1 为什么GPT不能做双向理解?
核心原因:因果掩码
BERT的双向注意力:
每个词能看到所有其他词 → 适合理解整个句子的语义关系
GPT的单向注意力:
每个词只能看到左边的词 → 适合"接着写"的生成任务
如果强行让GPT做双向会怎样?
假设GPT能看到右边:
输入:"今天天气[MASK],我们一起去公园。"
模型看到"公园" → 猜[MASK]是"很好"
但生成任务中,"公园"还没生成呢!模型不能"预知未来"。
这就好比让你写作文,但允许你看"标准答案"——作弊了!
根本矛盾:生成任务要求"逐步揭示信息",双向理解要求"同时看全貌"。两者目标不同,架构必然不同。
6.2 生成任务的数学本质是什么?
本质:条件概率的链式分解
要生成句子 "今天 天气 很好":
P(今天, 天气, 很好) =
P(今天) × P(天气|今天) × P(很好|今天, 天气)
用链式法则:
P(w₁, w₂, ..., wₙ) = ∏ P(wᵢ | w₁, w₂, ..., wᵢ₋₁)
GPT做的就是估计这些条件概率:
输入:"今天天气"
模型输出:P(很好 | 今天, 天气) = 0.35
P(不错 | 今天, 天气) = 0.25
P(糟糕 | 今天, 天气) = 0.05
...
采样选择:"很好"(概率最高,或按温度随机选)
6.3 为什么"预测下一个词"能产生智能?
三个层面的解释:
| 层面 | 解释 |
|---|---|
| 压缩视角 | 预测下一个词 = 压缩世界知识。要准确预测,模型必须学会语法、逻辑、常识、推理 |
| 多任务视角 | 语言包含所有任务。翻译、问答、总结都体现在文本中,模型"顺便"学会了 |
| 涌现视角 | 规模达到临界点,能力突然跃升。小模型是"鹦鹉学舌",大模型开始"理解" |
就像小孩学说话:开始是模仿,后来突然能造新句子、讲逻辑、表达情感。
七、核心总结
| 概念 | 一句话解释 |
|---|---|
| 自回归生成 | 一个词一个词"滚雪球",每次预测下一个 |
| Decoder-only | 只用Transformer解码器,不编码 |
| 因果掩码 | 遮住未来信息,防止"偷看" |
| Temperature | 控制随机性:低=保守,高=创意 |
| Top-k/Top-p | 限制采样范围,避免生成离谱内容 |
| RLHF | 用人类反馈"调教"模型,让它更听话 |
| In-context Learning | 从Prompt的例子中"领悟"任务,不更新参数 |
八、课后作业
作业1:Temperature实验
# 用同一个Prompt,分别用temperature=0.1, 0.5, 1.0, 2.0生成
# 观察:低温度是否更"安全"但无聊?高温度是否更"创意"但混乱?
作业2:Prompt设计挑战
任务:让GPT-2生成一个完整的"科幻微小说"(100字以内)
差Prompt:"写一个科幻小说"
好Prompt:"?"
思考:如何设计Prompt,让模型理解"微小说"的格式、科幻元素、字数限制?
作业3:理解"涌现能力"
问题:GPT-3比GPT-2大100倍,但某些能力(如数学推理、代码生成)
不是线性提升,而是突然出现的。为什么?
提示:从"记忆"vs"泛化"的角度思考。
小模型可能只是"记住"了训练数据中的模式,
大模型可能真正"学会"了抽象规则。
九、下讲预告
第5讲:Transformer在视觉领域的开山之作——ViT
我们将:
- 理解"把图像切成补丁块,当成单词序列"的核心思想
- 对比CNN和ViT的归纳偏置差异
- 动手用timm库加载ViT,观察注意力图
- 解释为什么ViT需要大数据预训练
更多推荐




所有评论(0)