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的"基础教育"
  • 微调是"专业培训"
  • 不要每次都从零开始
  • 站在巨人的肩膀上
相关推荐
奔跑中的小象2 小时前
统信UOS + 天数AI卡部署SGLang服务手册
人工智能·uos·sglang·天数智芯
DevSecOps选型指南2 小时前
中国版Mythos,为何是悬镜安全灵脉CodeAI?
人工智能·安全
Shockang3 小时前
LangGraph 状态机实战
人工智能
刹那芳华19923 小时前
循环神经网络的从零开始实现(RNN)
人工智能·rnn·深度学习
阿童木写作3 小时前
跨境图片翻译工具多合一,批量图片视频字幕翻译加智能抠图
人工智能·python·音视频·语音识别
科技之门3 小时前
AI3D从建模到贴图、绑骨和动画的完整流程怎么做?V2Fun完整工作流指南
人工智能·3d·贴图
宇宙第一小趴菜3 小时前
二、机器学习的应用领域和发展史
人工智能·机器学习
前端开发江鸟3 小时前
我写过 MCP Server,却一直以为 MCP 只有 Tool
人工智能
天国梦3 小时前
自习室智能化升级避坑指南:天学网AI智习室方案实测与选型建议
大数据·人工智能
阿里云云原生4 小时前
可用性从 99.9% 跃升至 99.995%:畅捷通如何用 AI 重塑运维底座?
运维·网络·人工智能