pytorch之迁移学习

article/2025/10/12 23:11:57

文章目录

      • 1.导入相关的包
      • 2.加载数据
      • 3.可视化部分图像数据
      • 4.训练模型
      • 5.可视化模型的预测结果
      • 6.场景1:微调ConvNet
      • 7.场景2:ConvNet作为固定特征提取器

实际中,基本没有人会从零开始(随机初始化)训练一个完整的卷积网络,因为相对于网络,很难得到一个足够大的数据集[网络很深, 需要足够大数据集]。通常的做法是在一个很大的数据集上进行预训练得到卷积网络ConvNet, 然后将这个ConvNet的参数作为目标任务的初始化参数或者固定这些参数。

转移学习的两个主要场景:

  • 微调Convnet:使用预训练的网络(如在imagenet 1000上训练而来的网络)来初始化自己的网络,而不是随机初始化。其他的训练步骤不变。
  • Convnet看成固定的特征提取器:首先固定ConvNet除了最后的全连接层外的其他所有层。最后的全连接层被替换成一个新的随机 初始化的层,只有这个新的层会被训练[只有这层参数会在反向传播时更新]

下面是利用PyTorch进行迁移学习步骤,要解决的问题是训练一个模型来对蚂蚁和蜜蜂进行分类。

1.导入相关的包

from __future__ import print_function, divisionimport torch
import torch.nn as nn
import torch.optim as optim
from torch.optim import lr_scheduler
import numpy as np
import torchvision
from torchvision import datasets, models, transforms
import matplotlib.pyplot as plt
import time
import os
import copyplt.ion()   # 交互模式

注释1:交互模式详情
在这里插入图片描述

2.加载数据

今天要解决的问题是训练一个模型来分类蚂蚁ants和蜜蜂bees。ants和bees各有约120张训练图片。每个类有75张验证图片。从零开始在 如此小的数据集上进行训练通常是很难泛化的。由于我们使用迁移学习,模型的泛化能力会相当好。 该数据集是imagenet的一个非常小的子集。从此处下载数据,并将其解压缩到当前目录。

# 训练集数据扩充和归一化
# 在验证集上仅需要归一化
data_transforms = {'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])]),
}data_dir = 'data/hymenoptera_data'
image_datasets = {x: datasets.ImageFolder(os.path.join(data_dir, x),data_transforms[x])for x in ['train', 'val']}
dataloaders = {x: torch.utils.data.DataLoader(image_datasets[x], batch_size=4,shuffle=True, num_workers=4)for x in ['train', 'val']}
dataset_sizes = {x: len(image_datasets[x]) for x in ['train', 'val']}
class_names = image_datasets['train'].classesdevice = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

注释2:ImageFolder
torchvision中有一个更常用的数据集类ImageFolder。 它假定了数据集是以如下方式构造的:

root/ants/xxx.png
root/ants/xxy.jpeg
root/ants/xxz.png
.
.
.
root/bees/123.jpg
root/bees/nsdf3.png
root/bees/asd932_.png

也就是"根目录/类别名称/该类别对应的图片"

3.可视化部分图像数据

可视化部分训练图像,以便了解数据扩充。

def imshow(inp, title=None):"""Imshow for Tensor."""inp = inp.numpy().transpose((1, 2, 0))mean = np.array([0.485, 0.456, 0.406])std = np.array([0.229, 0.224, 0.225])inp = std * inp + meaninp = np.clip(inp, 0, 1)plt.imshow(inp)if title is not None:plt.title(title)plt.pause(0.001)  # pause a bit so that plots are updated# 获得一批训练数据
inputs, classes = next(iter(dataloaders['train']))# 批量制作网格
out = torchvision.utils.make_grid(inputs)imshow(out, title=[class_names[x] for x in classes])

在这里插入图片描述

4.训练模型

编写一个通用函数来训练模型。下面将说明:

  • 调整学习速率
  • 保存最好的模型

下面的参数scheduler是一个来自 torch.optim.lr_scheduler的学习速率调整类的对象(LRscheduler object)。

