Pytorch学习笔记

1.数据载入之Dataset和DataLoader

1.1Dataset类

dataset类
所谓数据集,无非就是一组{x:y}的集合吗,你只需要在这个类里说明“有一组{x:y}的集合”就可以了。

对于图像分类任务,图像+分类

对于目标检测任务,图像+bbox、分类

对于超分辨率任务,低分辨率图像+超分辨率图像

对于文本分类任务,文本+分类

建立一个Dataset的子类MyDataSet,必须要重写__len__()和__getitem__()
1.__len__函数:使得类对象拥有 "len(object)"功能,返回dataset的size。
2.__getitem__函数:使得类对象拥有"object[index]"功能,可以用索引i去获得第i+1个样本
分两步:首先将数据包装为Dataset类,然后传入DataLoader

# 首先将数据包装为Dataset类
class MyDataSet(Dataset):
    def __init__(self):
        self.sample_list = ...
 
    def __getitem__(self, index):
        x= ...
        y= ...
        return x, y
 
    def __len__(self):
        return len(self.sample_list)
        
# 然后传入DataLoader        
DataLoader(MyDataSet, batch_size=1, shuffle=False, sampler=None,
           batch_sampler=None, num_workers=0, collate_fn=None,
           pin_memory=False, drop_last=False, timeout=0,
           worker_init_fn=None)
 

1.2ImageFolder类

from torchvision import transforms
from torchvision.datasets import ImageFolder
from torch.utils.data import DataLoader

data_path = r'./images'

# 将图像RGB三个通道的像素值分别减去0.5再除以0.5,从而将所有像素值
# 固定到[-1.0, 1.0]范围内
data_transforms = transforms.Compose([
    #裁剪为256*256
    transforms.Resize((256,256)),
    #随机垂直翻转
    transforms.RandomVerticalFlip(),
    #将0-255范围的像素转为0-1.0范围的tensor
    transforms.ToTensor(),
    transforms.Normalize([0.5,0.5,0.5],[0.5,0.5,0.5])
    ])

train_dataset = ImageFolder(data_path,transform=data_transforms)

print('训练集大小:',len(train_dataset)) # 训练集大小(图像数量) out: 1067
print('训练集第一张图像张量以及对应的标签,二维元组:',train_dataset[0]) # 训练集第一张图像张量以及对应的标签,二维元组
print('训练集第一张图像的张量:',train_dataset[0][0]) # 训练集第一张图像的张量
print('训练集第一张图像的标签:',train_dataset[0][0]) # 训练集第一张图像的标签

train_folder = DataLoader(train_dataset,batch_size=4,shuffle=True)
print(len(train_folder))

epochs = 2
for epoch in range(epochs):
    for i,(inputs,labels) in enumerate(train_folder):
        print(epoch,' ',i,'inputs:',inputs.data.size(),'labels:',labels.data.size())
    

参考:pytorch ImageFolder和Dataloader加载自制图像数据集

参考:Pytorch(五)入门:DataLoader 和 Dataset

2.模型保存与载入

方法一:保存网络的参数

#导入模块
import torch
##创建网络,当然还需要损失函数梯度等省略
net=Net()

#保存:可以是pth文件或者pt文件 
torch.save(net.state_dict()'state_dict_model.pth')
 
#我们想要在另外的一个python文件中读取我们之前已经保存好的模型,我们需要先创建一个和之前模型一样的空模型来接收。
from old_py import Net

#载入保存的模型参数
model=Net()
model.load_state_dict(torch.load(PATH))

#显示model.state_dict()中包含了那些内容
print("Model's state_dict:")
for param_tensor in model.state_dict():
    print(param_tensor, "\t", model.state_dict()[param_tensor].size())

#不启用 BatchNormalization 和 Dropout
model.eval() 

方法二:保存整个网络

import torch
net=Net()

# Save
torch.save(net, "entire_model.pt")
# Load
model = torch.load("entire_model.pt")
model.eval()

基于两种方法的区别,方法一:保存模型的参数,而不保存模型的框架,在读取模型参数前要先定义一个模型(模型必须与原模型相同的构造),也就是上面的先实例化网络模型,再导入参数。方法二:保存模型的结构与参数,读取时,直接加载模型。一般用的都是第一种。

3.指定GPU

1.终端指定

CUDA_VISIBLE_DEVICES=0 python xxx.py

2.代码中指定

import os
os.environ["CUDA_VISIBLE_DEVICES"] = "0"

3.程序中指定

# 指定GPU0
device = torch.device('cuda:0')

# 把数据移到cuda上
train_data = train_data.to(device)
label_data = label_data.to(device)
model.to(device)

# 训练完成后,输出数据移动到cpu上,返回的是tensor
predict_data = predict_data.cpu()

# 还可以转换成numpy类型
# predict_data = predict_data.cpu().numpy()

4.配上If操作

if torch.cuda.is_available():
	train_data = train_data.to(device)
	label_data = label_data.to(device)
	model.to(device)

4.torchvision.models

torchvision.models
torchvision.models 中为我们提供了已经训练好的模型,让我们可以加载之后,直接使用。

torchvision.models模块的 子模块中包含以下模型结构。

AlexNet
VGG
ResNet
SqueezeNet
DenseNet

我们可以直接使用如下代码来快速创建一个权重随机初始化的模型

import torchvision.models as models
resnet18 = models.resnet18()
alexnet = models.alexnet()
squeezenet = models.squeezenet1_0()
densenet = models.densenet_161()

也可以通过使用 pretrained=True 来加载一个别人预训练好的模型

import torchvision.models as models
resnet18 = models.resnet18(pretrained=True)
alexnet = models.alexnet(pretrained=True)

import torchvision.models as models
# 加载一个 resnet18 模型
resnet18 = models.resnet18()
print(resnet18)

import torchvision.models as models
resnet18 = models.resnet18(pretrained=True) # 加载一个已经预训练好的模型, 需要下载一段时间...

5.tochvision.transforms

transforms提供了一般图像操作的类
transforms.Normalize(mean,std)
如果需要同时使用几个transforms,就用transforms.Compose()

# 我们这里还是对MNIST进行处理,初始的MNIST是 28 * 28,我们把它处理成 96 * 96 的torch.Tensor的格式
from torchvision import transforms as transforms
import torchvision
from torch.utils.data import DataLoader

# 图像预处理步骤
transform = transforms.Compose([
    transforms.Resize(96), # 缩放到 96 * 96 大小
    transforms.ToTensor(),
    transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)) # 归一化
])

DOWNLOAD = True
BATCH_SIZE = 32

train_dataset = torchvision.datasets.MNIST(root='./data/', train=True, transform=transform, download=DOWNLOAD)


train_loader = DataLoader(dataset=train_dataset,
                          batch_size=BATCH_SIZE,
                          shuffle=True)

print(len(train_dataset))
print(len(train_loader))

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱吹口哨的夜莺

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值