03-深度学习基础:预训练模型与迁移学习

预训练模型与迁移学习:AI的范式革命

一、为什么需要预训练模型?

1.1 从零训练的困境

python 复制代码
import numpy as np
import matplotlib.pyplot as plt
import warnings
warnings.filterwarnings('ignore')

print("=" * 60)
print("为什么预训练模型改变了AI?")
print("=" * 60)

# 可视化从零训练的困境
fig, axes = plt.subplots(1, 2, figsize=(14, 5))

# 从零训练
ax1 = axes[0]
ax1.axis('off')
ax1.set_title('从零训练:高成本、低效率', fontsize=12)

problems = [
    ("数据需求", "需要大量标注数据(百万级)"),
    ("算力需求", "需要多GPU训练数周"),
    ("时间成本", "每次任务都要重新训练"),
    ("专业知识", "需要调参技巧"),
    ("环保问题", "碳排放巨大")
]

y_pos = 0.75
for problem, desc in problems:
    ax1.text(0.1, y_pos, f"• {problem}:", fontsize=11, fontweight='bold')
    ax1.text(0.35, y_pos, desc, fontsize=10)
    y_pos -= 0.12

ax1.text(0.5, 0.1, "每次新任务都要重复这个过程!", 
         ha='center', fontsize=11, color='red',
         bbox=dict(boxstyle='round', facecolor='lightcoral'))

# 迁移学习
ax2 = axes[1]
ax2.axis('off')
ax2.set_title('迁移学习:复用知识', fontsize=12)

# 预训练模型
pretrained_box = plt.Rectangle((0.35, 0.7), 0.3, 0.12,
                                 facecolor='lightgreen', ec='black')
ax2.add_patch(pretrained_box)
ax2.text(0.5, 0.76, '预训练模型', ha='center', va='center', fontsize=11, fontweight='bold')

# 下游任务
tasks = ['情感分析', '问答系统', '命名实体识别', '文本分类', '摘要生成']
y_pos = 0.55
for task in tasks:
    task_box = plt.Rectangle((0.35, y_pos-0.05), 0.3, 0.08,
                               facecolor='lightblue', ec='black')
    ax2.add_patch(task_box)
    ax2.text(0.5, y_pos, task, ha='center', va='center', fontsize=9)
    
    # 连接线
    ax2.annotate('', xy=(0.5, y_pos+0.03), xytext=(0.5, 0.7),
                arrowprops=dict(arrowstyle='->', color='blue', lw=1))
    y_pos -= 0.12

ax2.text(0.5, 0.05, "一个模型,多个任务!", 
         ha='center', fontsize=11, color='green',
         bbox=dict(boxstyle='round', facecolor='lightgreen'))

plt.suptitle('从零训练 vs 迁移学习', fontsize=14)
plt.tight_layout()
plt.show()

print("\n💡 预训练模型的核心思想:")
print("   1. 在大规模数据上预训练(学习通用知识)")
print("   2. 在小规模下游数据上微调(适应特定任务)")
print("   3. 大幅降低训练成本和时间")
print("   4. 小数据场景也能取得好效果")

二、迁移学习的基本概念

2.1 迁移学习的类型