def train_model(model, criterion, optimizer, scheduler, num_epochs=25):since = time.time()best_model_wts = copy.deepcopy(model.state_dict())best_acc = 0.0for epoch in range(num_epochs):print('Epoch {}/{}'.format(epoch, num_epochs - 1))print('-' * 10)# Each epoch has a training and validation phasefor phase in ['train', 'val']:if phase == 'train':model.train()  # Set model to training modeelse:model.eval()   # Set model to evaluate moderunning_loss = 0.0running_corrects = 0# Iterate over data.for inputs, labels in dataloaders[phase]:inputs = inputs.to(device)labels = labels.to(device)# 将参数梯度归零optimizer.zero_grad()# forward# 只在训练上追踪历史with torch.set_grad_enabled(phase == 'train'):outputs = model(inputs)_, preds = torch.max(outputs, 1)loss = criterion(outputs, labels)# backward + optimize 只在训练进行if phase == 'train':loss.backward()optimizer.step()# statisticsrunning_loss += loss.item() * inputs.size(0)running_corrects += torch.sum(preds == labels.data)if phase == 'train':scheduler.step()epoch_loss = running_loss / dataset_sizes[phase]epoch_acc = running_corrects.double() / dataset_sizes[phase]print('{} Loss: {:.4f} Acc: {:.4f}'.format(phase, epoch_loss, epoch_acc))# deep copy the modelif phase == 'val' and epoch_acc > best_acc:best_acc = epoch_accbest_model_wts = copy.deepcopy(model.state_dict())print()time_elapsed = time.time() - sinceprint('Training complete in {:.0f}m {:.0f}s'.format(time_elapsed // 60, time_elapsed % 60))print('Best val Acc: {:4f}'.format(best_acc))# load best model weightsmodel.load_state_dict(best_model_wts)return model

5.可视化模型的预测结果

一个通用的展示少量预测图片的函数

