前言
一、基础知识
1.Tensor介绍
二、常用代码
1.模型的保存和加载
2.cuda的device管理
总结
前篇numpy 的 ndarray类型的操作大多数都可套用到tensor上。
Tensor是PyTorch中的基本对象,翻译成张量,表示多维的矩阵。Tensor的大多数运算与Numpy相通,大多数情况下可以考虑直接迁移。
import torch
x = torch.Tensor(5,3)
print(x.size())
##output:
##torch.Size([5,3])
Tensor与 Numpy中的array可以互相转换,转换函数如下:x.numpy() 和 torch.from_numpy()
import torch
import numpy as np
x = torch.rand(5,3)
y = x.numpy()
z = torch.from_numpy(y)
print(x.type()) #tensor查看ndarray对应属性均加上括号
print(y.dtype) #ndarray无type属性
print(z.type())
# output:
# torch.FloatTensor
# float32
# torch.FloatTensor
**书中有介绍Variable,但因Pytorch的新版本已去除了Variable的使用,在此不再学习。
使用torch.load() 和 torch.save()分别进行加载和保存
import torch
torch.save(model, 'model.pkl') #保存整个模型
model = torch.load('model.pkl') #加载整个模型
torch.save(alexnet.state_dict(),'params.pkl') #保存网络中的参数
alexnet.load_state_dict(torch.load('params.pkl')) #加载网络中的参数
在Pytorch中提供了一些常用模型,具体在torchvision.models模块中。
import torch
import torchvision.models as models
Resnet18 = models.resnet18(pretrained=True)
AlexNet = models.alexnet(pretrained=True)
squeezenet = models.squeezenet1_0(pretrained=True)
vgg16 = models.vgg16(pretrained=True)
densenet = models.densenet161(pretrained=True)
inception = models.inception_v3(pretrained=True)
#...有很多模型,以上语句会自动下载模型并加载预训练参数
模型中某一层的修改以及加载部分模型可以参考:
https://www.jianshu.com/p/d67d62982a24
内容包括:加载预训练模型,并除去需要再次训练的层;固定部分参数;训练部分参数,检查部分参数是否固定等。(可以后期结合实验进行学习验证。)
Notion 需要注意:加载预训练权重有非常严格的要求,要求每一层一模一样,命名都要一样,否则无法将预训练模型权重加载到自定义的网络上。网络上也看到过手动加载模型权重,希望自定义加载层权重的,但效果来看仍存在问题。
import torch.nn as nn
import torchvision.models as models
import torch.utils.model_zoo as model_zoo
class Net(nn.Module):
def __init(self,n_output...) ->None:
super(Net, self).__init__()
self.n_output = n_output
pass
def forward(self, x):
pass
#加载model,model是自己定义好的模型
model =Net(5)
#读取参数
vgg16 = models.vgg16(pretrained=True)
pretrained_dict =vgg16.state_dict() #加载VGG16 预训练参数
#or
pretrained_dict = model_zoo.load_url(model_urls['resnet34'])
model_dict = model.state_dict() #加载自定义model 的预训练参数
#将pretrained_dict里不属于model_dict的键剔除掉
pretrained_dict = {k: v for k, v in pretrained_dict.items() if k in model_dict}
# 更新现有的model_dict
model_dict.update(pretrained_dict)
# 加载我们真正需要的state_dict
model.load_state_dict(model_dict)
torch.cuda用于设置和运行CUDA操作,会记录当前选择的GPU,且分配的所有CUDA张量默认在上面创建,使用torch.cuda.device上下文管理器更改所选设备。
*以上简单来说,就是被操作的两个张量要在同一个设备上(CPU or GPU),否则将报错(如:RuntimeError: expected device cuda:0 but got device cpu)
import torch
print(torch.cuda.is_available())
x = torch.rand(3,4)
y = torch.rand(3,1)
x = x.cuda()
y = y
print(x.cpu()+y)
print(x+y.cuda())
# torch.cuda.is_available() 函数可以用于测试CUDA是否可用,可用则会返回 True
#以上 x+y 操作,要不两者均使用 tensor.cuda()
# 要不两者均使用 tensor.cpu()
output:
# tensor([[1.0574, 0.7104, 0.7324, 1.0090],
# [1.5780, 1.4229, 0.7866, 1.3114],
# [1.0666, 1.2852, 1.4567, 1.3408]])
# tensor([[1.0574, 0.7104, 0.7324, 1.0090],
# [1.5780, 1.4229, 0.7866, 1.3114],
# [1.0666, 1.2852, 1.4567, 1.3408]], device='cuda:0')
#题外话
xx.weight.data.view(-1), xx.bias.data #可以用于查看网络层中的权重实际值(看了也没什么意思就是了)
## 只有网络层可以查看 weight 和 bias, pool以及网络本身不存在 weight, bias属性
本文大致描述了使用pytorch进行模型的加载和保存的方法,以及加载torchvision中模型库的预训练模型方式,查看网络权重的方法等。加载部分预训练模型,并固定某些层不参加训练等方法可参见上述提及的博客/简书,但具体操作仍需在实验中验证。