tensor2JPG
import torch
from torchvision import transforms
toPIL = transforms.ToPILImage() #这个函数可以将张量转为PIL图片,由小数转为0-255之间的像素值
img = torch.randn(3,128,64)
pic = toPIL(img)
pic.save('random.jpg')
tensor2list
import torch
value = torch.Tensor([1, 2, 3])
print("list:", value.tolist())
tensor2numpy
我们很容易用numpy()和from_numpy()将Tensor和NumPy中的数组相互转换。但是需要注意的一点是: 这两个函数所产生的Tensor和NumPy中的数组共享相同的内存(所以他们之间的转换很快),改变其中一个时另一个也会改变!
mport numpy as np
a = np.ones(7)
b = torch.from_numpy(a)
print(a, b)
用torch.tensor()将NumPy数组转换成Tensor,该方法总是会进行数据拷贝,返回的Tensor和原来的数据不再共享内存
import numpy as np
a = np.ones((2,3))
c = torch.tensor(a)
torch.eq(input,output).sum().item()
A = [1,2,3,4]
B = [1,1,2,2]
torch.eq(A,B)得到的结果就是[1,0,0,0]
torch.eq().sum()就是将所有值相加,但是得到的仍然是一个tensor,本例中torch.eq(A,B).sum()得到的结果就是1,最后一步torch.eq(A,B).sum().item()得到的就是这个tensor中的值了,即1。
torch.eq(A,B).sum().item()
1
torch.max()
输出的值有两个参数,第一个参数是最大值,第二个参数是最大值的索引(也就是分类label)
torch.max(A)
4,3
torch.argmax()
作用与前面类似,我们只想要神经网络最终的标签,它输出的概率值并不关心,那么就可以直接用torch.argmax()返回tensor数据最大值的索引
torch.argmax(A)
3
torch.save()
保存加载整个模型,网络结构和权重参数
model=ClassNet()
torch.save(model,"net.pth")
只保存模型参数,保存模型的权重参数
model=ClassNet()
torch.save(model.state_dict(),"net_params.pth")
torch.load()
state_dict=torch.load('net_params.pth')
model.load_state_dict(state_dict)
# 参数strict=False,加载预训练的参数(注意检查key是否匹配)
保存加载自定义模型
模型通常包含以下内存:
网络结构:输入、输出尺寸,隐藏层信息
模型的权重参数:各个网络层训练出来的参数
优化器参数:优化器的状态和使用的超参数
其他信息:epoch,batch_size
checkpoint={
"model":ClassNet(),
"model_state_dict":model.state_dict(),
"optimize_state_dict":optimizer.state_dict(),
"epoch":epoch
}
torch.save(checkpoint,"checkpoint,pkl")
def load_checkpoint(filepath):
checkpoint=torch.load(filepath)
def load_checkpoint(filepath):
checkpoint = torch.load(filepath)
model=checkpoint['model']#提前网络结构
model.load_state_dict(checkpoint['model_state_dict'])#加载网络权重参数
optimizer=TheOptimizerClass()
optimizer.load_state_dict(checkpoint['optimizer_state_dict'])#加载优化器参数
for parameter in model.parameters():
parameter.requires_grad=False
model.eval()
return model
modle=load_checkpoint('checkpoint.pkl')
model.named_parameters()
model = LeNet()
named_parameters():给出网络层的名字和参数的迭代器,
parameters():仅仅输出是参数的迭代器。
state_dict():仅仅输出网络层的名字迭代器。
named_parameters() = parameters() + state_dict()
model = models.resnet18()
for param in model.named_parameters():
print(param[0],param[1])
conv1.0.weight
conv1.0.bias
conv2.0.weight
conv2.0.bias
fc1.0.weight
fc1.0.bias
fc2.0.weight
fc2.0.bias
fc3.weight
fc3.bias
model命名规则
1、对于__init__中使用self定义的变量会使用这个变量名作为存储时的名字。
self.conv1 = nn.Conv2d(3, 12, kernel_size=3, stride=1, padding=1)
self.bn1 = nn.BatchNorm2d(12)
卷积层有2个参数:权重和偏移项,conv1.weight、conv1.bias
BN层有5个参数:bn1.weight、bn1.bias、bn1.running_mean、bn1.running_var、bn1.num_batches_tracked
2、当使用nn.Sequential时会根据传入的list的顺序对其进行编号,从0开始。
conv1 = nn.Conv2d(3, 12, kernel_size=3, stride=1, padding=1)
bn1 = nn.BatchNorm2d(12)
s1 = [conv1, bn1]
self.stage1 = nn.Sequential(*s1)
注意此时的conv1和bn1都没有self,stage1有self,由于Sequential将conv1和bn1进行顺序封装,因此conv1会被编号为stage1.0,bn1会被编号为stage1.1,具体结果如下:
stage1.0.weight、stage1.0.bias
stage1.1.weight、stage1.1.bias、stage1.1.running_mean、stage1.1.running_var、stage1.1.num_batches_tracked
3、当一个module被from torch.nn import DataParallel或者from torch.nn.parallel import DistributedDataParallel包围住后,会在这个变量名后面加上module.。
conv1 = nn.Conv2d(3, 12, kernel_size=3, stride=1, padding=1)
bn1 = nn.BatchNorm2d(12)
s1 = [conv1, bn1]
stage1 = nn.Sequential(*s1)
self.stage2 = DataParallel(stage1)
注意只有stage2前面有self,输出结果如下:
stage2.module.0.weight、stage2.module.0.bias
stage2.module.1.weight、stage2.module.1.bias、stage2.module.1.running_mean、stage2.module.1.running_var、stage2.module.1.num_batches_tracked
断点续训
checkpoint = torch.load("")
model_without_ddp.load_state_dict(checkpoint["model"])
optimizer.load_state_dict(checkpoint["optimizer"])
lr_scheduler.load_state_dict(checkpoint["lr_scheduler"])
epoch = checkpoint["epoch"] + 1