Pytorch创建自己的数据集(一)


尽管torchvision已经为我们准备了很多的数据集,直接通过如下语句便可以随便调用。但是有时我们要处理自己的数据集,该怎么办呢?

mnist_train = torchvision.datasets.MNIST(root='~/Datasets/MNIST', train=True, download=True, transform=transforms.ToTensor())

1、Dataset+DataLoader实现自定义数据集读取方法

创建自己的数据集需要继承父类torch.utils.data.Dataset,同时需要重载两个私有成员函数:def __len__(self)def __getitem__(self, index)def __len__(self)应该返回数据集的大小;def __getitem__(self, index)接收一个index,然后返回图片数据和标签,这个index通常指的是一个list的index,这个list的每个元素就包含了图片数据的路径和标签信息。如何制作这个list呢,通常的方法是将图片的路径和标签信息存储在一个txt中,然后从该txt中读取。

整个流程如下:

创建相应的txt文件
创建__init__函数进行参数和函数初始化以及创建list
将list传入__getitem__调用index对应的一张图片进行处理并返回处理后的图片与对应的label
__len__返回数据集大小
创建实例并将其导入DataLoader中进行设置
1.1、整体框架
class MyDataset(torch.utils.data.Dataset):#需要继承torch.utils.data.Dataset
    def __init__(self):
        #对继承自父类的属性进行初始化(好像没有这句也可以??)
        super(MyDataset,self).__init__()
        # TODO
        #1、初始化一些参数和函数,方便在__getitem__函数中调用。
        #2、制作__getitem__函数所要用到的图片和对应标签的list。
        #也就是在这个模块里,我们所做的工作就是初始化该类的一些基本参数。
        pass
    def __getitem__(self, index):
        # TODO
        #1、根据list从文件中读取一个数据(例如,使用numpy.fromfile,PIL.Image.open)。
        #2、预处理数据(例如torchvision.Transform)。
        #3、返回数据对(例如图像和标签)。
        #这里需要注意的是,这步所处理的是index所对应的一个样本。
        pass
    def __len__(self):
        #返回数据集大小
        return len()
1.2、例子讲解

给出一个最简单的例子,来理解整个过程。

第一步:先收集几张图片作为自己的数据集,然后自己手动创建一个txt文件(关于txt文件,通过python和matlab可以很容易的创建)储存图片对应的label。

图片文件如下
在这里插入图片描述

相应的txt文件如下

在这里插入图片描述

第二步:创建自己的数据集类。

import torch
import torchvision
from torchvision import transforms
from PIL import Image
from torch.utils.data import Dataset
from torch.utils.data import DataLoader

#路径是自己电脑里所对应的路径
datapath = r'E:\Python\DeepLearning\Datasets\testdata'
txtpath = r'E:\Python\DeepLearning\Datasets\testdata\label.txt'

class MyDataset(Dataset):
    def __init__(self,txtpath):
        #创建一个list用来储存图片和标签信息
        imgs = []
        #打开第一步创建的txt文件,按行读取,将结果以元组方式保存在imgs里
        datainfo = open(txtpath,'r')
        for line in datainfo:
            line = line.strip('\n')
            words = line.split()
            imgs.append((words[0],words[1]))

        self.imgs = imgs
	#返回数据集大小
    def __len__(self):
        return len(self.imgs)
	#打开index对应图片进行预处理后return回处理后的图片和标签
    def __getitem__(self, index):
        pic,label = self.imgs[index]
        pic = Image.open(datapath+'\\'+pic)
        pic = transforms.ToTensor()(pic)
        return pic,label
#实例化对象
data = MyDataset(txtpath)
#将数据集导入DataLoader,进行shuffle以及选取batch_size
data_loader = DataLoader(data,batch_size=2,shuffle=True,num_workers=0)
#Windows里num_works只能为0,其他值会报错

经过以上两步处理,就获得了可以输入到神经网络里的自己的数据集了。我们可以查看一下我们所获得的data_loader:

for pics,label in data_loader:
    print(pics,label)

输出如下:

tensor([[[[0., 0., 0.,  ..., 0., 0., 0.],
          [0., 0., 0.,  ..., 0., 0., 0.],
          [0., 0., 0.,  ..., 0., 0., 0.],
          ...,
          [0., 0., 0.,  ..., 0., 0., 0.],
          [0., 0., 0.,  ..., 0., 0., 0.],
          [0., 0., 0.,  ..., 0., 0., 0.]]],


        [[[0., 0., 0.,  ..., 0., 0., 0.],
          [0., 0., 0.,  ..., 0., 0., 0.],
          [0., 0., 0.,  ..., 0., 0., 0.],
          ...,
          [0., 0., 0.,  ..., 0., 0., 0.],
          [0., 0., 0.,  ..., 0., 0., 0.],
          [0., 0., 0.,  ..., 0., 0., 0.]]]]) ('4', '2')
