动手学深度学习3.5图像分类数据集-笔记&练习(PyTorch)

以下内容为结合李沐老师的课程和教材补充的学习笔记,以及对课后练习的一些思考,自留回顾,也供同学之人交流参考。

本节课程地址:图片分类数据集_哔哩哔哩_bilibili

本节教材地址:3.5. 图像分类数据集 — 动手学深度学习 2.0.0 documentation (d2l.ai)

本节开源代码:...>d2l-zh>pytorch>chapter_linear-networks>image-classification-dataset.ipynb


图像分类数据集

MNIST数据集 (ef="https://zh-v2.d2l.ai/chapter_references/zreferences.html#id90">LeCunet al., 1998) 是图像分类中广泛使用的数据集之一,但作为基准数据集过于简单。 我们将使用类似但更复杂的Fashion-MNIST数据集 (ref="https://zh-v2.d2l.ai/chapter_references/zreferences.html#id189">Xiaoet al., 2017)。

%matplotlib inline
import torch
import torchvision
from torch.utils import data
from torchvision import transforms
from d2l import torch as d2l

d2l.use_svg_display()

读取数据集

我们可以[通过框架中的内置函数将Fashion-MNIST数据集下载并读取到内存中]。

# 通过ToTensor实例将图像数据从PIL类型变换成32位浮点数格式,
# 并除以255使得所有像素的数值均在0~1之间
trans = transforms.ToTensor()
mnist_train = torchvision.datasets.FashionMNIST(
    root="../data", train=True, transform=trans, download=True)
mnist_test = torchvision.datasets.FashionMNIST(
    root="../data", train=False, transform=trans, download=True)

输出结果:

Downloading http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/train-images-idx3-ubyte.gz
Downloading http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/train-images-idx3-ubyte.gz to ../data\FashionMNIST\raw\train-images-idx3-ubyte.gz



0%| | 0/26421880 [00:00<?, ?it/s]


Extracting ../data\FashionMNIST\raw\train-images-idx3-ubyte.gz to ../data\FashionMNIST\raw

Downloading http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/train-labels-idx1-ubyte.gz
Downloading http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/train-labels-idx1-ubyte.gz to ../data\FashionMNIST\raw\train-labels-idx1-ubyte.gz



0%| | 0/29515 [00:00<?, ?it/s]


Extracting ../data\FashionMNIST\raw\train-labels-idx1-ubyte.gz to ../data\FashionMNIST\raw

Downloading http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/t10k-images-idx3-ubyte.gz
Downloading http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/t10k-images-idx3-ubyte.gz to ../data\FashionMNIST\raw\t10k-images-idx3-ubyte.gz



0%| | 0/4422102 [00:00<?, ?it/s]


Extracting ../data\FashionMNIST\raw\t10k-images-idx3-ubyte.gz to ../data\FashionMNIST\raw

Downloading http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/t10k-labels-idx1-ubyte.gz
Downloading http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/t10k-labels-idx1-ubyte.gz to ../data\FashionMNIST\raw\t10k-labels-idx1-ubyte.gz



0%| | 0/5148 [00:00<?, ?it/s]


Extracting ../data\FashionMNIST\raw\t10k-labels-idx1-ubyte.gz to ../data\FashionMNIST\raw

Fashion-MNIST由10个类别的图像组成, 每个类别由训练数据集(train dataset)中的6000张图像 和测试数据集(test dataset)中的1000张图像组成。 因此,训练集和测试集分别包含60000和10000张图像。 测试数据集不会用于训练,只用于评估模型性能。

len(mnist_train), len(mnist_test)

输出结果:

(60000, 10000)

每个输入图像的高度和宽度均为28像素。 数据集由灰度图像组成,其通道数为1。 为了简洁起见,本书将高度 ℎ 像素、宽度 𝑤 像素图像的形状记为 ℎ×𝑤 或(ℎ, 𝑤)。

mnist_train[0][0].shape
# 其中第一个[0]表示训练样本索引,第二个[0]表示样本特征索引,为三维数组(C,H,W)
# 输出(channel, h, w)

输出结果:

torch.Size([1, 28, 28])

[~~两个可视化数据集的函数~~]

Fashion-MNIST中包含的10个类别,分别为t-shirt(T恤)、trouser(裤子)、pullover(套衫)、dress(连衣裙)、coat(外套)、sandal(凉鞋)、shirt(衬衫)、sneaker(运动鞋)、bag(包)和ankle boot(短靴)。 以下函数用于在数字标签索引及其文本名称之间进行转换。

def get_fashion_mnist_labels(labels):  #@save
    """返回Fashion-MNIST数据集的文本标签"""
    text_labels = ['t-shirt', 'trouser', 'pullover', 'dress', 'coat',
                   'sandal', 'shirt', 'sneaker', 'bag', 'ankle boot']
    return [text_labels[int(i)] for i in labels]

我们现在可以创建一个函数来可视化这些样本。

def show_images(imgs, num_rows, num_cols, titles=None, scale=1.5):  #@save
    """绘制图像列表"""
    figsize = (num_cols * scale, num_rows * scale)
    _, axes = d2l.plt.subplots(num_rows, num_cols, figsize=figsize)
    """使用了d2l.plt.subplots()函数创建了一个包含num_rows行、num_cols列的子图网格,
    并将返回的figure对象赋值给_,将所有子图对象赋值给axes.
    _是一个占位符变量,一般用于表示不需要使用的变量。"""
    axes = axes.flatten()
    # flatten()方法将axes数组展平为一维数组,便于之后对子图进行索引和操作
    for i, (ax, img) in enumerate(zip(axes, imgs)):
        if torch.is_tensor(img):
            # 图片张量
            ax.imshow(img.numpy())
        else:
            # PIL图片
            ax.imshow(img)
        ax.axes.get_xaxis().set_visible(False)
        ax.axes.get_yaxis().set_visible(False)
        # 隐藏当前子图的X轴和Y轴刻度
        if titles:
            ax.set_title(titles[i])
    return axes

以下是训练数据集中前[几个样本的图像及其相应的标签]。

X, y = next(iter(data.DataLoader(mnist_train, batch_size=18)))
show_images(X.reshape(18, 28, 28), 2, 9, titles=get_fashion_mnist_labels(y));

读取小批量

为了使我们在读取训练集和测试集时更容易,我们使用内置的数据迭代器,而不是从零开始创建。 回顾一下,在每次迭代中,数据加载器每次都会[读取一小批量数据,大小为batch_size]。 通过内置数据迭代器,我们可以随机打乱了所有样本,从而无偏见地读取小批量。

batch_size = 256

def get_dataloader_workers():  #@save
    """使用4个进程来读取数据"""
    return 4

train_iter = data.DataLoader(mnist_train, batch_size, shuffle=True,
                             num_workers=get_dataloader_workers())

我们看一下读取训练数据所需的时间。

timer = d2l.Timer()
for X, y in train_iter:
    continue
f'{timer.stop():.2f} sec'

输出结果:

'3.35 sec'

整合所有组件

现在我们[定义load_data_fashion_mnist函数],用于获取和读取Fashion-MNIST数据集。 这个函数返回训练集和验证集的数据迭代器。 此外,这个函数还接受一个可选参数resize,用来将图像大小调整为另一种形状。

def load_data_fashion_mnist(batch_size, resize=None):  #@save
    """下载Fashion-MNIST数据集,然后将其加载到内存中"""
    trans = [transforms.ToTensor()]
    if resize:
        trans.insert(0, transforms.Resize(resize))
    trans = transforms.Compose(trans)
    """transforms.Compose(trans)用于组合多个图像变换操作到一个变换操作链中,
    图像resize + 转换为Tensor"""
    mnist_train = torchvision.datasets.FashionMNIST(
        root="../data", train=True, transform=trans, download=True)
    mnist_test = torchvision.datasets.FashionMNIST(
        root="../data", train=False, transform=trans, download=True)
    return (data.DataLoader(mnist_train, batch_size, shuffle=True,
                            num_workers=get_dataloader_workers()),
            data.DataLoader(mnist_test, batch_size, shuffle=False,
                            num_workers=get_dataloader_workers()))

下面,我们通过指定resize参数来测试load_data_fashion_mnist函数的图像大小调整功能。

train_iter, test_iter = load_data_fashion_mnist(32, resize=64)
for X, y in train_iter:
    print(X.shape, X.dtype, y.shape, y.dtype)
    break

输出结果:

torch.Size([32, 1, 64, 64]) torch.float32 torch.Size([32]) torch.int64

我们现在已经准备好使用Fashion-MNIST数据集,便于下面的章节调用来评估各种分类算法。

小结

  • Fashion-MNIST是一个服装分类数据集,由10个类别的图像组成。我们将在后续章节中使用此数据集来评估各种分类算法。
  • 我们将高度 ℎ 像素,宽度 𝑤 像素图像的形状记为 ℎ×𝑤 或(ℎ, 𝑤)。
  • 数据迭代器是获得更高性能的关键组件。依靠实现良好的数据迭代器,利用高性能计算来避免减慢训练过程。

练习

1. 减少batch_size(如减少到1)是否会影响读取性能?

解:
较大的batch_size可以利用并行化操作来提高数据加载的效率。在读取数据时,可以同时加载多个样本到内存中,以减少磁盘读取数据的时间。而当batch_size减少到1时,无法利用并行化操作,每次只能加载一个样本,从而导致数据加载的效率降低。
此外,较小的batch_size也会带来更多的数据加载次数。数据加载在计算机中属于I/O操作,通常是相对较慢的。因此,较小的batch_size会导致更频繁的数据加载操作,增加了整体的读取时间。
然而,较小的batch_size也具有一些优点,比如更快的模型更新和更精确的梯度估计。因此,在选择batch_size时,需要综合考虑性能和模型训练的需求,权衡不同因素。

