PyTorch基础:数据处理(数据加载、GPU加速)

数据对于深度学习而言是至关重要的。丰富、完整、规范的数据集往往能训练处效果更佳的网络模型
主流公开数据集

  • ImageNet数据集
  • PASCAL VOC数据集
  • COCO(Common Object in Context)数据集

数据加载

PyTorch将数据集的处理过程标准化,提供了Dataset基本的数据类,并在torchvision中提供了众多数据变化函数,数据加载的具体过程主要分为3步:

  1. 继承Dataset类
  2. 增加数据变换与增强:torchvision.transforms
  3. 继承Dataloader

1.继承Dataset类
对于数据集的处理,PyTorch提供了torch.utils.data.Dataset这个抽象类,在使用时只需要继承该类,并重写__len__()和__getitem()__函数,即可以方便地进行数据集的迭代

from torch.utils.data import Dataset


class my_data(Dataset):
    def __init__(self,image_path,annotation_path,transform=None):
        #初始化,读取数据集
    def __len__(self):
        #获取数据集的总大小
    def __getitem__(self, item):
        #对于指定的item,读取该数据并返回

对上述类进行实例化,即可进行迭代如下:

dataset = my_data("your image path","your annotation path")    #实例化该类
for data in dataset:
    print(data)

2. 数据变化与增强:torchvision.transforms
第一步虽然将数据集加载到了实例中,但在实际应用时,数据集中的图片有可能存在大小不一的情况,并且原始图片像素RGB值较大(0-255),这些都不利于神经网络的训练收敛,因此还需要进行一些图像变换工作。PyTorch为此提供了torchvision.transforms工具包,可以方便地进行图像缩放、裁剪、随即翻转、填充及张量的归一化等操作,操作对象是PIL的Image或者Tensor
如果需要进行多个变换功能,可以利用transforms.Compose将多个变化整合起来,并且在实际使用时,通常会将变换操作集成到Dataset的继承类中:

from torchvision import transforms
#将transforms继承到Dataset类中,使用Compose将多个变换整合到一起
dataset = my_data("your image path","your annotation path",transforms=transforms.Compose({
    transforms.Resize(256)   #将图像最短边缩小至256,宽高比例不变
    #以0.5的概率随即翻转指定的PIL图像
    transforms.RandomHorizontalFlip()
    #将PIL图像转为Tensor,元素区间从[0,255]归一到[0,1]
    transforms.ToTensor()
    #进行mean与std为0.5的标准化
    transforms.Normalize([0.5,0.5,0.5],[0.5,0.5,0.5])  
}))

3. 继承dataloader
经过前两步已经可以获取每一个变换后的样本,但是仍然无法进行批量处理、随机选取等操作,因此还要torch.utils.data.Dataloader类进一步封装,使用方法如下例所示,该类需要4个参数

  • 第1个参数是之前继承了Dataset的实例
  • 第2个参数是批量batch的大小
  • 第3个参数是是否打乱数据参数
  • 第4个参数是使用几个线程来加载数据
from torch.utils.data import Dataloader
#使用Dataloader进一步封装Dataset
dataloader = Dataloader(dataset,batch_size=4,shuffle=True,num_workers=4)

dataloader是一个可迭代对象,对该实例进行迭代即可用于训练过程

data_iter = iter(dataloader)
for step in range(iters_per_epoch):
    data = next(data_iter)
    #将data用于训练网络即可

GPU加速

PyTorch为数据在GPU上运行提供了非常便利的操作。首先可以使用torch.cuda.is_available()来判断当前环境下GPU是否可用,其次是对于Tensor和模型,可以直接调用cuda()方法将数据转移到GPU上运行,并且可以输入数字来指定具体转移到哪块GPU上运行

>>> import torch
>>> from torchvision import models
>>> a = torch.randn(3,3)
>>> b = models.vgg16()
>>> #判断当前GPU是否可用
>>> if torch.cuda.is_available():
...     a = a.cuda()
...     #指定将b转移到编号为1的GPU上
...     b = b.cuda(1)
...
>>> #使用torch.device()来指定使用哪一个GPU
>>> device = torch.device("cuda:1")
>>> c = torch.randn(3,3,device = device, requires_grad = True)

对于在全局指定使用哪一块GPU,官方给出了两种方法,首先实在终端执行脚本时直接指定GPU方式,如下:

CUDA_VISIBLE_DEVICES=2 python3 train.py

其次是在脚本中利用函数指定,如下:

import torch
torch.cuda.set_device(1)

官方建议使用第一种方法

在工程应用中,通常使用torch.nn.DataParallel(model,device_ids)函数来处理多GPU并行计算的问题。示例如下:

model_gpu = nn.Dataparallel(model,device_ids=[0,1])
output = model_gpu(input)

多GPU处理的实现方式是,首先将模型加载的主GPU上,然后复制模型到各个指定的GPU上,将输入数据按batch的维度进行划分,分配到每个GPU上独立进行前向计算,在将得到的损失求和并反向传播更新单个GPU上的参数,最后将更新后的参数复制到各个GPU上

你可能感兴趣的:(PyTorch基础)