深入理解Pytorch微调torchvision模型

目录
  • 一、简介
  • 二、导入相关包
  • 三、数据输入
  • 四、辅助函数
    • 1、模型训练和验证
    • 2、设置模型参数的'.requires_grad属性'

一、简介

在本小节,深入探讨如何对torchvision进行微调和特征提取。所有模型都已经预先在1000类的magenet数据集上训练完成。 本节将深入介绍如何使用几个现代的CNN架构,并将直观展示如何微调任意的PyTorch模型。
本节将执行两种类型的迁移学习:

  • 微调:从预训练模型开始,更新我们新任务的所有模型参数,实质上是重新训练整个模型。
  • 特征提取:从预训练模型开始,仅更新从中导出预测的最终图层权重。它被称为特征提取,因为我们使用预训练的CNN作为固定 的特征提取器,并且仅改变输出层。

通常这两种迁移学习方法都会遵循一下步骤:

  • 初始化预训练模型
  • 重组最后一层,使其具有与新数据集类别数相同的输出数
  • 为优化算法定义想要的训练期间更新的参数
  • 运行训练步骤

二、导入相关包

from __future__ import print_function
from __future__ import division
import torch
import torch.nn as nn
import torch.optim as optim
import numpy as np
import torchvision
from torchvision import datasets,models,transforms
import matplotlib.pyplot as plt
import time
import os
import copy
print("Pytorch version:",torch.__version__)
print("torchvision version:",torchvision.__version__)

运行结果

三、数据输入

数据集——>我在这里

链接:https://pan.baidu.com/s/1G3yRfKTQf9sIq1iCSoymWQ
提取码:1234

#%%输入
data_dir="D:\Python\Pytorch\data\hymenoptera_data"
# 从[resnet,alexnet,vgg,squeezenet,desenet,inception]
model_name='squeezenet'
# 数据集中类别数量
num_classes=2
# 训练的批量大小
batch_size=8
# 训练epoch数
num_epochs=15
# 用于特征提取的标志。为FALSE,微调整个模型,为TRUE只更新图层参数
feature_extract=True

四、辅助函数

1、模型训练和验证

  • train_model函数处理给定模型的训练和验证。作为输入,它需要PyTorch模型、数据加载器字典、损失函数、优化器、用于训练和验 证epoch数,以及当模型是初始模型时的布尔标志。
  • is_inception标志用于容纳 Inception v3 模型,因为该体系结构使用辅助输出, 并且整体模型损失涉及辅助输出和最终输出,如此处所述。 这个函数训练指定数量的epoch,并且在每个epoch之后运行完整的验证步骤。它还跟踪最佳性能的模型(从验证准确率方面),并在训练 结束时返回性能最好的模型。在每个epoch之后,打印训练和验证正确率。
#%%模型训练和验证
device=torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
def train_model(model,dataloaders,criterion,optimizer,num_epochs=25,is_inception=False):
    since=time.time()
    val_acc_history=[]
    best_model_wts=copy.deepcopy(model.state_dict())
    best_acc=0.0
    for epoch in range(num_epochs):
        print('Epoch{}/{}'.format(epoch, num_epochs-1))
        print('-'*10)
        # 每个epoch都有一个训练和验证阶段
        for phase in['train','val']:
            if phase=='train':
                model.train()
            else:
                model.eval()

            running_loss=0.0
            running_corrects=0
            # 迭代数据
            for inputs,labels in dataloaders[phase]:
                inputs=inputs.to(device)
                labels=labels.to(device)
                # 梯度置零
                optimizer.zero_grad()
                # 向前传播
                with torch.set_grad_enabled(phase=='train'):
                    # 获取模型输出并计算损失,开始的特殊情况在训练中他有一个辅助输出
                    # 在训练模式下,通过将最终输出和辅助输出相加来计算损耗,在测试中值考虑最终输出
                    if is_inception and phase=='train':
                        outputs,aux_outputs=model(inputs)
                        loss1=criterion(outputs,labels)
                        loss2=criterion(aux_outputs,labels)
                        loss=loss1+0.4*loss2
                    else:
                        outputs=model(inputs)
                        loss=criterion(outputs,labels)

                    _,preds=torch.max(outputs,1)

                    if phase=='train':
                        loss.backward()
                        optimizer.step()

                # 添加
                running_loss+=loss.item()*inputs.size(0)
                running_corrects+=torch.sum(preds==labels.data)

            epoch_loss=running_loss/len(dataloaders[phase].dataset)
            epoch_acc=running_corrects.double()/len(dataloaders[phase].dataset)

            print('{}loss : {:.4f} acc:{:.4f}'.format(phase, epoch_loss,epoch_acc))

            if phase=='train' and epoch_acc>best_acc:
                best_acc=epoch_acc
                best_model_wts=copy.deepcopy(model.state_dict())
            if phase=='val':
                val_acc_history.append(epoch_acc)

        print()

    time_elapsed=time.time()-since
    print('training complete in {:.0f}s'.format(time_elapsed//60, time_elapsed%60))
    print('best val acc:{:.4f}'.format(best_acc))

    model.load_state_dict(best_model_wts)
    return model,val_acc_history

2、设置模型参数的'.requires_grad属性'

当我们进行特征提取时,此辅助函数将模型中参数的 .requires_grad 属性设置为False。
默认情况下,当我们加载一个预训练模型时,所有参数都是 .requires_grad = True,如果我们从头开始训练或微调,这种设置就没问题。
但是,如果我们要运行特征提取并且只想为新初始化的层计算梯度,那么我们希望所有其他参数不需要梯度变化。

#%%设置模型参数的.require——grad属性
def set_parameter_requires_grad(model,feature_extracting):
    if feature_extracting:
        for param in model.parameters():
            param.require_grad=False

靓仔今天先去跑步了,再不跑来不及了,先更这么多,后续明天继续~(感谢有人没有催更!感谢监督!希望继续监督!)

以上就是深入理解Pytorch微调torchvision模型的详细内容,更多关于Pytorch torchvision模型的资料请关注我们其它相关文章!

(0)

相关推荐

  • anaconda安装pytorch1.7.1和torchvision0.8.2的方法(亲测可用)

    1. 创建一个新的环境 打开Anaconda Navigator,找不到的win10左下角输入一下就能找到了,如下图. 这里通过列表下面的create按钮可以创建一个新的环境,这里我将新环境起名为torch,右面列表中是我安装好的包,刚创建的时候没有这么多. 2. 从pytorch官网得到获取包的命令 打开Anaconda Prompt,输入activate 刚刚创建的环境名可以切换到刚刚创建的环境.这里我用的是下面的命令,你需要根据自己创建的环境名修改相应的激活名称. activate tor

  • pytorch torchvision.ImageFolder的用法介绍

    torchvision.datasets Datasets 拥有以下API: __getitem__ __len__ Datasets都是 torch.utils.data.Dataset的子类,所以,他们也可以通过torch.utils.data.DataLoader使用多线程(python的多进程). 举例说明: torch.utils.data.DataLoader(coco_cap, batch_size=args.batchSize, shuffle=True, num_workers

  • Pytoch之torchvision.transforms图像变换实例

    transforms.CenterCrop(size) 将给定的PIL.Image进行中心切割,得到给定的size,size可以是tuple,(target_height, target_width).size也可以是一个Integer,在这种情况下,切出来的图片的形状是正方形. size可以为int,也可以为float #定义中心切割 centerCrop = transforms.CenterCrop((img.size[0]/2,img.size[1]/2)) imgccrop = cen

  • 关于PyTorch源码解读之torchvision.models

    PyTorch框架中有一个非常重要且好用的包:torchvision,该包主要由3个子包组成,分别是:torchvision.datasets.torchvision.models.torchvision.transforms. 这3个子包的具体介绍可以参考官网: http://pytorch.org/docs/master/torchvision/index.html. 具体代码可以参考github: https://github.com/pytorch/vision/tree/master/

  • 深入理解Pytorch微调torchvision模型

    目录 一.简介 二.导入相关包 三.数据输入 四.辅助函数 1.模型训练和验证 2.设置模型参数的'.requires_grad属性' 一.简介 在本小节,深入探讨如何对torchvision进行微调和特征提取.所有模型都已经预先在1000类的magenet数据集上训练完成. 本节将深入介绍如何使用几个现代的CNN架构,并将直观展示如何微调任意的PyTorch模型. 本节将执行两种类型的迁移学习: 微调:从预训练模型开始,更新我们新任务的所有模型参数,实质上是重新训练整个模型. 特征提取:从预训

  • pytorch构建多模型实例

    pytorch构建双模型 第一部分:构建"se_resnet152","DPN92()"双模型 import numpy as np from functools import partial import torch from torch import nn import torch.nn.functional as F from torch.optim import SGD,Adam from torch.autograd import Variable fro

  • Python深度学习理解pytorch神经网络批量归一化

    目录 训练深层网络 为什么要批量归一化层呢? 批量归一化层 全连接层 卷积层 预测过程中的批量归一化 使用批量归一化层的LeNet 简明实现 争议 训练深层神经网络是十分困难的,特别是在较短的实践内使他们收敛更加棘手.在本节中,我们将介绍批量归一化(batch normalization),这是一种流行且有效的技术,可持续加速深层网络的收敛速度.在结合之后将介绍的残差快,批量归一化使得研究人员能够训练100层以上的网络. 训练深层网络 为什么要批量归一化层呢? 让我们回顾一下训练神经网络时出现的

  • 深入理解PyTorch中的nn.Embedding的使用

    目录 一.前置知识 1.1 语料库(Corpus) 1.2 词元(Token) 1.3 词表(Vocabulary) 二.nn.Embedding 基础 2.1 为什么要 embedding? 2.2 基础参数 2.3 nn.Embedding 与 nn.Linear 的区别 2.4 nn.Embedding 的更新问题 三.nn.Embedding 进阶 3.1 全部参数 3.2 使用预训练的词嵌入 四.最后 一.前置知识 1.1 语料库(Corpus) 太长不看版: NLP任务所依赖的语言数

  • PyTorch搭建多项式回归模型(三)

    PyTorch基础入门三:PyTorch搭建多项式回归模型 1)理论简介 对于一般的线性回归模型,由于该函数拟合出来的是一条直线,所以精度欠佳,我们可以考虑多项式回归来拟合更多的模型.所谓多项式回归,其本质也是线性回归.也就是说,我们采取的方法是,提高每个属性的次数来增加维度数.比如,请看下面这样的例子: 如果我们想要拟合方程: 对于输入变量和输出值,我们只需要增加其平方项.三次方项系数即可.所以,我们可以设置如下参数方程: 可以看到,上述方程与线性回归方程并没有本质区别.所以我们可以采用线性回

  • pytorch 实现打印模型的参数值

    对于简单的网络 例如全连接层Linear 可以使用以下方法打印linear层: fc = nn.Linear(3, 5) params = list(fc.named_parameters()) print(params.__len__()) print(params[0]) print(params[1]) 输出如下: 由于Linear默认是偏置bias的,所有参数列表的长度是2.第一个存的是全连接矩阵,第二个存的是偏置. 对于稍微复杂的网络 例如MLP mlp = nn.Sequential

  • pytorch中获取模型input/output shape实例

    Pytorch官方目前无法像tensorflow, caffe那样直接给出shape信息,详见 https://github.com/pytorch/pytorch/pull/3043 以下代码算一种workaround.由于CNN, RNN等模块实现不一样,添加其他模块支持可能需要改代码. 例如RNN中bias是bool类型,其权重也不是存于weight属性中,不过我们只关注shape够用了. 该方法必须构造一个输入调用forward后(model(x)调用)才可获取shape #coding

  • Pytorch实现将模型的所有参数的梯度清0

    有两种方式直接把模型的参数梯度设成0: model.zero_grad() optimizer.zero_grad()#当optimizer=optim.Optimizer(model.parameters())时,两者等效 如果想要把某一Variable的梯度置为0,只需用以下语句: Variable.grad.data.zero_() 补充知识:PyTorch中在反向传播前为什么要手动将梯度清零?optimizer.zero_grad()的意义 optimizer.zero_grad()意思

  • PyTorch深度学习模型的保存和加载流程详解

    一.模型参数的保存和加载 torch.save(module.state_dict(), path):使用module.state_dict()函数获取各层已经训练好的参数和缓冲区,然后将参数和缓冲区保存到path所指定的文件存放路径(常用文件格式为.pt..pth或.pkl). torch.nn.Module.load_state_dict(state_dict):从state_dict中加载参数和缓冲区到Module及其子类中 . torch.nn.Module.state_dict()函数

  • PyTorch 使用torchvision进行图片数据增广

    目录 使用torchvision来进行图片的数据增广 1. 读取图片 2. 图片增广 2.1 图片水平翻转 2.2 图片上下翻转 2.3 图片旋转 2.4 中心裁切 2.5 随机裁切 2.6 随机裁切并修改尺寸 2. 7 修改图片颜色 3. 训练数据集加载 使用torchvision来进行图片的数据增广 数据增强就是增强一个已有数据集,使得有更多的多样性.对于图片数据来说,就是改变图片的颜色和形状等等.比如常见的: 左右翻转,对于大多数数据集都可以使用:上下翻转:部分数据集不适合使用:图片切割:

随机推荐