数据对于深度学习而言是至关重要的,丰富、完整、规范的数据集往往能训练出性能优异的网络模型。本次首先介绍物体检测领域当前较为主流的公开数据集,然后从数据的加载、数据的GPU加速、数据的可视化3个方面介绍。
深度学习能够取得快速发展的其中一个主要原因是建立在大量数据的基础上,是用数据 “喂” 出来的。世界上一些先进的研究机构和公司开源了一些规模庞大且质量高的数据集,为研究者提供了训练数据,也提供了标准的评测平台。
公开主流数据集 | 发布时间 | 发布机构 | 目的 | 容量 | 类别 | 标签 |
---|---|---|---|---|---|---|
ImageNet | 2009 | CVPR | 促进计算机图像识别的技术发展 | 1400W | 2W | 类别标注以及图像中物体位置信息 |
PASCAL VOC | 2005 | / | 图像识别、物体检测 | 11530 | 20 | 类别标注以及图像中物体位置信息 |
COCO | / | 微软 | 物体检测、分割、图像语义理解以及人体关节点等 | 30W | 80 | 类别标注以及图像中物体位置信息 |
对于数据集的处理,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):
# 对于指定的id,读取该数据并返回
def __getitem__(self, id):
定义完我们自己的Dataset类之后,对其进行实例化便可进行迭代。
# 实例化该类
dataset = my_data("your image path", "your annotation path")
for data in dataset:
print(data)
另外TorchVision还为我们提供了数据变换和增强的功能(torchvision.transforms),可以进行图像翻转,归一化,裁剪,缩放,张量转化等操作,操作对象是PIL的Image或者Tensor。如果需要进行多个变换,可以使用transform.Compose将多个变换整合起来集成到Dataset类中。
# 将transforms集成到Dataset类中,使用Compose将多个变换整合到一起
from torchvision import transforms
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]) ]))
定义好Dataset继承类之后,我们还需要设置数据集的批量化加载和加载方式。这就是第三步继承Dataloader(torch.utils.data.Dataloader)
from torch.utils.data import Dataloader
# 使用Dataloader进一步封装
dataloader = Dataloader(dataset, batch_size=4, shuffle=True, num_workers=4)
继承该类需要设置4个参数,其中dataset是实例化的Dataset,batch_size是批量batch的大小,shuffle表示是否打乱顺序之后加载,num_workers是使用几个线程来加载数据。
Dataloader是可迭代对象,对该实例进行迭代即可用于训练过程。
data_iter = iter(dataloader)
for step in range(iter_per_epoch):
data = next(data_iter)
#data直接用于训练网络
使用GPU加速之前我们要先通过torch.cuda.is_available()判断当前环境下GPU是否可用,其次是对于Tensor和模型可以直接调用cuda()方法将数据转移到GPU上运行,并且可以输入数字指定具体转移到哪一块GPU上运行。
import torch
from torchvision import models
a = torch.randn(3, 3)
b = models.vgg16()
#判断当前环境下CUDA是否可用
if torch.cuda.is_available():
#默认将a转移到第一块GPU上
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 python train.py
第二种方法是在脚本中利用函数指定
import torch
torch.cuda.set_device(1)
通常,官方建议使用第一种方法
在工程应用中,一般使用torch.nn.DataParallel(module, device_ids)函数完成多GPU并行运算的任务。
model_gpu = torch.nn.DataParallel(model, device_ids=[0, 1])
output = model_gpu(input)
多GPU并行运算的实现方式是先将模型加载到主GPU上,然后复制模型到各个指定的GPU上,将输入数据按照batch的维度进行划分,分配到各个GPU上进行独立前向计算,然后计算损失加和并反向传播更新单个GPU上的参数,最好将更新后的参数复制到各个GPU上。
网络训练的时候我们可以通过在终端打印时刻观察训练过程中的动态信息,掌握网络的优化方向并做出及时调整。但是终端打印的方式始终不太直观,因此出现了TensorBoardX和Visdom等可视化工具。
pip install -i https://pypi.douban.com/simple tensorboardx
在训练脚本中码出几句指令,便可创建记录对象和数据的添加
# 创建writer对象
from tensorboardX import SummaryWriter
# 添加曲线,并且可以使用'/'进行多级标题的指定
writer = SummaryWriter('logs/tmp') writer.add_scalar('loss/total_loss', loss.data[0], total_iter) writer.add_scalar('loss/rpn_loss', rpn_loss.data[0], total_iter)
运行脚本之后,会在logs/tmp文件夹下生成events开头的记录文件,然后使用TensorBoard在终端开启web服务。
tensorboard --logdir=logs/tmp(然后按回车)
会出现下面的指令
TensorBoard 1.9.0 at http://pytorch:6006 (Press CTRL+C to quit)
在浏览器中输入http://pytorch:6006即可看到数据的可视化效果
visdom是FB团队开发的一款非常灵活的可视化工具,可用于多种数据的创建、组织以及共享,支持Numpy、Torch、Pytorch数据。
Visdom下载安装
pip install -i https://pypi.douban.com/simple visdom
使用如下指令可以开启visdom服务,该服务基于web,并默认使用8079端口。
python -m visdom.server
下面实现一个文本、曲线以及图片的可视化示例,更多功能参考Github。
import torch import visdom
# 创建visdom客户端,使用默认端口8097,环境为first,环境的作用是对可视化的空间进行分区
vis = visdom.Visdom(env='first') # vis对象有text()、line()和image()等函数,其中的win参数代表了显示的窗格(pane)的名字
vis.text('first visdom', win='text1')
# 在此使用append为真来进行增加text,否则会覆盖之前的text
vis.text('hello PyTorch', win='text1', append=True)
# 绘制y=-i^2+20×i+1的曲线,opts可以进行标题、坐标轴标签等的配置
for i in range(20):
vis.line(X=torch.FloatTensor([i]), Y=torch.FloatTensor([-i**2+20*i+1]), opts={'title': 'y=-x^2+20x+1'}, win='loss', update='append')
# 可视化一张随机图片
vis.image(torch.randn(3, 256, 256), win='random_image')
运行之后,打开浏览器输入http://localhost:8097,即可看到可视化的结果。
我们可以看到在first环境下有三个窗口,第一个窗口显示的是我们创建的文本,第二个窗口显示的是绘制的函数曲线,第三个窗口显示的是我们随机生成的一张图片。
这篇博客主要总结回顾了一下之前使用Pytorch的方法和经验,主要包括目标检测的主流公开数据集、数据的创建与加载,GPU加速的方法,训练数据可视化工具的使用等,希望能帮助到大家。