python 复制代码
def visualize_transfer_learning_types():
    """可视化不同类型的迁移学习"""
    
    fig, axes = plt.subplots(1, 3, figsize=(15, 5))
    
    # 1. 特征提取
    ax1 = axes[0]
    ax1.axis('off')
    ax1.set_title('特征提取', fontsize=12)
    
    # 预训练模型
    pretrained = plt.Rectangle((0.1, 0.6), 0.35, 0.15,
                                facecolor='lightblue', ec='black')
    ax1.add_patch(pretrained)
    ax1.text(0.275, 0.675, '预训练模型\n(冻结)', ha='center', va='center', fontsize=9)
    
    # 分类器
    classifier = plt.Rectangle((0.55, 0.6), 0.35, 0.15,
                                facecolor='lightgreen', ec='black')
    ax1.add_patch(classifier)
    ax1.text(0.725, 0.675, '新分类器\n(训练)', ha='center', va='center', fontsize=9)
    
    ax1.annotate('', xy=(0.55, 0.675), xytext=(0.45, 0.675),
                arrowprops=dict(arrowstyle='->', lw=2))
    
    ax1.text(0.5, 0.4, '只训练新添加的分类层\n预训练模型参数不变', 
            ha='center', fontsize=9,
            bbox=dict(boxstyle='round', facecolor='lightyellow'))
    
    # 2. 微调
    ax2 = axes[1]
    ax2.axis('off')
    ax2.set_title('微调 (Fine-tuning)', fontsize=12)
    
    # 预训练模型
    pretrained2 = plt.Rectangle((0.1, 0.6), 0.35, 0.15,
                                 facecolor='lightcoral', ec='black')
    ax2.add_patch(pretrained2)
    ax2.text(0.275, 0.675, '预训练模型\n(微调)', ha='center', va='center', fontsize=9)
    
    # 分类器
    classifier2 = plt.Rectangle((0.55, 0.6), 0.35, 0.15,
                                 facecolor='lightcoral', ec='black')
    ax2.add_patch(classifier2)
    ax2.text(0.725, 0.675, '新分类器\n(训练)', ha='center', va='center', fontsize=9)
    
    ax2.annotate('', xy=(0.55, 0.675), xytext=(0.45, 0.675),
                arrowprops=dict(arrowstyle='->', lw=2))
    
    ax2.text(0.5, 0.4, '所有参数都参与训练\n用小学习率微调', 
            ha='center', fontsize=9,
            bbox=dict(boxstyle='round', facecolor='lightyellow'))
    
    # 3. 渐进式微调
    ax3 = axes[2]
    ax3.axis('off')
    ax3.set_title('渐进式微调', fontsize=12)
    
    layers = ['底层', '中层', '高层', '分类层']
    colors = ['lightblue', 'lightblue', 'lightcoral', 'lightcoral']
    y_pos = [0.7, 0.55, 0.4, 0.25]
    
    for layer, color, y in zip(layers, colors, y_pos):
        layer_box = plt.Rectangle((0.3, y-0.05), 0.4, 0.1,
                                   facecolor=color, ec='black')
        ax3.add_patch(layer_box)
        ax3.text(0.5, y, layer, ha='center', va='center', fontsize=9)
        
        if y < 0.65:
            ax3.annotate('', xy=(0.5, y+0.05), xytext=(0.5, y-0.05),
                        arrowprops=dict(arrowstyle='->', lw=1))
    
    ax3.text(0.5, 0.1, '先微调高层,再逐步解冻底层', 
            ha='center', fontsize=9,
            bbox=dict(boxstyle='round', facecolor='lightyellow'))
    
    plt.suptitle('迁移学习的三种主要方式', fontsize=14)
    plt.tight_layout()
    plt.show()

visualize_transfer_learning_types()

print("\n📊 迁移学习方式对比:")
print("   特征提取: 快速、数据量小、计算资源少")
print("   微调: 效果好、需要更多数据")
print("   渐进式微调: 平衡效果和效率")

三、BERT:开创性的预训练模型

3.1 BERT的预训练任务

