AI第一天 自我理解笔记--微调大模型

目录

[1. 确定目标:明确任务和数据](#1. 确定目标:明确任务和数据)

[2. 选择预训练模型](#2. 选择预训练模型)

[3. 数据预处理](#3. 数据预处理)

[(1) 数据清洗与格式化](#(1) 数据清洗与格式化)

[(2) 划分数据集](#(2) 划分数据集)

[(3) 数据加载与批处理](#(3) 数据加载与批处理)

[4. 构建微调模型架构](#4. 构建微调模型架构)

[(1) 加载预训练模型](#(1) 加载预训练模型)

[(2) 修改模型尾部(适配任务)](#(2) 修改模型尾部(适配任务))

[(3) 冻结部分层(可选)](#(3) 冻结部分层(可选))

[5. 设置超参数](#5. 设置超参数)

[(1) 优化器与学习率](#(1) 优化器与学习率)

[(2) 损失函数](#(2) 损失函数)

[(3) 其他超参数](#(3) 其他超参数)

[6. 微调模型](#6. 微调模型)

[(1) 定义训练循环](#(1) 定义训练循环)

[(2) 监控训练过程](#(2) 监控训练过程)

[7. 调整超参数(可选)](#7. 调整超参数(可选))

[8. 评估与部署](#8. 评估与部署)

[(1) 模型评估](#(1) 模型评估)

[(2) 部署模型](#(2) 部署模型)

[9. 常见问题与解决方案](#9. 常见问题与解决方案)

[(1) 过拟合](#(1) 过拟合)

[(2) 欠拟合](#(2) 欠拟合)

[(3) 计算资源不足](#(3) 计算资源不足)

[10. 总结:微调的流程图](#10. 总结:微调的流程图)

附录:代码示例(文本分类)

关键点回顾


1. 确定目标:明确任务和数据

  • 任务类型
    确定你要解决的问题类型,例如:
    • 文本分类(如情感分析)
    • 图像分类(如识别猫狗)
    • 序列生成(如文本生成或机器翻译)
  • 数据集
    收集或准备与任务相关的数据集,并进行初步分析:
    • 数据规模(样本数量、类别分布)
    • 数据质量(是否有噪声、缺失值、标签错误)
    • 数据预处理需求(如文本清洗、图像归一化)

2. 选择预训练模型

  • 预训练模型
    根据任务选择合适的预训练模型:
    • 文本任务:BERT、RoBERTa、GPT、T5
    • 图像任务:ResNet、EfficientNet、ViT
    • 多模态任务:CLIP、Mixture of Experts(MoE)
  • 模型来源
    常用的模型库包括:
    • Hugging Face (如transformers库)
    • PyTorch/TensorFlow官方模型库
    • Timm库(针对计算机视觉)

3. 数据预处理

(1) 数据清洗与格式化
  • 文本数据
    • 去除特殊字符、停用词
    • 统一大小写(如全小写)
    • 处理缺失值或异常标签
  • 图像数据
    • 调整尺寸(如统一为224x224)
    • 归一化(如将像素值缩放到[0,1]或[-1,1])
    • 数据增强(如旋转、翻转、裁剪)
(2) 划分数据集
  • 训练集:用于模型训练(通常占80%)。
  • 验证集:用于调参和监控过拟合(通常占10%)。
  • 测试集:最终评估模型性能(通常占10%)。
(3) 数据加载与批处理
  • 使用DataLoader(PyTorch)或tf.data(TensorFlow)将数据分批次加载:

    复制代码

    python

    深色版本

    复制代码
    from torch.utils.data import DataLoader, Dataset
    
    class MyDataset(Dataset):
        def __init__(self, data, labels):
            self.data = data
            self.labels = labels
    
        def __len__(self):
            return len(self.data)
    
        def __getitem__(self, idx):
            return self.data[idx], self.labels[idx]
    
    train_dataset = MyDataset(train_data, train_labels)
    train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)

4. 构建微调模型架构

(1) 加载预训练模型
  • 文本模型示例(Hugging Face)

    复制代码

    python

    深色版本

    复制代码
    from transformers import BertModel, BertConfig
    
    model = BertModel.from_pretrained("bert-base-uncased")
  • 图像模型示例(PyTorch)

    复制代码

    python

    深色版本

    复制代码
    import torchvision.models as models
    
    model = models.resnet18(pretrained=True)
(2) 修改模型尾部(适配任务)
  • 分类任务 :替换最后一层全连接层(全连接层的输出维度需匹配任务类别数):

    复制代码

    python

    深色版本

    复制代码
    # 对于ResNet:
    num_features = model.fc.in_features
    model.fc = nn.Linear(num_features, num_classes)  # num_classes是目标类别数
    
    # 对于BERT:
    model.classifier = nn.Linear(model.config.hidden_size, num_classes)
(3) 冻结部分层(可选)
  • 冻结预训练层 :保留底层的通用特征提取能力,只训练新增层:

    复制代码

    python

    深色版本

    复制代码
    for param in model.parameters():
        param.requires_grad = False  # 冻结所有层
    
    # 解冻最后一层(如分类层)
    for param in model.fc.parameters():  # 对BERT可能是model.classifier.parameters()
        param.requires_grad = True

5. 设置训练参数

(1) 优化器与学习率
  • 选择优化器

    • 常用优化器:Adam、AdamW、SGD

    • 示例:

      复制代码

      python

      深色版本

      复制代码
      optimizer = torch.optim.Adam(model.parameters(), lr=2e-5)
  • 学习率(Learning Rate)

    • 预训练模型微调时,学习率通常比从头训练低(如1e-5到1e-3)。
    • 可使用学习率调度器(如torch.optim.lr_scheduler.CosineAnnealingLR)。
(2) 损失函数
  • 根据任务选择损失函数:
    • 分类任务 :交叉熵损失(nn.CrossEntropyLoss
    • 回归任务 :均方误差(nn.MSELoss
    • 生成任务:交叉熵或自定义损失(如BERT的MLM损失)
(3) 其他超参数
  • 批量大小(Batch Size):根据硬件限制选择(如32、64、128)。
  • 训练轮次(Epochs):通常5-20轮,根据验证集表现调整。
  • 早停(Early Stopping):当验证损失不再下降时停止训练,防止过拟合。

6. 训练模型

(1) 定义训练循环
复制代码

python

深色版本

复制代码
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model.to(device)

for epoch in range(num_epochs):
    model.train()
    total_loss = 0
    for batch in train_loader:
        inputs, labels = batch
        inputs, labels = inputs.to(device), labels.to(device)

        optimizer.zero_grad()
        outputs = model(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()

        total_loss += loss.item()
    
    # 验证阶段
    model.eval()
    val_loss = 0
    with torch.no_grad():
        for batch in val_loader:
            inputs, labels = batch
            inputs, labels = inputs.to(device), labels.to(device)
            outputs = model(inputs)
            val_loss += criterion(outputs, labels).item()
    
    print(f"Epoch {epoch+1}, Train Loss: {total_loss/len(train_loader)}, Val Loss: {val_loss/len(val_loader)}")
(2) 监控训练过程
  • 使用工具如TensorBoardWeights & Biases记录损失、准确率等指标。

  • 定期保存模型检查点(Checkpoint):

    复制代码

    python

    深色版本

    复制代码
    torch.save(model.state_dict(), f"model_epoch{epoch}.pth")

7. 调整超参数(可选)

  • 网格搜索(Grid Search)或随机搜索(Random Search)
    调整学习率、批量大小、层冻结策略等。
  • 自动化工具
    使用OptunaRay Tune进行超参数优化。

8. 评估与部署

(1) 模型评估
  • 在测试集上评估最终性能:

    复制代码

    python

    深色版本

    复制代码
    model.eval()
    test_loss = 0
    correct = 0
    with torch.no_grad():
        for data, target in test_loader:
            data, target = data.to(device), target.to(device)
            output = model(data)
            test_loss += criterion(output, target).item()
            pred = output.argmax(dim=1, keepdim=True)
            correct += pred.eq(target.view_as(pred)).sum().item()
    
    print(f"Test Accuracy: {100. * correct / len(test_loader.dataset)}%")
(2) 部署模型
  • 导出模型为ONNX格式或使用框架工具(如TorchScript):

    复制代码

    python

    深色版本

    复制代码
    torch.onnx.export(model, torch.randn(1, 3, 224, 224), "model.onnx")

9. 常见问题与解决方案

(1) 过拟合
  • 解决方法
    • 增加数据增强(如随机裁剪、翻转)。
    • 添加正则化(如Dropout、L2正则化)。
    • 减少模型复杂度或训练轮次。
(2) 欠拟合
  • 解决方法
    • 增加训练轮次或学习率。
    • 解冻更多层(释放模型潜力)。
    • 尝试更复杂的模型架构。
(3) 计算资源不足
  • 解决方法
    • 使用小批量(如batch_size=16)。
    • 使用模型量化或知识蒸馏(Knowledge Distillation)。
    • 选择轻量级模型(如MobileNet、DistilBERT)。

10. 总结:微调的流程图

复制代码

深色版本

复制代码
1. 确定任务和数据 →  
2. 选择预训练模型 →  
3. 数据预处理 →  
4. 修改模型尾部 →  
5. 设置超参数 →  
6. 训练并监控 →  
7. 调参优化 →  
8. 评估与部署

附录:代码示例(文本分类)

以下是一个完整的微调BERT进行文本分类的代码框架:

复制代码

python

深色版本

复制代码
import torch
from transformers import BertTokenizer, BertForSequenceClassification
from torch.utils.data import Dataset, DataLoader

# 加载预训练模型和分词器
model_name = "bert-base-uncased"
tokenizer = BertTokenizer.from_pretrained(model_name)
model = BertForSequenceClassification.from_pretrained(model_name, num_labels=num_classes)

# 数据预处理
class TextDataset(Dataset):
    def __init__(self, texts, labels):
        self.encodings = tokenizer(texts, truncation=True, padding=True, max_length=512)
        self.labels = labels

    def __len__(self):
        return len(self.labels)

    def __getitem__(self, idx):
        item = {k: torch.tensor(v[idx]) for k, v in self.encodings.items()}
        item["labels"] = torch.tensor(self.labels[idx])
        return item

# 加载数据
train_dataset = TextDataset(train_texts, train_labels)
train_loader = DataLoader(train_dataset, batch_size=8, shuffle=True)

# 训练配置
device = torch.device("cuda")
model.to(device)
optimizer = torch.optim.AdamW(model.parameters(), lr=2e-5)
criterion = nn.CrossEntropyLoss()

# 训练循环(参考步骤6)

关键点回顾

  • 微调的核心:利用预训练模型的通用特征,仅针对特定任务调整部分参数。
  • 数据质量:垃圾进,垃圾出(Garbage In, Garbage Out)。
  • 超参数调优:学习率、批量大小、层冻结策略是关键。
相关推荐
訾博ZiBo19 分钟前
AI日报 - 2025年3月20日
人工智能
WBingJ38 分钟前
深度学习零碎知识
人工智能·机器学习
gzgenius43 分钟前
独立部署DeepSeek 大语言模型(如 DeepSeek Coder、DeepSeek LLM)可以采用什么框架?
人工智能·学习·架构·deepseek
qq_5085760943 分钟前
LLM(大型语言模型) 和 VLM(视觉语言模型)
人工智能·语言模型·自然语言处理
智哪儿44 分钟前
家庭摄像头:如何正确守护安全而非制造隐私危机?
人工智能·智能家居
金智维科技官方1 小时前
AI Agent如何通过自然语言处理提升交互体验
人工智能·自然语言处理
kngines1 小时前
从零构建大语言模型全栈开发指南:第一部分:数学与理论基础-1.1.1语言模型演进:从N-gram到Transformer
人工智能·transformer·n-gram·提示工程·moe·大预言模型·混合专家
墨绿色的摆渡人1 小时前
pytorch小记(十):pytorch中torch.tril 和 torch.triu 详解
人工智能·pytorch·python
我是大咖1 小时前
c语言笔记 结构体内嵌套结构体的表示方式
笔记
Shawn_Shawn1 小时前
从 0 到 1:机器学习小白的起航指南
人工智能·机器学习