PyTorch 07: PyTorch加载图像数据

到目前为止,我们一直使用的都是虚拟数据集。但在实际运用里,你会处理一些完整尺寸的图像,例如智能手机摄像头拍摄的图像。现在,我们将学习如何加载图像并使用它们训练神经网络。

我们将使用猫狗照片数据集(从 Kaggle 上可以获得)。下面是几个示例图像:
在这里插入图片描述

我们将使用该数据集训练神经网络区分猫和狗。五年前,这对于计算机视觉系统来说,是一项巨大的挑战。现在,它的应用就很普遍了。

%matplotlib inline
%config InlineBackend.figure_format = 'retina'

import matplotlib.pyplot as plt

import torch
from torchvision import datasets, transforms

import helper

加载图像的最简单方式是使用 torchvisiondatasets.ImageFolder文档)。使用 ImageFolder,就是这样:

dataset = datasets.ImageFolder('path/to/data', transform=transform)

其中 'path/to/data' 是通往数据目录的文件路径,transform 是用 torchvision 中的 transforms 模块构建的处理步骤列表。ImageFolder 中的文件和目录应按以下格式构建:

root/dog/xxx.png

root/dog/xxy.png

root/dog/xxz.png

root/cat/123.png

root/cat/nsdf3.png

root/cat/asd932_.png

每个图像类别都有各自存储图像的目录(catdog)。然后使用从目录名中提取的类别标记图像。图像 123.png 将采用类别标签 cat。你可以从此页面下载已经采用此结构的数据集。我还将其拆分成了训练集和测试集。

转换

使用 ImageFolder 加载数据时,你需要定义转换。例如,图像的尺寸不相同,但是我们需要将它们变成统一尺寸,才能用于训练模型。你可以使用 transforms.Resize() 调整尺寸或使用 transforms.CenterCrop()transforms.RandomResizedCrop() 等裁剪图像。我们还需要使用 transforms.ToTensor() 将图像转换为 PyTorch 张量。通常,你将使用 transforms.Compose()来将这些转换结合到一条流水线中,这条流水线接收包含转换的列表,并按顺序运行。流程大概为缩放、裁剪,然后转换为张量:

transform = transforms.Compose([transforms.Resize(255),

                    transforms.CenterCrop(224),             
                    
                    transforms.ToTensor()])

我们可以使用许多种转换,接下来我会逐步讲解,你也可以查看这里的文档

数据加载器

加载 ImageFolder 后,你需要将其传入 DataLoaderDataLoader 接受数据集(例如要从 ImageFolder 获得的数据集),并返回批次图像和相应的标签。你可以设置各种参数,例如批次大小,或者在每个周期之后是否重排数据。

dataloader = torch.utils.data.DataLoader(dataset, batch_size=32, shuffle=True)

dataloader 是一个生成器。要从中获取数据,你需要遍历它,或将它转换成迭代器并调用 next()

# Looping through it, get a batch on each loop 
for images, labels in dataloader:
    pass

# Get one batch
images, labels = next(iter(dataloader))

**练习:**请从 Cat_Dog_data/train 文件夹加载图像,定义几个转换,然后构建数据加载器。

data_dir = 'Cat_Dog_data/train'

#TODO: compose transforms here
transform = transforms.Compose([transforms.Resize(255),
                                transforms.CenterCrop(224),
                                transforms.ToTensor()])
# TODO: create the ImageFolder
dataset = datasets.ImageFolder(data_dir, transform=transform)
# TODO: use the ImageFolder dataset to create the DataLoader
dataloader = torch.utils.data.DataLoader(dataset, batch_size=32, shuffle=True)
# Run this to test your data loader
images, labels = next(iter(dataloader))
print(labels[0])
tensor(0)
helper.imshow(images[0], normalize=False)
<matplotlib.axes._subplots.AxesSubplot at 0x7f983cc2c860>

在这里插入图片描述

如果数据加载正确,你应该看到类似如下所示的结果:

在这里插入图片描述

数据增强

训练神经网络的一个常见策略是在输入数据本身里引入随机性。例如,你可以在训练过程中随机地旋转、翻转、缩放和/或裁剪图像。这样一来,你的神经网络在处理位置、大小、方向不同的相同图像时,可以更好地进行泛化。

要随机旋转、缩放、裁剪图像,然后翻转图像,你需要如下所示地定义转换:

train_transforms = transforms.Compose([transforms.RandomRotation(30),
                                       transforms.RandomResizedCrop(224),
                                       transforms.RandomHorizontalFlip(),
                                       transforms.ToTensor(),
                                       transforms.Normalize([0.5, 0.5, 0.5], 
                                                            [0.5, 0.5, 0.5])])

另外,还需要使用 transforms.Normalize 标准化图像。传入均值和标准偏差列表,然后标准化颜色通道

减去 mean 使数据以 0 居中,除以 std 使值位于 -1 到 1 之间。准化有助于神经网络使权重接近 0,这能使反向传播更为稳定。不标准化的话,网络往往会学习失败。

你可以在此处查看可用的转换列表。测试时,不能改变图像(但是需要以同一方式标准化)。因此,在验证/测试图像时,通常只能调整大小和裁剪图像。

**练习:**请为下面的训练数据和测试数据定义转换。

data_dir = 'Cat_Dog_data'

# TODO: Define transforms for the training data and testing data
train_transforms = transforms.Compose([transforms.RandomRotation(30),
                                       transforms.RandomResizedCrop(224),
                                       transforms.RandomHorizontalFlip(),
                                       transforms.ToTensor()]) 

test_transforms = transforms.Compose([transforms.Resize(255),
                                      transforms.CenterCrop(224),
                                      transforms.ToTensor()])


# Pass transforms in here, then run the next cell to see how the transforms look
train_data = datasets.ImageFolder(data_dir + '/train', transform=train_transforms)
test_data = datasets.ImageFolder(data_dir + '/test', transform=test_transforms)

trainloader = torch.utils.data.DataLoader(train_data, batch_size=32)
testloader = torch.utils.data.DataLoader(test_data, batch_size=32)
# change this to the trainloader or testloader 
data_iter = iter(testloader)
images, labels = next(data_iter)
fig, axes = plt.subplots(figsize=(10,4), ncols=4)
for ii in range(4):
    ax = axes[ii]
    helper.imshow(images[ii], ax=ax, normalize=False)

在这里插入图片描述

转换后的图像应该如下所示。

在这里插入图片描述

测试示例:

在这里插入图片描述

好了,我们学习了加载训练和测试数据。现在,试试构建网络来分类猫和狗。这个题目其实挺难的,但不用担心,先试试!不过,说实话,使用完全连接的网络很有可能不可行。这些图像有三个颜色通道,而且分辨率更高(而我们之前试过的只是分辨率很小的 28x28 图像)。

在下个部分,我将演示如何使用预训练网络构建能实际解决该问题的模型。

# Optional TODO: Attempt to build a network to classify cats vs dogs from this dataset
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值