🎯 学习目标

  • 理解迁移学习的原理和优势
  • 掌握预训练模型的使用方法
  • 学会微调(Fine-tuning)策略
  • 了解特征提取与端到端训练的区别
迁移学习概念

什么是迁移学习

迁移学习(Transfer Learning)是将在大规模数据集(如ImageNet)上训练好的模型, 迁移应用到新的任务上。由于预训练模型已学习到丰富的通用特征,迁移学习可以显著减少训练数据需求和时间, 并在新任务上取得更好的性能。

💡 为什么迁移学习有效

底层特征通用性

卷积神经网络的不同层学习不同层次的特征:

  • 浅层:边缘、纹理、颜色等基础特征
  • 中层:局部形状、图案组合
  • 深层:语义级别的高级特征

迁移学习优势

  • 减少训练数据需求
  • 加速模型收敛
  • 提升模型性能
  • 降低计算成本

📊 迁移学习策略

策略 特征提取器 分类器 适用场景
特征提取 冻结,不更新 随机初始化,训练更新 小数据集,目标任务与预训练相似
微调 小学习率更新 正常学习率更新 中等数据集,目标任务与预训练相关
端到端训练 全部更新 全部更新 大数据集,目标任务差异大

💻 策略一:特征提取

import torch import torch.nn as nn import torchvision.models as models # 加载预训练ResNet-50 model = models.resnet50(pretrained=True) # 冻结所有卷积层参数 for param in model.parameters(): param.requires_grad = False # 替换最后的全连接层 num_features = model.fc.in_features model.fc = nn.Linear(num_features, 10) # 10分类任务 # 只有fc层的参数会被更新 optimizer = torch.optim.Adam(model.fc.parameters(), lr=0.001) # 查看可训练参数 trainable_params = sum(p.numel() for p in model.parameters() if p.requires_grad) print(f'可训练参数: {trainable_params}') # 仅约2万参数

🔧 策略二:微调训练

# 加载预训练模型 model = models.resnet50(pretrained=True) # 替换分类层 num_features = model.fc.in_features model.fc = nn.Linear(num_features, 10) # 为不同层设置不同学习率 params = [ {'params': model.conv1.parameters(), 'lr': 1e-5}, # 浅层小学习率 {'params': model.layer1.parameters(), 'lr': 1e-4}, {'params': model.layer2.parameters(), 'lr': 1e-4}, {'params': model.layer3.parameters(), 'lr': 1e-3}, {'params': model.layer4.parameters(), 'lr': 1e-3}, {'params': model.fc.parameters(), 'lr': 1e-2}, # 分类层大学习率 ] optimizer = torch.optim.Adam(params) # 或者使用更简单的方式:分类层更大学习率 optimizer = torch.optim.Adam([ {'params': model.fc.parameters(), 'lr': 0.01}, {'params': [p for n, p in model.named_parameters() if 'fc' not in n], 'lr': 0.001} ])

🌐 完整迁移学习示例

import torch import torch.nn as nn import torchvision.models as models import torchvision.transforms as transforms from torchvision.datasets import ImageFolder from torch.utils.data import DataLoader # 数据预处理(使用ImageNet标准化) transform = { 'train': transforms.Compose([ transforms.RandomResizedCrop(224), transforms.RandomHorizontalFlip(), transforms.ToTensor(), transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]) ]), 'val': transforms.Compose([ transforms.Resize(256), transforms.CenterCrop(224), transforms.ToTensor(), transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]) ]) } # 加载自定义数据集 train_dataset = ImageFolder('data/train', transform=transform['train']) val_dataset = ImageFolder('data/val', transform=transform['val']) train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True) val_loader = DataLoader(val_dataset, batch_size=32) # 创建模型 model = models.resnet50(pretrained=True) num_classes = len(train_dataset.classes) model.fc = nn.Linear(model.fc.in_features, num_classes) # 训练配置 device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') model = model.to(device) criterion = nn.CrossEntropyLoss() optimizer = torch.optim.Adam(model.parameters(), lr=0.001) scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=7, gamma=0.1)

📈 不同预训练模型对比

模型 参数量 Top-1准确率 推理速度 推荐场景
ResNet-18 11M 69.8% 快速原型、资源受限
ResNet-50 25M 76.1% 通用场景首选
EfficientNet-B0 5M 77.1% 移动端、边缘设备
EfficientNet-B4 19M 82.9% 高精度需求
ViT-B/16 86M 81.8% 大数据集、研究

🎨 迁移学习最佳实践

数据量 vs 策略

  • 小数据(<1k):特征提取
  • 中数据(1k-10k):微调
  • 大数据(>10k):端到端训练

学习率设置

  • 预训练层:小学习率(1e-4~1e-5)
  • 新分类层:大学习率(1e-3~1e-2)
  • 使用学习率预热
💡
实用建议

迁移学习时,务必使用与预训练模型相同的标准化参数。ImageNet预训练模型的标准参数为:mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]。

迁移学习应用
图:迁移学习让模型站在巨人的肩膀上

📝 本节小结

  • • 迁移学习利用预训练模型的通用特征,减少数据需求和训练时间
  • • 特征提取策略冻结卷积层,仅训练分类层,适合小数据集
  • • 微调策略更新所有层,但预训练层使用较小学习率
  • • 不同任务相似度、数据量决定策略选择
  • • torchvision.models提供丰富的预训练模型