python 复制代码
def visualize_bert_pretraining():
    """可视化BERT的预训练任务"""
    
    fig, axes = plt.subplots(1, 2, figsize=(14, 6))
    
    # 1. MLM (Masked Language Model)
    ax1 = axes[0]
    ax1.axis('off')
    ax1.set_title('MLM:掩码语言模型', fontsize=12)
    
    sentence = "The cat sat on the mat"
    words = sentence.split()
    
    # 显示原始句子
    x_pos = np.linspace(0.1, 0.9, len(words))
    for i, (word, x) in enumerate(zip(words, x_pos)):
        if word == 'sat':
            # 被掩码的词
            circle = plt.Circle((x, 0.7), 0.08, color='red', ec='black')
            ax1.add_patch(circle)
            ax1.text(x, 0.7, '[MASK]', ha='center', va='center', fontsize=8, color='white')
        else:
            circle = plt.Circle((x, 0.7), 0.08, color='lightblue', ec='black')
            ax1.add_patch(circle)
            ax1.text(x, 0.7, word, ha='center', va='center', fontsize=9)
    
    ax1.text(0.5, 0.5, '任务: 预测被掩码的词', ha='center', fontsize=10,
            bbox=dict(boxstyle='round', facecolor='lightyellow'))
    ax1.text(0.5, 0.4, '答案: "sat"', ha='center', fontsize=10, color='green')
    
    # 2. NSP (Next Sentence Prediction)
    ax2 = axes[1]
    ax2.axis('off')
    ax2.set_title('NSP:下一句预测', fontsize=12)
    
    # 句子A
    sent_a = "The cat sat on the mat."
    sent_b = "It was a sunny day."
    
    sent_a_box = plt.Rectangle((0.1, 0.7), 0.8, 0.12,
                                facecolor='lightblue', ec='black')
    ax2.add_patch(sent_a_box)
    ax2.text(0.5, 0.76, sent_a, ha='center', va='center', fontsize=10)
    
    sent_b_box = plt.Rectangle((0.1, 0.5), 0.8, 0.12,
                                facecolor='lightgreen', ec='black')
    ax2.add_patch(sent_b_box)
    ax2.text(0.5, 0.56, sent_b, ha='center', va='center', fontsize=10)
    
    # [SEP] token
    ax2.text(0.5, 0.64, '[SEP]', ha='center', va='center', fontsize=9,
            bbox=dict(boxstyle='round', facecolor='lightgray'))
    
    ax2.text(0.5, 0.38, '任务: 判断B是否是A的下一句', ha='center', fontsize=10,
            bbox=dict(boxstyle='round', facecolor='lightyellow'))
    ax2.text(0.5, 0.28, '答案: 不是 (IsNext? False)', ha='center', fontsize=10, color='red')
    
    plt.suptitle('BERT的预训练任务', fontsize=14)
    plt.tight_layout()
    plt.show()
    
    print("\n📊 BERT预训练:")
    print("   MLM: 让模型理解词在上下文中的含义")
    print("   NSP: 让模型理解句子间的关系")
    print("   数据: BooksCorpus (800M词) + Wikipedia (2.5B词)")

visualize_bert_pretraining()

3.2 使用BERT进行文本分类

python 复制代码
try:
    import torch
    from transformers import AutoTokenizer, AutoModelForSequenceClassification
    from transformers import Trainer, TrainingArguments
    from sklearn.model_selection import train_test_split
    from sklearn.metrics import accuracy_score, precision_recall_fscore_support
    import pandas as pd
    
    print("\n" + "=" * 60)
    print("使用BERT进行情感分类")
    print("=" * 60)
    
    # 创建模拟数据集
    np.random.seed(42)
    n_samples = 500
    
    texts = [
        "This product is amazing! I love it.",
        "Terrible quality, would not recommend.",
        "Good value for money, satisfied.",
        "Waste of money, very disappointed.",
        "Excellent service, will buy again.",
        "Not what I expected, poor quality."
    ] * 100
    
    labels = [1, 0, 1, 0, 1, 0] * 100  # 1: positive, 0: negative
    
    # 划分数据集
    train_texts, test_texts, train_labels, test_labels = train_test_split(
        texts, labels, test_size=0.2, random_state=42
    )
    
    # 加载BERT模型和分词器
    model_name = "bert-base-uncased"
    tokenizer = AutoTokenizer.from_pretrained(model_name)
    model = AutoModelForSequenceClassification.from_pretrained(model_name, num_labels=2)
    
    # 分词
    train_encodings = tokenizer(train_texts, truncation=True, padding=True, max_length=128)
    test_encodings = tokenizer(test_texts, truncation=True, padding=True, max_length=128)
    
    # 创建Dataset类
    class SentimentDataset(torch.utils.data.Dataset):
        def __init__(self, encodings, labels):
            self.encodings = encodings
            self.labels = labels
        
        def __getitem__(self, idx):
            item = {key: torch.tensor(val[idx]) for key, val in self.encodings.items()}
            item['labels'] = torch.tensor(self.labels[idx])
            return item
        
        def __len__(self):
            return len(self.labels)
    
    train_dataset = SentimentDataset(train_encodings, train_labels)
    test_dataset = SentimentDataset(test_encodings, test_labels)
    
    # 训练参数
    training_args = TrainingArguments(
        output_dir='./results',
        num_train_epochs=3,
        per_device_train_batch_size=8,
        per_device_eval_batch_size=8,
        warmup_steps=100,
        weight_decay=0.01,
        logging_dir='./logs',
        logging_steps=10,
        evaluation_strategy="epoch",
        save_strategy="epoch",
        load_best_model_at_end=True,
    )
    
    # 定义评估函数
    def compute_metrics(pred):
        labels = pred.label_ids
        preds = pred.predictions.argmax(-1)
        precision, recall, f1, _ = precision_recall_fscore_support(labels, preds, average='binary')
        acc = accuracy_score(labels, preds)
        return {
            'accuracy': acc,
            'f1': f1,
            'precision': precision,
            'recall': recall
        }
    
    # 创建Trainer
    trainer = Trainer(
        model=model,
        args=training_args,
        train_dataset=train_dataset,
        eval_dataset=test_dataset,
        compute_metrics=compute_metrics,
    )
    
    # 训练
    print("开始训练BERT模型...")
    trainer.train()
    
    # 评估
    print("\n评估结果:")
    eval_results = trainer.evaluate()
    for key, value in eval_results.items():
        print(f"  {key}: {value:.4f}")
    
    # 测试预测
    test_text = "I absolutely love this product! Best purchase ever."
    inputs = tokenizer(test_text, return_tensors="pt", truncation=True, padding=True, max_length=128)
    outputs = model(**inputs)
    prediction = torch.softmax(outputs.logits, dim=1)
    
    print(f"\n测试预测:")
    print(f"文本: {test_text}")
    print(f"正面概率: {prediction[0][1].item():.4f}")
    print(f"负面概率: {prediction[0][0].item():.4f}")