tensor([[[[0., 0., 0.,  ..., 0., 0., 0.],
          [0., 0., 0.,  ..., 0., 0., 0.],
          [0., 0., 0.,  ..., 0., 0., 0.],
          ...,
          [0., 0., 0.,  ..., 0., 0., 0.],
          [0., 0., 0.,  ..., 0., 0., 0.],
          [0., 0., 0.,  ..., 0., 0., 0.]]],


        [[[0., 0., 0.,  ..., 0., 0., 0.],
          [0., 0., 0.,  ..., 0., 0., 0.],
          [0., 0., 0.,  ..., 0., 0., 0.],
          ...,
          [0., 0., 0.,  ..., 0., 0., 0.],
          [0., 0., 0.,  ..., 0., 0., 0.],
          [0., 0., 0.,  ..., 0., 0., 0.]]]]) ('2', '1')
tensor([[[[0., 0., 0.,  ..., 0., 0., 0.],
          [0., 0., 0.,  ..., 0., 0., 0.],
          [0., 0., 0.,  ..., 0., 0., 0.],
          ...,
          [0., 0., 0.,  ..., 0., 0., 0.],
          [0., 0., 0.,  ..., 0., 0., 0.],
          [0., 0., 0.,  ..., 0., 0., 0.]]],


        [[[0., 0., 0.,  ..., 0., 0., 0.],
          [0., 0., 0.,  ..., 0., 0., 0.],
          [0., 0., 0.,  ..., 0., 0., 0.],
          ...,
          [0., 0., 0.,  ..., 0., 0., 0.],
          [0., 0., 0.,  ..., 0., 0., 0.],
          [0., 0., 0.,  ..., 0., 0., 0.]]]]) ('0', '1')
tensor([[[[0., 0., 0.,  ..., 0., 0., 0.],
          [0., 0., 0.,  ..., 0., 0., 0.],
          [0., 0., 0.,  ..., 0., 0., 0.],
          ...,
          [0., 0., 0.,  ..., 0., 0., 0.],
          [0., 0., 0.,  ..., 0., 0., 0.],
          [0., 0., 0.,  ..., 0., 0., 0.]]],


        [[[0., 0., 0.,  ..., 0., 0., 0.],
          [0., 0., 0.,  ..., 0., 0., 0.],
          [0., 0., 0.,  ..., 0., 0., 0.],
          ...,
          [0., 0., 0.,  ..., 0., 0., 0.],
          [0., 0., 0.,  ..., 0., 0., 0.],
          [0., 0., 0.,  ..., 0., 0., 0.]]]]) ('4', '0')
tensor([[[[0., 0., 0.,  ..., 0., 0., 0.],
          [0., 0., 0.,  ..., 0., 0., 0.],
          [0., 0., 0.,  ..., 0., 0., 0.],
          ...,
          [0., 0., 0.,  ..., 0., 0., 0.],
          [0., 0., 0.,  ..., 0., 0., 0.],
          [0., 0., 0.,  ..., 0., 0., 0.]]],


        [[[0., 0., 0.,  ..., 0., 0., 0.],
          [0., 0., 0.,  ..., 0., 0., 0.],
          [0., 0., 0.,  ..., 0., 0., 0.],
          ...,
          [0., 0., 0.,  ..., 0., 0., 0.],
          [0., 0., 0.,  ..., 0., 0., 0.],
          [0., 0., 0.,  ..., 0., 0., 0.]]]]) ('3', '3')

以上结果显示,data_loader这个迭代器里存储的是每2个一组(batch_size)的图片像素信息以及对应的标签信息,也就是我们后续要导入到神经网络里的数据。

以上操作只是一个最简单的用来加深理解的例子,实际应用时会比这复杂很多,比如图像的渲染、变换等,但是基本流程都是一样的。

1.3、txt文件的生成

这部分留到以后再添加进来
pass

2、ImageFolder+DataLoader实现本地数据导入

在pytorch中提供了torchvision.datasets.ImageFolder让我们训练自己的图像。ImageFolder假设所有的文件按文件夹保存,每个文件夹下存储同一个类别的图片,文件夹名为类名,其构造函数如下:

ImageFolder(root, transform=None, target_transform=None, loader=default_loader)

它主要有四个参数:
root:在root指定的路径下寻找图片
transform:对loader读取图片的返回对象进行转换操作(ToTensor等)
target_transform:对label的转换
loader:给定路径后如何读取图片,默认读取为RGB格式的PIL Image对象

文件夹严格按照如下方式保存:

    .
    ├──train
    |   ├──类别1
    |   |   ├──*.jpg
    |   |   ├──*.jpg
    |   |   └──...
    |   ├──类别2
    |   |   ├──*.jpg
    |   |   ├──*.jpg
    |   |   └──...
    |   └──...
    └──test  
        ├──类别1
        |   ├──*.jpg
        |   ├──*.jpg
        |   └──...
        ├──类别2
        |   ├──*.jpg
        |   ├──*.jpg
        |   └──...
        └──...

实现代码如下

transform = transforms.ToTensor()
root = r'E:\Python\DeepLearning\Datasets\mymnist\train'
# 使用torchvision.datasets.ImageFolder读取数据集 指定train 和 test文件夹
train_data = torchvision.datasets.ImageFolder(root, transform=transform)
train_iter = torch.utils.data.DataLoader(train_data, batch_size=256, shuffle=True, num_workers=0)

test_data = torchvision.datasets.ImageFolder(root, transform=transform)
test_iter = torch.utils.data.DataLoader(test_data, batch_size=256, shuffle=True, num_workers=0)

参考资料
https://blog.csdn.net/sinat_42239797/article/details/90641659

评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值