如何深入理解Pytorch微调torchvision模型,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。
在本小节,深入探讨如何对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
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
当我们进行特征提取时,此辅助函数将模型中参数的 .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模型问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注亿速云行业资讯频道了解更多相关知识。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。