except ImportError:
    print("Transformers未安装,使用概念演示")
    
    print("\n📊 BERT文本分类流程:")
    print("   1. 加载预训练的BERT模型")
    print("   2. 添加分类头")
    print("   3. 在小规模标注数据上微调")
    print("   4. 评估和预测")
    
    # 可视化BERT分类
    fig, ax = plt.subplots(figsize=(12, 6))
    ax.axis('off')
    
    # 输入文本
    text = "This movie is fantastic!"
    ax.text(0.5, 0.85, f"输入: '{text}'", ha='center', fontsize=12,
           bbox=dict(boxstyle='round', facecolor='lightblue'))
    
    # BERT
    bert_box = plt.Rectangle((0.3, 0.5), 0.4, 0.25,
                              facecolor='lightgreen', ec='black')
    ax.add_patch(bert_box)
    ax.text(0.5, 0.625, 'BERT\n(预训练 + 微调)', ha='center', va='center', fontsize=11)
    
    # 输出
    ax.text(0.5, 0.35, '输出: 正面 (概率: 0.96)', ha='center', fontsize=12, color='green',
           bbox=dict(boxstyle='round', facecolor='lightgreen'))
    
    ax.annotate('', xy=(0.5, 0.5), xytext=(0.5, 0.75),
               arrowprops=dict(arrowstyle='->', lw=2))
    ax.annotate('', xy=(0.5, 0.35), xytext=(0.5, 0.5),
               arrowprops=dict(arrowstyle='->', lw=2))
    
    ax.set_title('BERT文本分类流程', fontsize=14)
    plt.tight_layout()
    plt.show()

四、GPT:生成式预训练

4.1 GPT的原理

