Pytorch读取数据--两个关键函数


数据读取主要使用dataset和dataloader类。

dataset

在这里插入图片描述dataset函数在乱序的输入数据中,实现对数据的整理和排序,输入数据列表,支持下表检测。
dataloader函数将dataset输出的数据列表打包分块,将数据设置为batchsize大小。
有两种数据组织形式:一种是将同一label类型的数据放入同一文件夹下,文件夹名称就是label;第二种是一个文件夹中放数据,另一个文件夹放label。
在这里插入图片描述
所有的数据集都需要继承dataset这个类;每个子类都需要重写getitem这个函数,用于获取数据集和label;可以选择性重写len方法,返回数据集长度。

#torch.utils.data包用于加载数据
#os包用于文件操作
from torch.utils.data import Dataset
import os
from PIL import Image

class Mydata(Dataset):
    def __init__(self,root_dir,label_dir):
        self.root_dir=root_dir
        self.label_dir=label_dir
        self.path=os.path.join(self.root_dir,self.label_dir)#将两个路径进行拼接
        self.img_list=os.listdir(self.path)#列出路径下的文件列表

    def __getitem__(self, idx):
        img_path=self.img_list[idx]
        img_item_path=os.path.join(self.path,img_path)
        img=Image.open(img_item_path)
        label=self.label_dir
        return img,label
    def __len__(self):
        return len(self.img_list)

root_dir="D:\\project\\pytorch-tutorial-master\\hymenoptera_data\\train"
label_dir="ants"
ants_data=Mydata(root_dir,label_dir)#创建类的对象
img,label=ants_data[1]#该处使用魔法函数,使类对象具有检索id的功能
img.show()

使用self定义的类中全局变量,使用时通过self.变量,即使该变量的定义和使用在同一函数中
不使用self定义的变量的作用域只有定义变量所在的函数,使用时不需要加self,在其他函数中不能使用
写地址时,使用符号"/""\",不能使用""

魔法函数
上述代码中的三个函数都属于魔法函数。
__init__函数用于初始化类属性,在类创建对象时自动调用,无需用户在外界调用,类似于C++中类的构造函数,在创建对象时自动调用。
__getitem__函数赋予对象id检索功能,用户使用ants_data[id]时相当于自动调用ants_data.getitem(id)。
__len__函数返回长度:len(ants_data)相当于调用ants_data.len()。

tensorboard

显示函数图形和图片
SummaryWriter该类是一个直接向log_dir写东西的事件文件,可以被tensorboard进行解析。
大概就是可以将函数,图片和网络模型写入一个事件文件,该文件在tensorboard上进行显示,SummaryWriter就是操作将函数,图片和网络模型写入事件文件的类。

  1. 新建SummaryWriter类对象
  2. 准备数据
  3. writer.add_image()或writer.add_scalar()
  4. 关闭writer.close()
from torch.utils.tensorboard import SummaryWriter
import numpy as np
from PIL import Image

writer = SummaryWriter("logs")#新建类
image_path = "data/train/ants_image/6240329_72c01e663e.jpg"
img_PIL = Image.open(image_path)
img_array = np.array(img_PIL)
print(type(img_array))
print(img_array.shape)

writer.add_image("train", img_array, 1, dataformats='HWC')#将图片写入事件文件
# y = 2x
for i in range(100):
    writer.add_scalar("y=2x", 3*i, i)#将函数写入事件文件
#关闭
writer.close()

具体执行过程:

  1. 运行后会生成logs文件夹,且在文件夹下生成执行文件,每运行一次生成一次。
  2. 执行文件:在terminal中将路径定位到logs文件夹的上一级文件夹输入tensorboard --logdir=logs;默认打开的端口号是6006,为了避免多进程时产生冲突,手动更改端口号,tensorboard --logdir=logs --port=端口号
    在这里插入图片描述
    在这里插入图片描述
  3. 点击链接,进入tensorboard.
    在这里插入图片描述
    注意
    当修改writer.add_scalar(“y=2x”,2i,i),再重新运行生成执行文件,再将执行文件打开。生成两个图形。在这里插入图片描述
    当只修改函数表达式,不修改title。修改writer.add_scalar(“y=2x”,3
    i,i),再重新运行生成执行文件,再将执行文件打开。出错。解决方式:把之前logs文件夹下的执行文件删除再重新开始运行;创建新的文件夹放执行文件。
    在这里插入图片描述

add_scale()

def add_scalar(self, tag, scalar_value, global_step=None, walltime=None):

tag相当于title,scalar_value相当于y轴,global_step相当于x轴
在这里插入图片描述

add_image()

def add_image(self, tag, img_tensor, global_step=None, walltime=None, dataformats='CHW'):

tag (string): title
img_tensor (torch.Tensor, numpy.array, or string/blobname): Image data#要求输入图片的格式为tensor,numy,或者字符串

  • • Image.open()函数读出图片数组类型为’PIL.JpegImagePlugin.JpegImageFile’
    • opencv读取图片数组格式为numpy格式,将数组转换为numpy格式:np.array()
    经过Image读取并转成numpy的图像数组格式为(H,W,C),add_image()函数默认使用输入图片的格式为(C,H,W),所以需要指定dataformats参数。

如果后续添加图像,改变图像路径,没有改变title,图像将以step的形式展示(需要修改step);要想让图像单独显示,只需要在生成执行文件时修改title.

transform

transform是一个python文件,里面有很多用于图片处理的类。
在这里插入图片描述
如何将图片数据变为tensor数据类型

  1. 新建一个ToTensor类的对象
  2. 将图像传入
from torchvision import transforms
from  PIL import Image
img_path="D:\\project\\pytorch-learn-code\\pytorch-tutorial-master\\hymenoptera_data\\train\\ants\\0013035.jpg"
img_PIL=Image.open(img_path)
#1.新建一个ToTensor类的对象
tensor_trans=transforms.ToTensor()
#2.将图像传入
#在括号中Ctrl+p可以显示需要输入的参数
img_tensor=tensor_trans(img_PIL)
print(img_tensor)

几种常见的transforms的使用

from PIL import Image
from  torchvision import transforms
from torch.utils.tensorboard import SummaryWriter
writer=SummaryWriter("Test")
img=Image.open("D:\\project\\pytorch-learn-code\\pytorch-tutorial-master\imgs\\000.jpg")

#Totensor
tensor_trans=transforms.ToTensor()
img_tensor=tensor_trans(img)
writer.add_image("Totensor",img_tensor)

#Normalize
#input[channel] = (input[channel] - mean[channel]) / std[channel]
trans_norm=transforms.Normalize([0.5,0.5,0.5],[0.5,0.5,0.5])
img_norm=trans_norm(img_tensor)
writer.add_image("Norm",img_norm)
writer.close()

compose的使用

Compose()中的参数需要是一个列表。python中,列表的表示形式为【数据1,数据2,…】,在Compose中,数据需要是transforms类型,所以得到compose([transforms参数1,transforms参数2,…])

from PIL import Image
from torchvision import transforms
from torch.utils.tensorboard import  SummaryWriter
writer=SummaryWriter("Test")
img=Image.open("D:\\project\\pytorch-learn-code\\pytorch-tutorial-master\imgs\\000.jpg")
#compose
trans_resize=transforms.Resize(512)
trans_totensor=transforms.ToTensor()
trans_compose=transforms.Compose([trans_resize,trans_totensor])
img_compose=trans_compose(img)
writer.add_image("Compose",img_compose)
writer.close()
• 上述程序是将图片img,先经过resize,再经过totensor。

注意:前面transforms函数的输出,必须和后面transforms函数的输出匹配。

torchvision数据集

在这里插入图片描述
• root:数据存储位置
• train:True为训练集,False为测试集
• download:TRUE下载数据集,如果数据集已经下载完成,不会重新下载
transfrom:执行transforms中的操作,对文件中的每张图片都进行

import torchvision
from torch.utils.tensorboard import SummaryWriter
#定义tensorforms操作,将数据集中的每张图片都Totensor
dataset_transform = torchvision.transforms.Compose([
    torchvision.transforms.ToTensor()
])

train_set = torchvision.datasets.CIFAR10(root="./dataset", train=True, transform=dataset_transform, download=True)
test_set = torchvision.datasets.CIFAR10(root="./dataset", train=False, transform=dataset_transform, download=True)

# print(test_set[0])#获取第一个图片,类似于之前的Dataset
# print(test_set.classes)#获取类别序列
# img, target = test_set[0]#target是类别id,对应在classes列表中的索引
# print(img)
# print(target)
# print(test_set.classes[target])

#将数据集中的前10个在tensorboard中进行显示
writer = SummaryWriter("p10")
for i in range(10):
    img, target = test_set[i]
    writer.add_image("test_set", img, i)

writer.close()

dataloader

dataset是数据集,dataloader是从dataset中取部分数据送入神经网络。
在这里插入图片描述
○ dataset:没有默认值,数据集的位置,数据集的索引,第一张,第二张数据到底是什么;总共有多少数据
○ batch_size:每次读取数据的数量
○ shuffle:读取数据之前是否将数据打乱,TRUE打乱
○ batch_sampler
○ num_workers:是否采用多进程加载数据
drop_last:当数据不够一个batch时,剩下的数据是舍弃还是不舍弃,TRUE舍弃

import torchvision
# 准备的测试数据集
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
#测试数据集
test_data = torchvision.datasets.CIFAR10("./dataset", train=False, transform=torchvision.transforms.ToTensor())
#加载测试集
test_loader = DataLoader(dataset=test_data, batch_size=64, shuffle=True, num_workers=0, drop_last=True)

# 测试数据集中第一张图片及target
img, target = test_data[0]
print(img.shape)
print(target)

writer = SummaryWriter("dataloader")
for epoch in range(2):
    step = 0
    for data in test_loader:
        imgs, targets = data
        # print(imgs.shape)
        # print(targets)
        writer.add_images("Epoch: {}".format(epoch), imgs, step)
        step = step + 1

writer.close()
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值