数据准备

我们要用到的数据是CIFAR-10 dataset. 数据下载,数据介绍

CIFAR-10数据集里包含了60000张32*32的彩色图片。图片一共有十个种类。每个种类有5000个训练图片,1000个测试图片。

在继续阅读本篇文章之前,默认读者已经掌握了深度学习的基本概念,只是对PyTorch不熟悉 。如果你还不了解深度学习的原理,建议你读一下我写的深度学习系列文章

在你下载了cifar-10-python.tar.gz文件后,你可以解压.tar.gz,直到得到如下的文件:
batches.meta
data_batch_1
data_batch_2
data_batch_3
data_batch_4
data_batch_5
readme.html
test_batch

然后你可以用我下边的Python代码把这些文件转化为图片文件

import pickle
import numpy as np
import os
import cv2
def unpickle(file):
    with open(file,"rb") as fo:
        dict = pickle.load(fo,encoding = 'bytes')
    return dict
categories = ['airplane','automobile','bird','cat','deer','dog','frog','horse','ship','truck']
def write_image(dict,path):
    size = len(dict[b'labels'])
    for i in range(size):
        img = dict[b'data'][i]
        img = np.reshape(img,(3,32,32))
        img = img.transpose((1,2,0))
        img_name = dict[b'filenames'][i]
        img_label = dict[b'labels'][i]
        file_path = path+categories[img_label]+"\"+str(img_name,encoding='utf-8')
        print(file_path)
        cv2.imwrite(file_path,img)
def convert_to_image(sourcePath,targetPath):
    for i in range(10):
        path = targetPath+"
\train\"+categories[i]
        if(not os.path.exists(path)):
            os.makedirs(path)
        path = targetPath+"
\test\"+categories[i]
        if(not os.path.exists(path)):
            os.makedirs(path)
    path = targetPath+"
\train\"
    for i in range(1,6):
        dict = unpickle(sourcePath+"
\data_batch_"+str(i))
        write_image(dict,path)
path = targetPath+"
\test\"
dict = unpickle(sourcePath+"
\test_batch")
write_image(dict,path)

convert_to_image("
E:\data\cifar-10-python.tar\cifar-10-python\cifar-10-batches-py","E:\data\cifar10")<br />

注意,最后是通过调用convert_to_image方法来实现图片文件的生成的。这个方法有两个参数,第一个是我们解压好的原始文件,第二个参数转化为图片保存的目标路径。运行后,你会在保存图片的目标路径下看到test,和train两个文件夹,里边分别有10个文件夹,分别是10种要分类样本的图片。

在PyTorch里加载数据

加载图片文件,转化为可以放到神经网络训练的数据,这个工作是每个做深度学习的人都会遇到的,PyTorch当然贴心的为我们准备了工具类来实现。有了PyTorch的帮忙,我们可以方便的加载图片,文本,和音频等数据。

Dataset 和 DataLoader

Pytorch里将数据读入的功能由两个类来实现。一个是数据集合Dataset类。一个是负责数据读取方式的DataLoader类。
** Dataset **
一个Dataset对象主要实现两个方法,一个是根据index获取Dataset具体元素。一个是获取整个Dataset元素个数。它是一个数据集合类。
** DataLoader **
DataLoader是来定义以何种方式读取Dataset。比如用几个进程去读数据,或者batchsize,是否需要进行shuffle等。

ImageFolder

Pytorch的torchvision包下有一个ImageFolder类可以帮助我们方便的读取文件夹里的图片。它默认一个文件夹里的图片属于同一类别。类别名就是这个文件夹的名字,这个很符合常理。

我们看一下如何通过ImageFolder来生成Dataset,以及如何用DataLoader来获取数据:

import torch
import torchvision as tv
from torchvision import transforms

batch_size = 64

train_data_path = "E:/data/cifar10/train/"
train_data = tv.datasets.ImageFolder(train_data_path)
train_data_loader = torch.utils.data.DataLoader(train_data,batch_size,shuffle=True)

test_data_path = "E:/data/cifar10/test/"
test_data = tv.datasets.ImageFolder(test_data_path)
test_data_loader = torch.utils.data.DataLoader(test_data,batch_size,shuffle=False)

Transfom

在读取数据时,同时可以对数据做一些必要的转化,比如对每一个channel进行归一化,改变图片的size等。每一种对数据的转化都对应一个Transform。在生成Dataset时,我们可以传入一个Transform的集合来对读入的图片进行多种叠加的操作:

import torch
import torchvision as tv
from torchvision import transforms

batch_size = 64
transform = transforms.Compose(
    [transforms.ToTensor(),
     transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])
train_data_path = "E:/data/cifar10/train/"
train_data = tv.datasets.ImageFolder(train_data_path,transform=transform)
train_data_loader = torch.utils.data.DataLoader(train_data,batch_size,shuffle=True)

test_data_path = "E:/data/cifar10/test/"
test_data = tv.datasets.ImageFolder(test_data_path,transform=transform)
test_data_loader = torch.utils.data.DataLoader(test_data,batch_size,shuffle=False)

向上边的代码我们在读取图片数据时,同时做了两种transform,一个是归一化,每个通道的均值和方差都认为是0.5。另一个操作是将数据转化为Tensor。需要注意的是,如果我们在生成Dataset的时候,没有定义Transform,那么默认的Transform就是transforms.ToTensor()。如果你要覆盖默认的Tranform,就要记的加上transforms.ToTensor()。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

%d 博主赞过: