使用了一段时间PyTorch,感觉爱不释手(0-0),听说现在已经有C++接口。在应用过程中不可避免需要使用Finetune/参数初始化/模型加载等。

模型保存/加载

1.所有模型参数

训练过程中,有时候会由于各种原因停止训练,这时候我们训练过程中就需要注意将每一轮epoch的模型保存(一般保存最好模型与当前轮模型)。一般使用pytorch里面推荐的保存方法。该方法保存的是模型的参数。

#保存模型到checkpoint.pth.tar
torch.save(model.module.state_dict(), ‘checkpoint.pth.tar’)

对应的加载模型方法为(这种方法需要先反序列化模型获取参数字典,因此必须先load模型,再load_state_dict):

mymodel.load_state_dict(torch.load(‘checkpoint.pth.tar’))

有了上面的保存后,现以一个例子说明如何在inference AND/OR resume train使用。

#保存模型的状态,可以设置一些参数,后续可以使用
state = {'epoch': epoch + 1,#保存的当前轮数
'state_dict': mymodel.state_dict(),#训练好的参数
'optimizer': optimizer.state_dict(),#优化器参数,为了后续的resume
'best_pred': best_pred#当前最好的精度
,....,...} #保存模型到checkpoint.pth.tar
torch.save(state, ‘checkpoint.pth.tar’)
#如果是best,则复制过去
if is_best:
shutil.copyfile(filename, directory + 'model_best.pth.tar') checkpoint = torch.load('model_best.pth.tar')
model.load_state_dict(checkpoint['state_dict'])#模型参数
optimizer.load_state_dict(checkpoint['optimizer'])#优化参数
epoch = checkpoint['epoch']#epoch,可以用于更新学习率等 #有了以上的东西,就可以继续重新训练了,也就不需要担心停止程序重新训练。
train/eval
....
....

上面是pytorch建议使用的方法,当然还有第二种方法。这种方法灵活性不高,不推荐。

#保存
torch.save(mymodel,‘checkpoint.pth.tar’) #加载
mymodel = torch.load(‘checkpoint.pth.tar’)

2.部分模型参数

在很多时候,我们加载的是已经训练好的模型,而训练好的模型可能与我们定义的模型不完全一样,而我们只想使用一样的那些层的参数。

有几种解决方法:

(1)直接在训练好的模型开始搭建自己的模型,就是先加载训练好的模型,然后再它基础上定义自己的模型;

model_ft = models.resnet18(pretrained=use_pretrained)
self.conv1 = model_ft.conv1
self.bn = model_ft.bn
... ...

(2) 自己定义好模型,直接加载模型

#第一种方法:
mymodelB = TheModelBClass(*args, **kwargs)
# strict=False,设置为false,只保留键值相同的参数
mymodelB.load_state_dict(model_zoo.load_url(model_urls['resnet18']), strict=False) #第二种方法:
# 加载模型
model_pretrained = models.resnet18(pretrained=use_pretrained) # mymodel's state_dict,
# 如: conv1.weight
# conv1.bias
mymodelB_dict = mymodelB.state_dict() # 将model_pretrained的建与自定义模型的建进行比较,剔除不同的
pretrained_dict = {k: v for k, v in model_pretrained.items() if k in mymodelB_dict}
# 更新现有的model_dict
mymodelB_dict.update(pretrained_dict) # 加载我们真正需要的state_dict
mymodelB.load_state_dict(mymodelB_dict) # 方法2可能更直观一些

参数初始化

第二个问题是参数初始化问题,在很多代码里面都会使用到,毕竟不是所有的都是有预训练参数。这时就需要对不是与预训练参数进行初始化。pytorch里面的每个Tensor其实是对Variabl的封装,其包含data、grad等接口,因此可以用这些接口直接赋值。这里也提供了怎样把其他框架(caffe/tensorflow/mxnet/gluonCV等)训练好的模型参数直接赋值给pytorch.其实就是对data直接赋值。

pytorch提供了初始化参数的方法:

 def weight_init(m):
