温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Python深度学习迁移学习

发布时间:2025-10-03 01:01:51 来源:亿速云 阅读:112 作者:小樊 栏目:编程语言

Python深度学习迁移学习:核心概念与实践指南
迁移学习是深度学习中利用预训练模型(在大规模数据集如ImageNet上训练好的模型)的知识,迁移到新任务的技术,旨在解决数据不足、计算资源有限等问题,显著提升模型性能。其核心思想是“知识转移”——预训练模型的底层网络能提取通用特征(如边缘、纹理),而顶层网络针对源任务设计,新任务可通过保留通用特征并微调顶层适应自身需求。

一、迁移学习的核心策略

  1. 特征提取(Feature Extraction):冻结预训练模型的大部分层(保持参数不变),仅训练新添加的顶层(如全连接层)。这种方法适用于新任务与源任务差异较大的情况,能保留预训练模型的通用特征,避免过拟合。
  2. 微调(Fine-tuning):解冻预训练模型的部分或全部层,在新数据集上继续训练。通常用于新任务与源任务相似的情况,通过微调让模型适应新数据的分布,进一步提升性能。

二、Python实现迁移学习的关键步骤

1. 准备数据集

数据集需分为训练集、验证集和测试集(如8:1:1),并进行预处理:

  • 图像任务:调整图像大小(如ResNet要求224x224)、归一化(使用ImageNet的均值[0.485, 0.456, 0.406]和标准差[0.229, 0.224, 0.225])、数据增强(随机翻转、旋转、裁剪);
  • 文本任务:分词、构建词表、转换为索引序列。

2. 选择预训练模型

根据任务类型选择合适的预训练模型:

  • 图像分类:VGG16/19(适合中小尺寸图像)、ResNet(残差结构,适合深层网络)、EfficientNet(高效轻量化);
  • 文本分类:BERT(双向Transformer,适合理解任务)、GPT(自回归Transformer,适合生成任务)。

3. 修改模型架构

  • 加载预训练模型(如torchvision.models.resnet18(pretrained=True)tensorflow.keras.applications.VGG16(weights='imagenet', include_top=False));
  • 替换顶层:根据新任务的类别数修改最后一层(如ResNet的fc层替换为nn.Linear(in_features, num_classes),VGG的Flatten后添加Dense(256, activation='relu')Dense(num_classes, activation='softmax'))。

4. 编译模型

设置损失函数、优化器和评估指标:

  • 图像分类:损失函数用CrossEntropyLoss(多分类),优化器用Adam(学习率0.001)或SGD(学习率0.01,动量0.9);
  • 文本分类:损失函数用CrossEntropyLoss,优化器用AdamW(学习率2e-5);
  • 评估指标:准确率(accuracy)、精确率(precision)、召回率(recall)。

5. 训练模型

  • 特征提取:冻结预训练模型的层(layer.trainable = False),仅训练新添加的顶层;
  • 微调:解冻部分层(如ResNet的layer4),用较小的学习率(如0.0001)继续训练;
  • 训练过程:使用model.fit()(TensorFlow)或trainer.train()(PyTorch Lightning)迭代训练,监控验证集性能。

6. 评估与调优

在测试集上评估模型性能,若效果不佳,可调整:

  • 学习率(如使用StepLR调度器降低学习率);
  • 微调层数(如增加解冻层数);
  • 数据增强(如增加随机裁剪、颜色抖动)。

三、Python实现迁移学习的代码示例

1. TensorFlow/Keras实现(图像分类,ResNet50)

import tensorflow as tf
from tensorflow.keras.applications import ResNet50
from tensorflow.keras.layers import Dense, GlobalAveragePooling2D
from tensorflow.keras.models import Model
from tensorflow.keras.preprocessing.image import ImageDataGenerator

# 数据预处理
train_datagen = ImageDataGenerator(
    rescale=1./255,
    shear_range=0.2,
    zoom_range=0.2,
    horizontal_flip=True
)
train_generator = train_datagen.flow_from_directory(
    'data/train',
    target_size=(224, 224),
    batch_size=32,
    class_mode='categorical'
)

# 加载预训练模型(不含顶层)
base_model = ResNet50(weights='imagenet', include_top=False, input_shape=(224, 224, 3))

# 冻结预训练模型层
for layer in base_model.layers:
    layer.trainable = False

# 添加新顶层
x = base_model.output
x = GlobalAveragePooling2D()(x)
x = Dense(256, activation='relu')(x)
predictions = Dense(10, activation='softmax')(x)  # 假设10个类别

# 构建模型
model = Model(inputs=base_model.input, outputs=predictions)

# 编译模型
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])

# 训练模型(特征提取)
model.fit(train_generator, epochs=10, steps_per_epoch=100)

2. PyTorch实现(图像分类,ResNet18)

import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import models, transforms
from torch.utils.data import DataLoader
from torchvision.datasets import ImageFolder

# 数据预处理
transform = transforms.Compose([
    transforms.RandomResizedCrop(224),
    transforms.RandomHorizontalFlip(),
    transforms.ToTensor(),
    transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
])
train_dataset = ImageFolder(root='data/train', transform=transform)
train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)

# 加载预训练模型
model = models.resnet18(weights=models.ResNet18_Weights.DEFAULT)

# 冻结预训练模型层
for param in model.parameters():
    param.requires_grad = False

# 修改顶层
num_features = model.fc.in_features
model.fc = nn.Linear(num_features, 10)  # 假设10个类别

# 定义损失函数和优化器
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(filter(lambda p: p.requires_grad, model.parameters()), lr=0.001)

# 训练模型(特征提取)
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model.to(device)
for epoch in range(10):
    model.train()
    running_loss = 0.0
    for inputs, labels in train_loader:
        inputs, labels = inputs.to(device), labels.to(device)
        optimizer.zero_grad()
        outputs = model(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()
        running_loss += loss.item()
    print(f'Epoch {epoch+1}, Loss: {running_loss/len(train_loader)}')

四、迁移学习的注意事项

  • 数据相关性:预训练数据与新任务数据需相关(如ImageNet预训练模型用于自然图像分类,而非医学图像);
  • 过拟合:冻结层过多可能导致欠拟合,微调时可逐步解冻层;
  • 学习率:微调时使用较小的学习率(如0.0001),避免破坏预训练模型的通用特征;
  • 计算资源:预训练模型较大时,需足够的GPU内存(如ResNet101需更多内存)。
向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI