Skip to content

数据集和数据加载器

数据集和数据加载器(Dataset & DataLoader)

  • 引子
  • 什么是数据集
  • Dataset概要
  • 加载数据集
  • 迭代和可视化数据集
  • 创建自定义数据集
  • 使用数据加载器为训练模型准备数据
  • 遍历数据加载器

引子

  • 模型的开发过程包括数据的读取、网络的设计、优化方法与损失函数的选择以及一些辅助的工具等。

Torchvision

  • 计算机视觉是深度学习中最重要的一类应用,为了方便研究者使用,Pytorch团队专门开发了一个视觉工具包torchvision,这个包独立于Pytorch,需要通过pip install torchvision安装。

Torchvision

  • torchvision主要包含以下三个部分:
    • models:提供深度学习中各种经典网络的网络结构及预训练好的模型,包括AlexNet,VGG, ResNet,GoogLeNet等。
    • datasets:提供常用数据集的dataset加载,设计上继承了torch.utils.data.Dataset的属性,主要包括MNIST,CIFAR-10,ImageNet等数据集
    • transforms: 提供常用的数据预处理操作,主要包括对Tensor及PIL Image对象的操作

什么是数据集

数据集又称为资料集、数据集合或资料集合,是一种由数据所组成的集合。通常以表格形式(***.csv)出现。每一列代表一个特定变量。每一行都对应于某一成员的数据集的问题,每个数值被称为数据资料。

什么是数据集

  • 深度学习的关键是训练。无论是从图像处理到语音识别,每个问题都有其独特的细微差别和方法,使用高质量的数据集可以改善模型的性能。
  • 数据集分为三类——图像处理、自然语言处理和音频/语音处理。

什么是数据集

  • 在开始深度学习任务时,需要准备一些数据集用来训练自己的算法。在选择数据集上面,最好使用可以快速下载的小的数据集,这种数据不用花太多的时间来训练模型。此外,也可以使用一些标准的数据集或者被广泛使用的数据集,这样可以把测试结果和别人的结果进行对比,以此来看是否取得进展。

什么是数据集-自然语言处理

  • 文本分类
    • 路透社新闻稿主题分类,这是路透社在 1982 年整理的一系列按照新闻主题归类的数据。
    • IMDB电影评论情感分类。这是一个从 imdb.com 网站收集的电影评论的数据集,评论数据分为正向和负向。
  • 文本摘要
    • 法律案件报告数据集。这个数据集收集了 4000 个法律案件及其总结。
    • TIPSTER 会议总结语料库。这个语料库收集了近 200 份文件及其摘要。

什么是数据集-ImageNet

  • ImageNet是一个计算机视觉系统识别项目,是目前世界上图像识别最大的数据库。是美国斯坦福的计算机科学家李飞飞模拟人类的识别系统建立的,能够完成图像识别任务。目前已经包含14197122张图像,是已知的最大的图像数据库。每年的ImageNet大赛更是魂萦梦牵着国内外各个名校和大型IT公司以及网络巨头的心。

什么是数据集-MS COCO

  • MS COCO的全称是Microsoft Common Objects in Context,起源于微软于2014年出资标注的Microsoft COCO数据集,与ImageNet竞赛一样,被视为是计算机视觉领域最受关注和最权威的比赛之一。
  • COCO数据集是一个大型的、丰富的物体检测,分割和字幕数据集。这个数据集从复杂的日常场景中截取,图像包括91类目标,328,000影像和2,500,000个label。目前为止有语义分割的最大数据集,提供的类别有80类,有超过33万张图片,其中20万张有标注,整个数据集中个体的数目超过150万个。

Dataset概要

  • 在解决深度学习问题的过程中,往往需要花费大量的精力去处理数据,包括图像、文本、语音或其他二进制数据等。数据的处理对训练神经网络来说十分重要,良好的数据处理不仅会加速模型训练,也会提高模型效果。
  • 考虑到这一点,Pytorch 提供了几个高效便捷的工具(本节学习的Dataset和Dataloader),以便使用者进行数据处理或增强等操作,同时可通过并行化加速数据加载。

Dataset概要

  • 用于处理数据样本的代码可能会变得混乱且难以维护;理想情况下,我们希望数据集代码与模型训练代码分离,以获得更好的可读性和模块化。
  • Pytorch提供了两个数据原语:torch.utils.data.DataLoader和torch.utils.data.Dataset,允许您使用预加载的数据集和自己的数据。
  • Dataset存储样本及其对应的标签,DataLoader迭代包装在Dataset周围,以便于访问样本。

Dataset概要

  • Pytorch域库提供了许多预加载的数据集(如FashionMNIST ),这些数据集都是torch.utils.data.Dataset的子类(包括MNIST,CIFAR10/100,IMAGENET等数据集在设计上都继承了其相关属性)
  • Pytorch针对特定数据实现特定的函数,这些函数可以用来原型化和基准化神经网络模型。

数据集的加载

  • Pytorch中的 Dataset 类是一个抽象类,它可以用来表示数据集。我们通过继承 Dataset 类来自定义数据集的格式、大小和其它属性,后面就可以供 DataLoader 类直接使用。

数据集的加载

  • 以下是如何从TorchVision加载时尚MNIST数据集的示例。《Fashion-MNIST》是Zalando文章图像的数据集,由60,000个训练样本和10,000个测试样本组成。每个示例包括一个28×28灰度图像和一个来自10个类别之一的关联标签。

数据集的加载

  • 加载数据集所需的参数
  • 我们使用以下参数加载FashionMNIST数据集:
  • root 是存储训练/测试数据的路径。
  • train 指定训练或测试数据集。
  • download=True如果root不可用,则从互联网下载数据。
  • transformtarget_transform 指定特征和标签变换。

数据集的加载

import torch
from torch.utils.data import Dataset
from torchvision import datasets
from torchvision.transforms import ToTensor
import matplotlib.pyplot as plt

#使用以下参数加载FashionMNIST数据集
training_data = datasets.FashionMNIST(
    root="data",
    train=True,
    download=True,
    transform=ToTensor()
)

test_data = datasets.FashionMNIST(
    root="data",
    train=False,
    download=True,
    transform=ToTensor()
)

迭代和可视化数据集

  • 可以像python列表一样按索引提取数据集:training_data[index]。
  • 使用matplotlib来可视化训练数据中的一些样本。
'''手动索引数据集'''
labels_map = {
    0: "T-Shirt",
    1: "Trouser",
    2: "Pullover",
    3: "Dress",
    4: "Coat",
    5: "Sandal",
    6: "Shirt",
    7: "Sneaker",
    8: "Bag",
    9: "Ankle Boot",
}
#绘制标签图谱

'''使用matplotlib来可视化训练数据中的一些样本'''


figure = plt.figure(figsize=(8, 8))
#生成一个图框,指定figure的宽和高分别为8英寸
cols, rows = 3, 3
for i in range(1, cols * rows + 1):
    sample_idx = torch.randint(len(training_data), size=(1,)).item()
    #生成随机整数
    img, label = training_data[sample_idx]
    #获取随机整数对应的img和label
    figure.add_subplot(rows, cols, i)
    #添加子图
    plt.title(labels_map[label])
    plt.axis("off")
    plt.imshow(img.squeeze(), cmap="gray")
    #将imgsqueeze成二维,然后显示
plt.show()

创建自定义数据集

在Pytorch当中,数据加载可通过自定义的数据集对象实现,数据集对象会被抽象为Dataset类,实现自定义的数据集需要继承Dataset,可以直接访问(调用)Dataset的静态属性和方法。

创建自定义数据集

  • 自定义数据集类必须实现三个函数:__init____len__、和__getitem__
  • FashionMNIST图像存储在目录img_dir中,它们的标签分别存储在CSV文件annotations_file中。

创建自定义数据集

import pandas as pd
from torchvision.io import read_image

class CustomImageDataset(Dataset):
    #初始化包含图像、注释文件和转换的目录
    def __init__(self, annotations_file, img_dir, transform=None, target_transform=None):
        self.img_labels = pd.read_csv(annotations_file)
        self.img_dir = img_dir
        self.transform = transform
        self.target_transform = target_transform
    #返回数据集中的样本数
    def __len__(self):
        return len(self.img_labels)
    #加载并返回数据集中给定索引idx处的样本
    def __getitem__(self, idx):
        img_path = os.path.join(self.img_dir, self.img_labels.iloc[idx, 0])
        image = read_image(img_path)
        label = self.img_labels.iloc[idx, 1]
        if self.transform:
            image = self.transform(image)
        if self.target_transform:
            label = self.target_transform(label)
        return image, label

创建自定义数据集

  • __init__ 函数在实例化数据集对象时运行一次。
  • 初始化过程包含图像初始化、注释文件的初始化、transform的初始化。

创建自定义数据集

# __init__ 函数初始化过程包含图像初始化、注释文件的初始化、transform的初始化

tshirt1.jpg, 0
tshirt2.jpg, 0
......
ankleboot999.jpg, 9

def __init__(self, annotations_file, img_dir, transform=None, target_transform=None):
    self.img_labels = pd.read_csv(annotations_file)
    self.img_dir = img_dir
    self.transform = transform
    self.target_transform = target_transform

创建自定义数据集

#__len__ 函数返回数据集中的样本数   
def __len__(self):
    return len(self.img_labels)

创建自定义数据集

  • 函数__getitem__加载并返回数据集中给定索引idx处的样本。基于索引,它识别图像在磁盘上的位置,使用read_image将其转换为张量,从self.img_labels中的csv数据中检索相应的标签,并返回元组中的张量图像和相应标签。

创建自定义数据集

#函数__getitem__加载并返回数据集中给定索引idx处的样本
def __getitem__(self, idx):
    img_path = os.path.join(self.img_dir, self.img_labels.iloc[idx, 0])
    image = read_image(img_path)
    label = self.img_labels.iloc[idx, 1]
    if self.transform:
        image = self.transform(image)
    if self.target_transform:
        label = self.target_transform(label)
    return image, label

使用数据加载器为训练模型准备数据

  • Dataset检索数据集的特征并一次标注一个样本的标签。在训练模型时,我们通常希望传递“迷你批次”中的样本,在每个时期重新排列数据以减少模型过度拟合,并使用Python的多重处理来加速数据检索。
  • DataLoader是一个迭代器 ,它在一个简单的API中为我们抽象了这种复杂性。

使用数据加载器为训练模型准备数据

Dataset只负责数据的抽象,一次调用__getitem__只返回一个样本,而在训练神经网络时,需要对一个batch的数据进行操作,同时还需要对数据进行shuffle或者并行加速等操作。对此,Pytorch中提供了DataLoader帮助我们实现这些功能。

使用数据加载器为训练模型准备数据

from torch.utils.data import DataLoader

train_dataloader = DataLoader(training_data, batch_size=64, shuffle=True)
test_dataloader = DataLoader(test_data, batch_size=64, shuffle=True)

遍历数据加载器

  • 我们已经将该数据集加载到DataLoader中,并可以根据需要遍历该数据集。下面的每个迭代返回一批train_features和train_labels(分别包含batch_size=64个要素和标注)。因为我们指定shuffle=True,所以在我们遍历所有批处理之后,数据被打乱(为了更好地控制数据加载顺序,看一下采样器)。

遍历数据加载器

#使用shuffle在batch所有batch后打乱数据
# Display image and label.
train_features, train_labels = next(iter(train_dataloader))
print(f"Feature batch shape: {train_features.size()}")
print(f"Labels batch shape: {train_labels.size()}")
img = train_features[0].squeeze()
label = train_labels[0]
plt.imshow(img, cmap="gray")
plt.show()
print(f"Label: {label}")