if isinstance(m,nn.Conv2d):
n = m.kernel_size[0] * m.kernel_size[1] * m.out_channels
m.weight.data.normal_(0,math.sqrt(2./n))
elif isinstance(m,nn.BatchNorm2d):
m.weight.data.fill_(1)
m.bias.data.zero_()

但一般如果没有很大需求初始化参数,也没有问题(不确定性能是否有影响的情况下),pytorch内部是有默认初始化参数的。

Fintune

最后就是精调了,我们平时做实验,至少backbone是用预训练的模型,将其用作特征提取器,或者在它上面做精调。

用于特征提取的时候,要求特征提取部分参数不进行学习,而pytorch提供了requires_grad参数用于确定是否进去梯度计算,也即是否更新参数。以下以minist为例,用resnet18作特征提取:

#加载预训练模型
model = torchvision.models.resnet18(pretrained=True) #遍历每一个参数,将其设置为不更新参数,即不学习
for param in model.parameters():
param.requires_grad = False # 将全连接层改为mnist所需的10类,注意:这样更改后requires_grad默认为True
model.fc = nn.Linear(512, 10) # 优化
optimizer = optim.SGD(model.fc.parameters(), lr=1e-2, momentum=0.9)

用于全局精调时,我们一般对不同的层需要设置不同的学习率,预训练的层学习率小一点,其他层大一点。这要怎么做呢?

# 加载预训练模型
model = torchvision.models.resnet18(pretrained=True)
model.fc = nn.Linear(512, 10) # 参考:https://blog.csdn.net/u012759136/article/details/65634477
ignored_params = list(map(id, model.fc.parameters()))
base_params = filter(lambda p: id(p) not in ignored_params, model.parameters()) # 对不同参数设置不同的学习率
params_list = [{'params': base_params, 'lr': 0.001},]
params_list.append({'params': model.fc.parameters(), 'lr': 0.01}) optimizer = torch.optim.SGD(params_list,
0.001,
momentum=args.momentum,
weight_decay=args.weight_decay)

最后整理一下目前,pytorch预训练的基础模型:

(1)torchvision

torchvision里面已经提供了不同的预训练模型,一般也够用了。

pytorch/visiongithub.com

