数据对于深度学习而言是至关重要的。丰富、完整、规范的数据集往往能训练处效果更佳的网络模型
主流公开数据集
PyTorch将数据集的处理过程标准化,提供了Dataset基本的数据类,并在torchvision中提供了众多数据变化函数,数据加载的具体过程主要分为3步:
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个参数
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用于训练网络即可
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上