2. 数据迭代器的性能非常重要。当前的实现足够快吗?探索各种选择来改进它。

解:
1)使用pin_memory=True:在创建数据加载器时,设置pin_memory=True来将数据加载到GPU内存中,利用GPU的并行性来加快数据传输速度。
2)使用多个get_dataloader_workers:通过增加get_dataloader_workers参数的值,可以使用多个子进程或线程来并行读取数据,从而加快数据加载的速度。可以根据计算机的硬件配置和数据加载的需求,选择合适的get_dataloader_workers值。

3. 查阅框架的在线API文档。还有哪些其他数据集可用?

解:如下:

dir(torchvision.datasets)

输出结果:

['CIFAR10',
'CIFAR100',
'CLEVRClassification',
'Caltech101',
'Caltech256',
'CelebA',
'Cityscapes',
'CocoCaptions',
'CocoDetection',
'Country211',
'DTD',
'DatasetFolder',
'EMNIST',
'EuroSAT',
'FER2013',
'FGVCAircraft',
'FakeData',
'FashionMNIST',
'Flickr30k',
'Flickr8k',
'Flowers102',
'FlyingChairs',
'FlyingThings3D',
'Food101',
'GTSRB',
'HD1K',
'HMDB51',
'INaturalist',
'ImageFolder',
'ImageNet',
'KMNIST',
'Kinetics',
'Kinetics400',
'Kitti',
'KittiFlow',
'LFWPairs',
'LFWPeople',
'LSUN',
'LSUNClass',
'MNIST',
'Omniglot',
'OxfordIIITPet',
'PCAM',
'PhotoTour',
'Places365',
'QMNIST',
'RenderedSST2',
'SBDataset',
'SBU',
'SEMEION',
'STL10',
'SUN397',
'SVHN',
'Sintel',
'StanfordCars',
'UCF101',
'USPS',
'VOCDetection',
'VOCSegmentation',
'VisionDataset',
'WIDERFace',
'__all__',
'__builtins__',
'__cached__',
'__doc__',
'__file__',
'__loader__',
'__name__',
'__package__',
'__path__',
'__spec__',
'_optical_flow',
'caltech',
'celeba',
'cifar',
'cityscapes',
'clevr',
'coco',
'country211',
'dtd',
'eurosat',
'fakedata',
'fer2013',
'fgvc_aircraft',
'flickr',
'flowers102',
'folder',
'food101',
'gtsrb',
'hmdb51',
'imagenet',
'inaturalist',
'kinetics',
'kitti',
'lfw',
'lsun',
'mnist',
'omniglot',
'oxford_iiit_pet',
'pcam',
'phototour',
'places365',
'rendered_sst2',
'sbd',
'sbu',
'semeion',
'stanford_cars',
'stl10',
'sun397',
'svhn',
'ucf101',
'usps',
'utils',
'video_utils',
'vision',
'voc',
'widerface']

注:Pytorch框架自带数据集的详细介绍可参考:Pytorch自带数据集介绍_pytorch数据集_哎呦茶叶蛋的博客-CSDN博客

  • 32
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
动手深度学习是理解和掌握深度学习的重要途径之一。PyTorch作为一个开源的深度学习框架,具有易用性和灵活性,适合初者入门。下面我将介绍一些练习方法,帮助大家动手PyTorch。 首先,PyTorch的基础知识是必要的。可以通过阅读官方文档、教程和书籍等方式PyTorch的基本概念、操作和函数等知识点,了解它的使用方法和语法规则。 其次,可以通过实践来深入理解和掌握PyTorch。可以选择一些经典的深度学习模型,如卷积神经网络(CNN)、递归神经网络(RNN)等,利用PyTorch的功能实现这些模型。可以从模型的搭建、训练和评估等方面入手,逐步掌握PyTorch的使用方法和技巧。 此外,实践过程中可以使用一些已有的深度学习数据集,如MNIST手写数字数据集、CIFAR-10图像分类数据集等,用于模型的训练和测试。可以通过探索不同数据集的使用方法,了解数据预处理、批量处理和加载等操作。 同时,还可以PyTorch中的一些常用模块和函数,如优化器(Optimizer)、损失函数(Loss Function)等,了解它们的作用和使用方法,并在实践中尝试不同的组合和调节,优化模型的训练效果。 最后,还可以参与一些开源项目或者比赛,与其他开发者共同习和交流。可以从官方论坛、GitHub等平台获取一些有趣的项目,尝试运行和优化,加深对PyTorch的理解和运用能力。 总之,动手PyTorch的方式是最有效的方式之一。通过实践,可以深入理解深度学习的原理和PyTorch的使用方法,提升自己的编程能力和解决实际问题的能力。希望以上的建议对大家有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

scdifsn

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值