python 复制代码
def visualize_gpt():
    """可视化GPT的原理"""
    
    fig, axes = plt.subplots(1, 2, figsize=(14, 6))
    
    # 1. GPT的自回归生成
    ax1 = axes[0]
    ax1.axis('off')
    ax1.set_title('GPT:自回归生成', fontsize=12)
    
    # 生成过程
    steps = [
        ("The", 0.1, 0.7),
        ("The cat", 0.3, 0.7),
        ("The cat sat", 0.5, 0.7),
        ("The cat sat on", 0.7, 0.7),
        ("The cat sat on the", 0.9, 0.7),
    ]
    
    for text, x, y in steps:
        box = plt.Rectangle((x-0.08, y-0.04), 0.16, 0.08,
                             facecolor='lightblue', ec='black')
        ax1.add_patch(box)
        ax1.text(x, y, text, ha='center', va='center', fontsize=7)
    
    # 箭头
    ax1.annotate('', xy=(0.22, 0.7), xytext=(0.18, 0.7),
                arrowprops=dict(arrowstyle='->', lw=1))
    ax1.annotate('', xy=(0.42, 0.7), xytext=(0.38, 0.7),
                arrowprops=dict(arrowstyle='->', lw=1))
    ax1.annotate('', xy=(0.62, 0.7), xytext=(0.58, 0.7),
                arrowprops=dict(arrowstyle='->', lw=1))
    ax1.annotate('', xy=(0.82, 0.7), xytext=(0.78, 0.7),
                arrowprops=dict(arrowstyle='->', lw=1))
    
    ax1.text(0.5, 0.5, '逐步生成下一个词', ha='center', fontsize=10,
            bbox=dict(boxstyle='round', facecolor='lightyellow'))
    
    # 2. GPT的应用
    ax2 = axes[1]
    ax2.axis('off')
    ax2.set_title('GPT的应用场景', fontsize=12)
    
    applications = [
        ("文本生成", "续写故事、文章"),
        ("对话系统", "ChatGPT"),
        ("代码生成", "GitHub Copilot"),
        ("翻译", "机器翻译"),
        ("摘要", "文本摘要"),
        ("问答", "回答问题")
    ]
    
    y_pos = 0.75
    for app, desc in applications:
        circle = plt.Circle((0.2, y_pos), 0.05, color='lightgreen', ec='black')
        ax2.add_patch(circle)
        ax2.text(0.2, y_pos, app[0], ha='center', va='center', fontsize=8)
        ax2.text(0.35, y_pos, f"{app}: {desc}", fontsize=10)
        y_pos -= 0.1
    
    plt.suptitle('GPT:生成式预训练模型', fontsize=14)
    plt.tight_layout()
    plt.show()
    
    print("\n📊 GPT vs BERT:")
    print("   BERT: 双向编码器 → 理解任务")
    print("   GPT: 单向解码器 → 生成任务")
    print("   共同点: 大规模预训练 + 微调")

visualize_gpt()

五、预训练模型的选择与使用

5.1 模型选择指南

python 复制代码
def model_selection_guide():
    """预训练模型选择指南"""
    
    fig, ax = plt.subplots(figsize=(12, 8))
    ax.axis('off')
    
    guide = """
    ╔══════════════════════════════════════════════════════════════════════════════════╗
    ║                         预训练模型选择指南                                        ║
    ╠══════════════════════════════════════════════════════════════════════════════════╣
    ║                                                                                  ║
    ║  任务类型         推荐模型                    理由                               ║
    ║  ─────────────────────────────────────────────────────────────────────────────── ║
    ║  文本分类         BERT, RoBERTa             双向理解,效果好                     ║
    ║  情感分析         DistilBERT                 轻量级,速度快                      ║
    ║  命名实体识别     BERT, LayoutLM            捕捉上下文边界                       ║
    ║  问答系统         BERT, ALBERT              理解问题和上下文                     ║
    ║  文本生成         GPT-2, GPT-3              自回归生成能力强                     ║
    ║  对话系统         DialoGPT, BlenderBot      专门为对话优化                       ║
    ║  代码生成         CodeGPT, CodeLlama        在代码数据上预训练                   ║
    ║  摘要生成         BART, T5                  序列到序列架构                       ║
    ║  翻译             mBART, M2M100             多语言模型                           ║
    ║  多语言任务       XLM-R, mBERT              支持多种语言                         ║
    ║                                                                                  ║
    ║  资源受限场景:                                                                   ║
    ║    - DistilBERT (体积减少40%,速度提升60%)                                       ║
    ║    - TinyBERT (体积更小,适合移动端)                                             ║
    ║    - ALBERT (参数共享,内存占用少)                                               ║
    ║                                                                                  ║
    ║  中文任务:                                                                       ║
    ║    - BERT-wwm (全词掩码,效果更好)                                              ║
    ║    - RoBERTa-wwm-ext (更大数据,更强性能)                                       ║
    ║    - ERNIE (知识增强,理解中文更好)                                              ║
    ║                                                                                  ║
    ╚══════════════════════════════════════════════════════════════════════════════════╝
    """
    
    ax.text(0.05, 0.95, guide, transform=ax.transAxes, fontsize=9,
            verticalalignment='top', fontfamily='monospace')
    ax.set_title('预训练模型选择指南', fontsize=14, pad=20)
    
    plt.tight_layout()
    plt.show()