def visualize_model(model, num_images=6):was_training = model.trainingmodel.eval()images_so_far = 0fig = plt.figure()with torch.no_grad():for i, (inputs, labels) in enumerate(dataloaders['val']):inputs = inputs.to(device)labels = labels.to(device)outputs = model(inputs)_, preds = torch.max(outputs, 1)for j in range(inputs.size()[0]):images_so_far += 1ax = plt.subplot(num_images//2, 2, images_so_far)ax.axis('off')ax.set_title('predicted: {}'.format(class_names[preds[j]]))imshow(inputs.cpu().data[j])if images_so_far == num_images:model.train(mode=was_training)returnmodel.train(mode=was_training)

6.场景1:微调ConvNet

加载预训练模型并重置最终完全连接的图层。

model_ft = models.resnet18(pretrained=True)
# in_features 是fc线性层的输入数量
num_ftrs = model_ft.fc.in_features
# 这里,每个输出样本的大小设置为2。
# 或者,它可以推广到nn.Linear(num_ftrs,len(类名称))。
model_ft.fc = nn.Linear(num_ftrs, 2)model_ft = model_ft.to(device)criterion = nn.CrossEntropyLoss()# 观察所有参数都正在优化
optimizer_ft = optim.SGD(model_ft.parameters(), lr=0.001, momentum=0.9)# 每7个epochs衰减LR通过设置gamma=0.1
exp_lr_scheduler = lr_scheduler.StepLR(optimizer_ft, step_size=7, gamma=0.1)

训练和评估模型
(1)训练模型 该过程在CPU上需要大约15-25分钟,但是在GPU上,它只需不到一分钟。(我在CPU上跑的)

model_ft = train_model(model_ft, criterion, optimizer_ft, exp_lr_scheduler,num_epochs=25)
  • 输出
Epoch 0/24
----------
train Loss: 0.6633 Acc: 0.6721
val Loss: 0.2236 Acc: 0.9216Epoch 1/24
----------
train Loss: 0.4831 Acc: 0.7705
val Loss: 0.2813 Acc: 0.9020Epoch 2/24
----------
train Loss: 0.4444 Acc: 0.7828
val Loss: 0.1721 Acc: 0.9477Epoch 3/24
----------
train Loss: 0.4857 Acc: 0.7828
val Loss: 0.1651 Acc: 0.9477Epoch 4/24
----------
train Loss: 0.5882 Acc: 0.7705
val Loss: 0.4952 Acc: 0.8301Epoch 5/24
----------
train Loss: 0.5504 Acc: 0.7869
val Loss: 0.1896 Acc: 0.9412Epoch 6/24
----------
train Loss: 0.5927 Acc: 0.7992
val Loss: 0.3142 Acc: 0.8954Epoch 7/24
----------
train Loss: 0.4391 Acc: 0.8361
val Loss: 0.1705 Acc: 0.9477Epoch 8/24
----------
train Loss: 0.3733 Acc: 0.8566
val Loss: 0.1884 Acc: 0.9346Epoch 9/24
----------
train Loss: 0.3567 Acc: 0.8484
val Loss: 0.2050 Acc: 0.9281Epoch 10/24
----------
train Loss: 0.3769 Acc: 0.8279
val Loss: 0.2070 Acc: 0.9346Epoch 11/24
----------
train Loss: 0.3473 Acc: 0.8648
val Loss: 0.2191 Acc: 0.9281Epoch 12/24
----------
train Loss: 0.3654 Acc: 0.8566
val Loss: 0.1732 Acc: 0.9412Epoch 13/24
----------
train Loss: 0.2885 Acc: 0.8689
val Loss: 0.1959 Acc: 0.9346Epoch 14/24
----------
train Loss: 0.3242 Acc: 0.8525
val Loss: 0.2066 Acc: 0.9281Epoch 15/24
----------
train Loss: 0.3471 Acc: 0.8279
val Loss: 0.1821 Acc: 0.9477Epoch 16/24
----------
train Loss: 0.4058 Acc: 0.8443
val Loss: 0.1773 Acc: 0.9346Epoch 17/24
----------
train Loss: 0.4398 Acc: 0.8279
val Loss: 0.1726 Acc: 0.9477Epoch 18/24
----------
train Loss: 0.3293 Acc: 0.8689
val Loss: 0.1841 Acc: 0.9346Epoch 19/24
----------
train Loss: 0.3484 Acc: 0.8361
val Loss: 0.1846 Acc: 0.9412Epoch 20/24
----------
train Loss: 0.3164 Acc: 0.8402
val Loss: 0.1702 Acc: 0.9542Epoch 21/24
----------
train Loss: 0.3769 Acc: 0.8197
val Loss: 0.1828 Acc: 0.9346Epoch 22/24
----------
train Loss: 0.3204 Acc: 0.8852
val Loss: 0.2065 Acc: 0.9412Epoch 23/24
----------
train Loss: 0.3201 Acc: 0.8852
val Loss: 0.1970 Acc: 0.9346Epoch 24/24
----------
train Loss: 0.2603 Acc: 0.8730
val Loss: 0.2063 Acc: 0.9412Training complete in 33m 18s
Best val Acc: 0.954248Process finished with exit code 0

(2)模型评估结果可视化

visualize_model(model_ft)
  • 输出
    在这里插入图片描述

7.场景2:ConvNet作为固定特征提取器

在这里需要冻结除最后一层之外的所有网络。通过设置requires_grad == Falsebackward()来冻结参数,这样在反向传播backward()的时候他们的梯度就不会被计算。

model_conv = torchvision.models.resnet18(pretrained=True)
for param in model_conv.parameters():param.requires_grad = False# 默认情况下,新建模块的参数需要requires_grad=True
num_ftrs = model_conv.fc.in_features
model_conv.fc = nn.Linear(num_ftrs, 2)model_conv = model_conv.to(device)criterion = nn.CrossEntropyLoss()# 请注意,只有最后一层的参数被优化为
# 与以前相反。
optimizer_conv = optim.SGD(model_conv.fc.parameters(), lr=0.001, momentum=0.9)# 每7个epochs将LR衰减0.1倍
exp_lr_scheduler = lr_scheduler.StepLR(optimizer_conv, step_size=7, gamma=0.1)

训练和评估
(1)训练模型 在CPU上,与前一个场景相比,这将花费大约一半的时间,因为不需要为大多数网络计算梯度。但需要计算转发。

model_conv = train_model(model_conv, criterion, optimizer_conv,exp_lr_scheduler, num_epochs=25)
  • 输出
Epoch 0/24
----------
train Loss: 0.5987 Acc: 0.6393
val Loss: 0.3066 Acc: 0.8693Epoch 1/24
----------
train Loss: 0.5367 Acc: 0.7172
val Loss: 0.1962 Acc: 0.9477Epoch 2/24
----------
train Loss: 0.4591 Acc: 0.7992
val Loss: 0.1974 Acc: 0.9477Epoch 3/24
----------
train Loss: 0.5040 Acc: 0.7787
val Loss: 0.1922 Acc: 0.9346Epoch 4/24
----------
train Loss: 0.5343 Acc: 0.7705
val Loss: 0.2062 Acc: 0.9542Epoch 5/24
----------
train Loss: 0.5048 Acc: 0.7828
val Loss: 0.2255 Acc: 0.9281Epoch 6/24
----------
train Loss: 0.5591 Acc: 0.7951
val Loss: 0.2150 Acc: 0.9346Epoch 7/24
----------
train Loss: 0.3710 Acc: 0.8402
val Loss: 0.2361 Acc: 0.9346Epoch 8/24
----------
train Loss: 0.2645 Acc: 0.8934
val Loss: 0.2024 Acc: 0.9346Epoch 9/24
----------
train Loss: 0.3999 Acc: 0.8402
val Loss: 0.1959 Acc: 0.9477Epoch 10/24
----------
train Loss: 0.3806 Acc: 0.8238
val Loss: 0.2191 Acc: 0.9346Epoch 11/24
----------
train Loss: 0.4044 Acc: 0.8402
val Loss: 0.1941 Acc: 0.9542Epoch 12/24
----------
train Loss: 0.3234 Acc: 0.8648
val Loss: 0.1977 Acc: 0.9477Epoch 13/24
----------
train Loss: 0.3640 Acc: 0.8361
val Loss: 0.2026 Acc: 0.9346Epoch 14/24
----------
train Loss: 0.4070 Acc: 0.8115
val Loss: 0.1912 Acc: 0.9542Epoch 15/24
----------
train Loss: 0.3331 Acc: 0.8484
val Loss: 0.2011 Acc: 0.9346Epoch 16/24
----------
train Loss: 0.3006 Acc: 0.8770
val Loss: 0.1766 Acc: 0.9542Epoch 17/24
----------
train Loss: 0.3397 Acc: 0.8443
val Loss: 0.2180 Acc: 0.9412Epoch 18/24
----------
train Loss: 0.3332 Acc: 0.8443
val Loss: 0.1928 Acc: 0.9477Epoch 19/24
----------
train Loss: 0.3563 Acc: 0.8238
val Loss: 0.1982 Acc: 0.9477Epoch 20/24
----------
train Loss: 0.3222 Acc: 0.8566
val Loss: 0.2268 Acc: 0.9281Epoch 21/24
----------
train Loss: 0.4554 Acc: 0.8115
val Loss: 0.2420 Acc: 0.9281Epoch 22/24
----------
train Loss: 0.3066 Acc: 0.8648
val Loss: 0.1828 Acc: 0.9542Epoch 23/24
----------
train Loss: 0.4099 Acc: 0.8279
val Loss: 0.2061 Acc: 0.9477Epoch 24/24
----------
train Loss: 0.3176 Acc: 0.8648
val Loss: 0.2098 Acc: 0.9346Training complete in 0m 34s
Best val Acc: 0.954248

(2)模型评测结果可视化

visualize_model(model_conv)plt.ioff()
plt.show()
  • 输出
    在这里插入图片描述

http://chatgpt.dhexx.cn/article/2SbU8QeZ.shtml

相关文章

翻译: Transfer learning 迁移学习指南

这是您需要了解的有关经典迁移学习和深度迁移学习的所有信息。阅读本指南可改进您的模型训练并在更短的时间内获得更好的性能。 1. 背景 事情是这样的—— 至少可以说,在处理一项全新的任务时收集大量数据可能具有挑战性。 然而- 仅使用有限数量的训练数据获得…

迁移学习方法学习

目录 迁移学习的基础知识迁移学习的概念迁移学习的分类按目标域标签分按学习方法分按特征分类按离线与在线形式分 迁移学习的基本方法基于样本的迁移基于特征的迁移基于模型的迁移基于关系的迁移 深度迁移学习深度网络的可迁移性最简单的迁移学习——finetune finetune的使用技…

迁移学习实例

上一篇我们介绍了迁移学习的核心思想和流程,我们介绍一个实例来加深理解。 传送门:迁移学习概述 获取预训练模型 pytorch和tensorflow都封装了很多预训练模型。 pytorch通过工具包torchvision.models模块获取,主要包括AlexNet、VGG系列、 Res…

迁移学习与微调的区别

一、迁移学习: 1、从字面意义上理解是知识转移的学习方法,指一种学习方法;类比机器学习、深度学习等等概念; 2、把已训练好的模型参数迁移到新的模型来帮助新模型训练二、微调: 1、从字面意义上理解是小小的调整&…

迁移学习---举一反三

1.概念 迁移学习是指充分考虑数据、任务、或者模型的相似性,将在旧领域学习到的模型,应用到新的领域的一种学习过程。 通俗的讲就是把已经学习训练好的模型参数迁移到新的模型进行训练。考虑到大部分数据或任务是存在相关性的,所以通过迁移…

迁移学习基础

人类具有跨任务传输知识的固有能力。我们在学习一项任务的过程中获得的知识,可以用来解决相关的任务。任务相关程度越高,我们就越容易迁移或交叉利用知识。到目前为止所讨论的机器学习和深度学习算法,通常都是被设计用于单独运作的。这些算法…

学习迁移学习

学习迁移学习 一、相关背景 随着机器学习和数据挖掘不断发展,一个愈加明显的问题出现在人们面前:要想机器学习能够正常运转必须要保证训练集和测试集有相同的特征空间并且同分布。一旦分布改变,大多数模型往往要根据数据重建,这…

联邦迁移学习

本博客地址:https://security.blog.csdn.net/article/details/123573886 一、联邦学习的定义 横向联邦学习和纵向联邦学习要求所有的参与方具有相同的特征空间或样本空间,从而建立起一个有效的共享机器学习模型。然而,在更多的实际情况下&am…

迁移学习(二)

迁移学习综述(二)(学习笔记) A Comprehensive Survey on Transfer Learning 1.引言 迁移学习的目标是利用来自相关领域(称为源领域)的知识,以提高学习性能或最小化目标领域中需要的标记示例的数量。知识转移并不总是…

深度学习中的迁移学习介绍

迁移学习(Transfer Learning)的概念早在20世纪80年代就有相关的研究,这期间的研究有的称为归纳研究(inductive transfer)、知识迁移(knowledge transfer)、终身学习(life-long learning)以及累积学习(incremental learning)等。直到2009年,香港科技大学杨…

迁移学习综述

这是我根据北京邮电大学一位博士的讲解视频所归纳的笔记 视频地址:https://www.bilibili.com/video/BV1ct41167kV?spm_id_from333.337.search-card.all.click 正文 我们为什么需要迁移学习? 众所周知,AlphaGo是通过强化学习去训练&#x…

整理学习之深度迁移学习

迁移学习(Transfer Learning)通俗来讲就是学会举一反三的能力,通过运用已有的知识来学习新的知识,其核心是找到已有知识和新知识之间的相似性,通过这种相似性的迁移达到迁移学习的目的。世间万事万物皆有共性&#xff…

迁移学习简要

什么是迁移学习 迁移学习是一种机器学习方法,就是把任务为A的开发模型作为其的初始点,重新使用在任务为B的开发模型的过程中。迁移学习是通过从已学习的相关任务中转移知识来改进学习的新任务。虽然大多数机器学习的新 算法都是为了解决单个任务而设计的…

迁移学习(Transfer),面试看这些就够了!(附代码)

1. 什么是迁移学习 迁移学习(Transfer Learning)是一种机器学习方法,就是把为任务 A 开发的模型作为初始点,重新使用在为任务 B 开发模型的过程中。迁移学习是通过从已学习的相关任务中转移知识来改进学习的新任务,虽然大多数机器学习算法都…

迁移学习

简介 好的机器学习模型需要大量数据和许多GPU或TPU进行训练。大多数时候,他们只能执行特定的任务。 大学和大公司有时会发布他们的模型。但很可能你希望开发一个机器学习应用程序,但没有适合你的任务的可用模型。 但别担心,你不必收集大量数据…

迁移学习(Transfer)

1. 什么是迁移学习 迁移学习(Transfer Learning)是一种机器学习方法,就是把为任务 A 开发的模型作为初始点,重新使用在为任务 B 开发模型的过程中。迁移学习是通过从已学习的相关任务中转移知识来改进学习的新任务,虽然大多数机器学习算法都…

2021-11-29 拿到第一个badger

Coursera课程的前三节 What is data science Tool of data science Methodology of data science 感觉更像是阅读理解 今天拿到了第一个badger 准备花一周把剩下俩阅读理解拿了,开始搞实战部分 我走得很慢,但是从来不停下

Postgersql神器之pgbadger安装配置

文章目录 1.介绍2.安装pgbager3.参数调整3.1相关参数内容3.2 重启db4.配置apache5.安装libtext-csv-perl,6.手动产生报告 7.排程自动产生分析报告7.2脚本授权:7.3设定crontab7.4检视pgbadger日志分析报告 1.介绍 pgbadger是postgresql 三大神器之一:pg_…

BoltDB,RocksDB,PebbleDB,BadgerDb简介及测评

几个常用数据库性能分析 ​ 最近公司需要选型一款单机KV数据库来做业务承载,所以我对比了目前市面上比较流行的几个KV数据库并记录下来,包括boltdb,rocksdb,pebbledb,badgerdb四款,我将简单分析一下各数据库的特点,最后用自己的简…

智能优化算法-蜜獾算法Honey Badger Algorithm(附Matlab代码)

引言 提出了一种新的元启发式优化算法——蜜獾算法(Honey Badger Algorithm,HBA)。该算法受蜜獾智能觅食行为的启发,从数学上发展出一种求解优化问题的高效搜索策略。蜜獾挖掘和采蜜的动态搜索行为。于2021年发表在Mathematics and Computers in Simula…