包含了alexnet/densenet各种版本(densenet121/densenet169/densenet201/densenet161)/inception_v3/resnet各种版本(resnet18', 'resnet34', 'resnet50', 'resnet101','resnet152')/SqueezeNet各种版本( 'squeezenet1_0', 'squeezenet1_1')/VGG各种版本( 'vgg11', 'vgg11_bn', 'vgg13', 'vgg13_bn', 'vgg16', 'vgg16_bn','vgg19_bn', 'vgg19')

(2)其他预训练好的模型,如,SENet/NASNet等。

Cadene/pretrained-models.pytorchgithub.com

(3)gluonCV转pytorch的模型,包括,分类网络,分割网络等,这里的精度均比其他框架高几个百分点。

zhanghang1989/gluoncv-torchgithub.com

PyTorch模型读写、参数初始化、Finetune的更多相关文章

  1. [PyTorch]PyTorch中模型的参数初始化的几种方法(转)

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 本文目录 1. xavier初始化 2. kaiming初始化 3. 实际使用中看到的初始化 3.1 ResNeXt,de ...

  2. Pytorch基础(6)----参数初始化

    一.使用Numpy初始化:[直接对Tensor操作] 对Sequential模型的参数进行修改: import numpy as np import torch from torch import n ...

  3. pytorch对模型参数初始化

    1.使用apply() 举例说明: Encoder :设计的编码其模型 weights_init(): 用来初始化模型 model.apply():实现初始化 # coding:utf- from t ...

  4. pytorch和tensorflow的爱恨情仇之参数初始化

    pytorch和tensorflow的爱恨情仇之基本数据类型 pytorch和tensorflow的爱恨情仇之张量 pytorch和tensorflow的爱恨情仇之定义可训练的参数 pytorch版本 ...

  5. PyTorch常用参数初始化方法详解

    1. 均匀分布 torch.nn.init.uniform_(tensor, a=0, b=1) 从均匀分布U(a, b)中采样,初始化张量. 参数: tensor - 需要填充的张量 a - 均匀分 ...

  6. 从零搭建Pytorch模型教程(四)编写训练过程--参数解析

    ​  前言 训练过程主要是指编写train.py文件,其中包括参数的解析.训练日志的配置.设置随机数种子.classdataset的初始化.网络的初始化.学习率的设置.损失函数的设置.优化方式的设置. ...

  7. 【转载】 pytorch自定义网络结构不进行参数初始化会怎样?

    原文地址: https://blog.csdn.net/u011668104/article/details/81670544 ------------------------------------ ...

  8. ubuntu之路——day15.1 只用python的numpy在底层检验参数初始化对模型的影响

    首先感谢这位博主整理的Andrew Ng的deeplearning.ai的相关作业:https://blog.csdn.net/u013733326/article/details/79827273 ...

  9. DEX-6-caffe模型转成pytorch模型办法

    在python2.7环境下 文件下载位置:https://data.vision.ee.ethz.ch/cvl/rrothe/imdb-wiki/ 1.可视化模型文件prototxt 1)在线可视化 ...

随机推荐

  1. Springboot使用MatrixVariable 注解

        根据 URI 规范 RFC 3986 中 URL 的定义,路径片段中可以可以包含键值对.规范中没对对应的术语.一般 "URL 路径参数" 可以被应用,尽管更加独特的 &qu ...

  2. new和delete关键字

    new关键字创建出来的对象位于什么地方?很明显嘛,new关键字创建出来的对象一定位于堆空间,这种说法一定正确吗?本篇博客帮你揭开其神秘的面纱. 被忽略的事实new/delete的本质是C++预定义的操 ...

  3. JMeter结果树响应数据中文乱码

    打开apache-jmeter-2.11\bin\jmeter.properties文件,搜索"encoding"关键字,找到如下配置: # The encoding to be ...

  4. 解析ThreadPoolExecutor类是如何保证线程池正确运行的

    摘要:对于线程池的核心类ThreadPoolExecutor来说,有哪些重要的属性和内部类为线程池的正确运行提供重要的保障呢? 本文分享自华为云社区<[高并发]通过源码深度解析ThreadPoo ...

  5. python3使用pycuda执行简单GPU计算任务

    技术背景 GPU的加速技术在深度学习.量子计算领域都已经被广泛的应用.其适用的计算模型是小内存的密集型计算场景,如果计算的模型内存较大,则需要使用到共享内存,这会直接导致巨大的数据交互的运算量,通信开 ...

  6. Layui form表单提交注意事项

    // 表单提交form.on('submit(first1)', function (data) { var articleFrom = data.field; $.ajax({ type:" ...

  7. golang context包

    go context标准库 context包在Go1.7版本时加入到标准库中.其设计目标是给Golang提供一个标准接口来给其他任务发送取消信号和传递数据.其具体作用为: 可以通过context发送取 ...

  8. 01_Keil与Proteus联合仿真的注意事项

    01. 关于keil5和Proteus8的联合仿真的操作步骤,这里就不细说,给个链接,步骤差不多是最齐全的 CSDN博客链接:https://blog.csdn.net/wzk456/article/ ...

  9. 20210824 Prime,Sequence,Omeed

    考场 T1 貌似是 luogu 上原题 T2 计数,想起了这题和这题,但没有 \(n^2\) 一档的分...准备打个表 T3 期望 DP,但暴力是 \(O(qn)\) 的,发现 \(combo\) 的 ...

  10. Xshell破~~解和SecureCRT破~~解办法,亲测可行

    解决办法很简单,那就是安装MobaXterm, 安装上即可使用,无需破击,免费,功能同样强大,不比xshell, SecureCRT功能差.它是集万千功能于一身的全能型终端神器. 听名字就不会太差,看 ...