model_selection_guide()

5.2 模型微调最佳实践

python 复制代码
def finetuning_best_practices():
    """模型微调最佳实践"""
    
    fig, axes = plt.subplots(2, 2, figsize=(14, 10))
    
    # 1. 学习率选择
    ax1 = axes[0, 0]
    ax1.axis('off')
    ax1.set_title('学习率选择', fontsize=12)
    
    lr_guide = """
    学习率建议:
    
    预训练层: 2e-5 ~ 5e-5
    分类层:   1e-4 ~ 1e-3
    
    规则:
    • 数据量大 → 学习率可以稍大
    • 数据量小 → 学习率要小
    • 使用学习率预热 (warmup)
    • 线性衰减或余弦衰减
    """
    ax1.text(0.1, 0.95, lr_guide, transform=ax1.transAxes, fontsize=10,
            verticalalignment='top', fontfamily='monospace')
    
    # 2. 数据量要求
    ax2 = axes[0, 1]
    ax2.axis('off')
    ax2.set_title('数据量要求', fontsize=12)
    
    # 数据量柱状图
    categories = ['特征提取', '微调', '从零训练']
    min_data = [100, 1000, 10000]
    colors = ['lightgreen', 'lightblue', 'lightcoral']
    
    bars = ax2.bar(categories, min_data, color=colors)
    ax2.set_ylabel('最小样本数')
    ax2.set_title('不同方法的数据需求')
    
    for bar, val in zip(bars, min_data):
        ax2.text(bar.get_x() + bar.get_width()/2, bar.get_height() + 100,
                f'{val}+', ha='center', va='bottom')
    
    # 3. 训练技巧
    ax3 = axes[1, 0]
    ax3.axis('off')
    ax3.set_title('训练技巧', fontsize=12)
    
    tips = """
    ⚡ 微调技巧:
    
    1. 分层学习率
       • 底层用较小学习率
       • 高层用较大学习率
    
    2. 梯度裁剪
       • 防止梯度爆炸
       • max_norm = 1.0
    
    3. 早停 (Early Stopping)
       • 验证集不改善时停止
       • patience = 3-5
    
    4. 混合精度训练
       • 加速训练
       • 减少显存占用
    """
    ax3.text(0.1, 0.95, tips, transform=ax3.transAxes, fontsize=10,
            verticalalignment='top', fontfamily='monospace')
    
    # 4. 评估指标
    ax4 = axes[1, 1]
    ax4.axis('off')
    ax4.set_title('评估指标', fontsize=12)
    
    metrics = """
    📊 常用评估指标:
    
    分类任务:
    • Accuracy (准确率)
    • Precision (精确率)
    • Recall (召回率)
    • F1-Score (F1分数)
    • AUC-ROC (ROC曲线下面积)
    
    生成任务:
    • BLEU (机器翻译)
    • ROUGE (摘要生成)
    • Perplexity (语言模型)
    
    问答任务:
    • EM (精确匹配)
    • F1 (单词重叠度)
    """
    ax4.text(0.1, 0.95, metrics, transform=ax4.transAxes, fontsize=10,
            verticalalignment='top', fontfamily='monospace')
    
    plt.suptitle('模型微调最佳实践', fontsize=14)
    plt.tight_layout()
    plt.show()

finetuning_best_practices()

六、实战:完整的微调流程

