使用skorch实现迁移学习的完整指南

使用skorch实现迁移学习的完整指南

skorch skorch 项目地址: https://gitcode.com/gh_mirrors/sko/skorch

什么是迁移学习

迁移学习(Transfer Learning)是机器学习中一种重要的技术,它允许我们将一个预训练模型的知识迁移到新的任务上。这种方法特别适用于深度学习领域,因为从头开始训练深度神经网络通常需要大量数据和计算资源。

在计算机视觉领域,迁移学习尤为常见。我们可以利用在大型数据集(如ImageNet)上预训练的模型,通过微调(fine-tuning)或特征提取(feature extraction)的方式,将其应用于新的、通常规模较小的数据集上。

skorch项目简介

skorch是一个将PyTorch与scikit-learn无缝集成的Python库,它提供了scikit-learn风格的API来训练PyTorch神经网络。这使得我们可以利用scikit-learn强大的工具生态系统(如网格搜索、管道等)来处理PyTorch模型。

准备工作

安装必要的库

在开始之前,我们需要确保安装了以下Python库:

  • torch
  • torchvision
  • skorch
  • numpy

数据集介绍

本教程使用的是蚂蚁和蜜蜂的二分类数据集,包含:

  • 训练集:每个类别120张图片
  • 验证集:每个类别75张图片

数据集已经预先划分为训练集和验证集,这有助于我们评估模型的泛化能力。

数据预处理

数据增强

对于训练数据,我们应用了以下增强技术:

  • 随机裁剪到224x224大小
  • 随机水平翻转

这些技术有助于增加数据的多样性,防止模型过拟合。

数据标准化

所有图像都进行了标准化处理,使用了ImageNet数据集的均值和标准差:

  • 均值:[0.485, 0.456, 0.406]
  • 标准差:[0.229, 0.224, 0.225]

使用这些特定值是因为我们的预训练模型是在ImageNet上训练的,保持一致的预处理有助于模型更好地工作。

构建预训练模型

我们使用ResNet18作为基础模型,这是一个在ImageNet上预训练的中等规模卷积神经网络。

class PretrainedModel(nn.Module):
    def __init__(self, output_features):
        super().__init__()
        model = models.resnet18(pretrained=True)
        num_ftrs = model.fc.in_features
        model.fc = nn.Linear(num_ftrs, output_features)
        self.model = model
        
    def forward(self, x):
        return self.model(x)

关键点:

  1. 我们保留了除最后一层外的所有预训练权重
  2. 替换了最后的全连接层以适应我们的二分类任务
  3. 输出特征数设为2(蚂蚁和蜜蜂两个类别)

使用skorch配置训练

学习率调度器

我们使用StepLR调度器,每7个epoch将学习率乘以0.1:

from skorch.callbacks import LRScheduler

lrscheduler = LRScheduler(
    policy='StepLR', step_size=7, gamma=0.1)

这种学习率衰减策略有助于模型在训练后期更精细地调整权重。

模型检查点

设置检查点回调以保存最佳模型:

from skorch.callbacks import Checkpoint

checkpoint = Checkpoint(
    f_params='best_model.pt', monitor='valid_acc_best')

这会监控验证集准确率,并在达到新高时保存模型。

冻结层

我们冻结了除最后一层外的所有权重:

from skorch.callbacks import Freezer

freezer = Freezer(lambda x: not x.startswith('model.fc'))

这种策略称为"特征提取",即只训练新添加的分类层,而保持预训练特征提取器的权重不变。

完整的神经网络分类器

将所有组件组合起来:

net = NeuralNetClassifier(
    PretrainedModel, 
    criterion=nn.CrossEntropyLoss,
    lr=0.001,
    batch_size=4,
    max_epochs=25,
    module__output_features=2,
    optimizer=optim.SGD,
    optimizer__momentum=0.9,
    iterator_train__shuffle=True,
    iterator_train__num_workers=2,
    iterator_valid__num_workers=2,
    train_split=predefined_split(val_ds),
    callbacks=[lrscheduler, checkpoint, freezer],
    device='cuda'
)

配置详解:

  • 使用交叉熵损失函数
  • 初始学习率0.001
  • 批量大小4(可根据GPU内存调整)
  • 训练25个epoch
  • 使用带动量的SGD优化器
  • 启用数据加载器的多线程
  • 使用验证集进行模型选择
  • 在GPU上训练(如果可用)

训练过程分析

从训练日志可以看到:

  1. 初始验证准确率就很高(94.77%),这得益于预训练模型的特征提取能力
  2. 随着训练进行,损失持续下降
  3. 第5个epoch达到最高验证准确率96.08%
  4. 学习率在第7个epoch后下降,导致训练损失变化趋缓

这种表现说明:

  • 迁移学习非常有效,即使只训练最后一层也能获得很好的结果
  • 预训练模型已经学习到了通用的图像特征
  • 我们的微调策略是合适的

实际应用建议

  1. 数据量较小时:建议冻结大多数层,只训练最后的分类层
  2. 数据量适中时:可以解冻更多层进行微调
  3. 计算资源有限时:考虑使用更小的预训练模型(如ResNet18而非ResNet50)
  4. 不同领域数据:如果新数据与预训练数据差异很大,可能需要解冻更多层

常见问题解决

  1. 过拟合:增加数据增强、使用更小的学习率、添加Dropout层
  2. 训练不稳定:减小学习率、增大批量大小、使用学习率预热
  3. 内存不足:减小批量大小、使用更小的模型、尝试混合精度训练

总结

通过本教程,我们学习了如何使用skorch实现迁移学习。关键点包括:

  1. 利用预训练模型作为特征提取器
  2. 替换并训练最后的分类层
  3. 使用skorch的简洁API配置训练过程
  4. 应用各种回调函数增强训练控制

迁移学习是深度学习实践中极其重要的技术,而skorch使得这一过程更加简单和可维护。希望本教程能帮助你快速上手迁移学习在实际项目中的应用。

skorch skorch 项目地址: https://gitcode.com/gh_mirrors/sko/skorch

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

高崴功Victorious

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值