pytorch学习1:如何加载自己的训练数据

转载自:https://blog.csdn.net/woshicao11/article/details/78318156,本文只做个人记录学习使用,版权归原作者所有。

Pytorch中文文档已出(http://pytorch-cn.readthedocs.io/zh/latest/)。第一篇博客献给了pytorch,主要是为了整理自己的思路。

原来使用caffe,总是要编译,经历了无数的坑。当开始接触pytorch时,果断拔草caffe。

学习Pytorch最好有一些深度学习理论基础才更好开,废话不多说,进入主题。

1 先有个框框,再往里面填东西
当训练一个神经网络的时候,我们需要有数据,有模型,并且需要设置训练的参数。为了不乱,我们最好分别定义三个文件,分别是:数据准备和预处理traindataset.py+编写模型model.py+如何训练main.py(xx.py,xx自己可任意取名)。

今天我们只讲数据准备与预处理阶段:traindataset.py(怎样命名无所谓,as you like)。这个文件的作用是什么呢?

统一将图像(或矩阵)返回成torch能处理的[original_iamges.tensor,label.tensor]
我们先跳跃一下看中文介绍是如何导入数据:

torch.utils.data.Dataloader(dataset, batch_size=1, shuffle=False, sample=None, num_workers=0, collate_fn=, pin_memory=False, drop_last=False)

我们一般关注dataloader的四个参数,dataset, batch_size, shuffle, num_workers=0

batch_size是你批处理数目,shuffle是否每个epoch都打乱,workers是载入数据的线程数。

我们具体再看看dataset——加载数据的数据集

这个dataset是[original_images.tensor, label.tensor]之类的,我们定义的traindataset.py就是产生这个dataset的,然后只需要在main.py文件import就可以调用!

from traindataset import *

2 定义一个自己的py文件产生自己的dataset

这个py文件一定要:

1)能输入自己的数据路径2)还能预处理

step 1:先导入你肯定需要的库路径

import torch.utils.data
import torch
from torchvision import transforms

torch.utils.data模块是子类化你的数据

transforms库对数据进行预处理

step 2:自定义dataset类(子类化你的数据)

class MyTrainData(torch.utils.data.Dataset)    

这里继承了torch.utils.data.Dataset这个类,我们看看这个类在中文文档中介绍:

所有其他类数据集都应该进行子类化。所有子类应该override_len_和_getitem_,前者提供了数据集的大小,后者支持整数索引,范围是从0到len(self),当然还有一个初始化_init_()_

类:属性+方法,_init_()就是定义自己的属性

我们脸谱化基础框架,再往里面加东西(以下为基础框架)

import torch.utils.data as data
import torch
import torchvision.transforms as transforms

class MyTrainData(torch.utils.data.Dataset) #子类化
    def __init__(self,root,transform=None,train=True): #第一步,初始化各个变量
        self.root=root
        self.train=train

    def __getitem__(self,idx): #第二步,装载数据,返回[img,label],idx就是一张纸读取
        
        img=imread(img_path) #img_path根据自己的数据自定义,灵活性很高
        img=torch.from_numpy(img).float() #需要转换成float
        
        gt=imread(gt_path) #读取gt,如果是分类问题,可以根据文件夹或者命名赋值0 1
        gt=torch.from_numpy(gt).float()

        return img,gt

    def __len__(self):
        return len(self.imagenumber)  #这个是必须返回的长度

现在往框框里填:

(1)是否transform如裁剪、归一化、旋转等?如果需要transform则要区分test和train,比如说我train需要随机旋转,但是test则不需要操作

(2)如何做到一张一张对应读取图片?可以自定义这些函数

以下贴出完整代码:

import torch.utils.data as data
import torch

from scipy.ndimage import imread
import os
import os.path
import glob

import torchvision.transforms as transforms

def make_dataset(root,train=True):#读取自己的数据的函数
    dataset=[]
    if train:
        dirgt=os.path.join(root,'train_data/groundtruth')
        dirimg=os.path.join(root,'train_data/images')

    for fGT in glob.glob(os.path.join(dirgt,''*.jpg)):
        fName=os.path.basename(fGT)
        fImg='train_ori'+fName[8:]
        dataset.append([os.path.join(dirimg,fImg),os.path.join(dirgt,fName)]) 

return dataset

#自定义dataset的框架
class MyTrainData(data.Dataset):
    def __init__(self,root,transform=None,train=True): #初始化文件路径或文件名
        self.train=train
        if self.train:
            self.train_set_path=make_dataset(root,train)


    def __getitem__(self,idx):
        if self.train:
            img_path,gt_path=self.train_set_path[idx] 

            img=imread(img_path)
            img=np.atleast_3d(img).transpose(2,0,1).astype(np.float32)
            img=(img-img.min())/(img.max()-img.min())
            img=torch.from_numpy(img).float()

            gt=imread(gt_path)
            gt=np.atleast_3d(gt).transpose(2,0,1)
            gt=gt/255.0
            gt=torch.from_numpy(gt).float()

        return img,gt

    def __len__(self):
        return len(self.train_set_path)     

这里的py文件需要在最后的main.py中调用,所以root我并没有赋值,我会在main.py中赋值

这里我并没有用到“transform”进行预处理,如果你想用的话,在__getitem__()下面,return img,gt前面重新赋值

img=transforms.ToTensor(img)及gt=transforms.ToTensor(gt)

这里需要注意的是,查看中文文档transforms库有哪些变换,如果有需要涉及参数的如CenterCrop(size),需要先实例化,如crop=transforms.CenterCrop(10),再使用img=crop(img).

你可能感兴趣的:(深度学习)