python 复制代码
# 完整的BERT微调示例(使用简化数据)
def complete_finetuning_demo():
    """完整的微调流程演示"""
    
    print("\n" + "=" * 60)
    print("完整的预训练模型微调流程")
    print("=" * 60)
    
    # 步骤1: 数据准备
    print("\n📁 步骤1: 准备数据")
    print("   - 收集标注数据")
    print("   - 划分训练集/验证集/测试集")
    print("   - 数据清洗和预处理")
    
    # 步骤2: 模型选择
    print("\n🤖 步骤2: 选择预训练模型")
    print("   - 根据任务类型选择模型架构")
    print("   - 考虑模型大小和资源限制")
    print("   - 加载预训练权重")
    
    # 步骤3: 模型适配
    print("\n🔧 步骤3: 适配下游任务")
    print("   - 替换输出层")
    print("   - 添加任务特定的头")
    print("   - 配置损失函数")
    
    # 步骤4: 训练配置
    print("\n⚙️ 步骤4: 配置训练参数")
    print("   - 设置学习率 (2e-5 ~ 5e-5)")
    print("   - 设置batch size (16, 32)")
    print("   - 设置epochs (2-4)")
    print("   - 配置优化器 (AdamW)")
    
    # 步骤5: 训练
    print("\n🏋️ 步骤5: 微调训练")
    print("   - 监控训练损失")
    print("   - 验证集评估")
    print("   - 保存最佳模型")
    
    # 步骤6: 评估
    print("\n📊 步骤6: 模型评估")
    print("   - 测试集性能")
    print("   - 错误分析")
    print("   - 模型导出")
    
    # 可视化整个流程
    fig, ax = plt.subplots(figsize=(12, 4))
    ax.axis('off')
    
    steps = [
        ("数据准备", 0.1),
        ("模型选择", 0.3),
        ("模型适配", 0.5),
        ("训练配置", 0.7),
        ("微调训练", 0.9)
    ]
    
    for step, x in steps:
        circle = plt.Circle((x, 0.5), 0.08, color='lightblue', ec='black')
        ax.add_patch(circle)
        ax.text(x, 0.5, step, ha='center', va='center', fontsize=8)
        
        if x < 0.85:
            ax.annotate('', xy=(x+0.18, 0.5), xytext=(x+0.1, 0.5),
                       arrowprops=dict(arrowstyle='->', lw=2))
    
    ax.set_xlim(0, 1)
    ax.set_ylim(0, 1)
    ax.set_title('预训练模型微调完整流程', fontsize=14)
    plt.tight_layout()
    plt.show()

complete_finetuning_demo()

七、大语言模型(LLM)时代

7.1 LLM的关键技术

python 复制代码
def visualize_llm_techniques():
    """可视化大语言模型的关键技术"""
    
    fig, axes = plt.subplots(2, 2, figsize=(14, 10))
    
    # 1. 指令微调
    ax1 = axes[0, 0]
    ax1.axis('off')
    ax1.set_title('指令微调 (Instruction Tuning)', fontsize=11)
    
    examples = [
        ("分类", "将这句话分类为正面或负面: '太棒了!' → 正面"),
        ("翻译", "将'Hello'翻译成中文 → '你好'"),
        ("摘要", "总结: '今天天气很好...' → '天气晴朗'"),
        ("问答", "回答: '中国的首都是?' → '北京'")
    ]
    
    y_pos = 0.8
    for task, example in examples:
        ax1.text(0.1, y_pos, f"• {task}:", fontsize=9, fontweight='bold')
        ax1.text(0.25, y_pos, example, fontsize=8)
        y_pos -= 0.12
    
    # 2. RLHF
    ax2 = axes[0, 1]
    ax2.axis('off')
    ax2.set_title('RLHF (人类反馈强化学习)', fontsize=11)
    
    # 流程图
    steps = ['模型生成', '人类评估', '奖励模型', '强化学习']
    y_pos = 0.7
    for i, step in enumerate(steps):
        box = plt.Rectangle((0.2, y_pos-0.05), 0.6, 0.1,
                             facecolor='lightgreen', ec='black')
        ax2.add_patch(box)
        ax2.text(0.5, y_pos, step, ha='center', va='center', fontsize=9)
        
        if i < 3:
            ax2.annotate('', xy=(0.5, y_pos-0.05), xytext=(0.5, y_pos-0.1),
                        arrowprops=dict(arrowstyle='->', lw=1))
        y_pos -= 0.15
    
    # 3. 上下文学习
    ax3 = axes[1, 0]
    ax3.axis('off')
    ax3.set_title('上下文学习 (In-Context Learning)', fontsize=11)
    
    # Few-shot示例
    ax3.text(0.1, 0.85, "示例:", fontsize=9, fontweight='bold')
    ax3.text(0.1, 0.75, "输入: '我喜欢这个电影' → 情感: 正面", fontsize=8)
    ax3.text(0.1, 0.65, "输入: '太无聊了' → 情感: 负面", fontsize=8)
    ax3.text(0.1, 0.55, "输入: '非常棒的产品' → 情感:", fontsize=9, fontweight='bold')
    ax3.text(0.1, 0.45, "模型预测: 正面", fontsize=9, color='green')
    
    # 4. 思维链
    ax4 = axes[1, 1]
    ax4.axis('off')
    ax4.set_title('思维链 (Chain-of-Thought)', fontsize=11)
    
    cot_example = """
    问题: 小明有5个苹果,给了小红2个,
          又买了3个,现在有多少个苹果?
    
    思考过程:
    1. 开始有5个苹果
    2. 给小红2个: 5 - 2 = 3
    3. 又买3个: 3 + 3 = 6
    
    答案: 6个苹果
    """
    ax4.text(0.1, 0.9, cot_example, fontsize=8, verticalalignment='top',
            fontfamily='monospace')
    
    plt.suptitle('大语言模型(LLM)的关键技术', fontsize=14)
    plt.tight_layout()
    plt.show()

visualize_llm_techniques()

八、学习检查清单

基础概念

  • 理解迁移学习的原理
  • 知道预训练模型的优势
  • 掌握BERT的预训练任务
  • 理解GPT的自回归生成

实践技能

  • 会用Hugging Face加载模型
  • 能微调BERT到下游任务
  • 知道如何选择预训练模型
  • 掌握模型评估方法

进阶知识

  • 了解RLHF的原理
  • 理解指令微调的作用
  • 知道思维链技术
  • 关注LLM的最新发展

九、总结

预训练模型的核心价值:

方面 传统方法 预训练模型
数据需求 大量标注数据 少量标注数据
训练时间 数周 数小时
计算资源 多GPU 单GPU
性能 依赖数据量 通常更好
可迁移性

使用流程:

复制代码
选择预训练模型 → 加载模型和分词器 → 
适配下游任务 → 微调训练 → 评估部署

记住:

  • 预训练模型是AI的"基础教育"
  • 微调是"专业培训"
  • 不要每次都从零开始
  • 站在巨人的肩膀上
相关推荐
RInk7oBjo2 小时前
多Agent编排时代 · OpenAI × Anthropic 跨生态协作
人工智能
Yuanxl9032 小时前
PyTorch模型训练全流程详解
人工智能·pytorch·深度学习
码农的神经元2 小时前
从零搭建一个带 GUI 的机器学习建模系统:多模型切换、遗传算法优化与可视化实战复盘
人工智能·机器学习
一楼的猫2 小时前
茄子小说AI辅助智能写作助手:10倍速创作神器
人工智能·学习·机器学习·学习方法·ai写作·迁移学习·集成学习
懂AI的老郑2 小时前
人工智能手机的构建思路:从架构到实现
人工智能·智能手机·架构
思绪无限2 小时前
YOLOv5至YOLOv12升级:交通信号灯识别系统的设计与实现(完整代码+界面+数据集项目)
深度学习·yolo·目标检测·交通信号灯识别·yolov12·yolo全家桶
gjhave2 小时前
强化学习论文(Double-DQN)
人工智能·机器学习
rADu REME2 小时前
rust web框架actix和axum比较
前端·人工智能·rust
Mark-Han2 小时前
AI产品的定价是一门玄学
人工智能
BizViewStudio2 小时前
GEO vs SEO vs SEM:2026 年品牌流量获取的三元格局分析
大数据·运维·网络·人工智能·ai