如果你是AI零基础,请关注本专栏,将带你一起飞。
2.2.3 调整大小和裁剪
1. 调整大小(Resize)
在PyTorch中,可以使用transforms模块中的Resize类来调整数据集的大小,可以指定调整后的目标大小,也可以指定调整方式(如保持纵横比或填充)。例如下面是一个调整数据集大小的例子。
实例2-5:调整数据集大小(源码路径:daima\2\daxiao.py)
实例文件daxiao.py的具体实现代码如下所示。
import torchvision.transforms as transforms
from torchvision.datasets import CIFAR10
# 定义转换操作列表,包括Resize
transform = transforms.Compose([
transforms.Resize((224, 224)),
transforms.ToTensor(),
])
# 创建CIFAR-10数据集实例并应用转换操作
dataset = CIFAR10(root='data/', train=True, download=True, transform=transform)
# 获取第一个样本
sample = dataset[0]
# 打印调整大小后的图像张量
print('调整大小后的图像张量:', sample[0])
在上述代码中定义了一个名为transform的转换操作列表,其中包括了Resize操作。通过指定目标大小为(224, 224),将CIFAR-10数据集中的图像调整为224x224大小。然后,创建CIFAR-10数据集实例时应用了这个转换操作。最后,通过打印输出第一个样本的图像张量,可以观察到已经完成了大小调整。执行后会输出:
调整大小后的图像张量: tensor([[[0.2314, 0.2314, 0.2314, ..., 0.5804, 0.5804, 0.5804],
[0.2314, 0.2314, 0.2314, ..., 0.5804, 0.5804, 0.5804],
[0.2314, 0.2314, 0.2314, ..., 0.5804, 0.5804, 0.5804],
...,
[0.6941, 0.6941, 0.6941, ..., 0.4824, 0.4824, 0.4824],
[0.6941, 0.6941, 0.6941, ..., 0.4824, 0.4824, 0.4824],
[0.6941, 0.6941, 0.6941, ..., 0.4824, 0.4824, 0.4824]],
[[0.2431, 0.2431, 0.2431, ..., 0.4863, 0.4863, 0.4863],
[0.2431, 0.2431, 0.2431, ..., 0.4863, 0.4863, 0.4863],
[0.2431, 0.2431, 0.2431, ..., 0.4863, 0.4863, 0.4863],
...,
[0.5647, 0.5647, 0.5647, ..., 0.3608, 0.3608, 0.3608],
[0.5647, 0.5647, 0.5647, ..., 0.3608, 0.3608, 0.3608],
[0.5647, 0.5647, 0.5647, ..., 0.3608, 0.3608, 0.3608]],
[[0.2471, 0.2471, 0.2471, ..., 0.4039, 0.4039, 0.4039],
[0.2471, 0.2471, 0.2471, ..., 0.4039, 0.4039, 0.4039],
[0.2471, 0.2471, 0.2471, ..., 0.4039, 0.4039, 0.4039],
...,
[0.4549, 0.4549, 0.4549, ..., 0.2824, 0.2824, 0.2824],
[0.4549, 0.4549, 0.4549, ..., 0.2824, 0.2824, 0.2824],
[0.4549, 0.4549, 0.4549, ..., 0.2824, 0.2824, 0.2824]]])
在 TensorFlow 中,调整数据集的大小通常指的是调整数据集中图像的大小,以便它们适应特定的模型输入大小。这在处理图像数据时很常见,因为不同的模型可能需要不同大小的输入图像。例如下面是一个使用TensorFlow调整数据集中图像大小的例子。
实例2-5:调整数据集大小(源码路径:daima\2\tdaxiao.py)
(1)准备数据集文件:假设“path/to/your/dataset”目录是一个存放数据集文件夹的路径,在这个路径下放置了我们的图像数据,按照不同类别分别存放在子文件夹中,具体内容如下:
path/to/your/dataset/
├── class1/
│ ├── image1.jpg
│ ├── image2.jpg
│ └── ...
├── class2/
│ ├── image1.jpg
│ ├── image2.jpg
│ └── ...
├── class3/
│ ├── image1.jpg
│ ├── image2.jpg
│ └── ...
└── ...
在数据集文件夹“path/to/your/dataset”中,class1、class2、class3 是不同的类别名称,每个类别文件夹中包含属于该类别的图像文件(例如 image1.jpg、image2.jpg 等)。每个图像文件应该位于对应类别的子文件夹中。在运行本实例时,需要将 “path/to/your/dataset”替换为实际数据集文件夹的路径,并确保数据集文件夹按照类别组织,并且包含真实的图像文件。
(2)实例文件tdaxiao.py的具体实现代码如下所示。
import tensorflow as tf
import os
# 设置图像目标大小
target_image_size = (128, 128)
# 定义数据集文件夹路径和批次大小
data_dir = "path/to/your/dataset" # 替换为你的数据集文件夹路径
batch_size = 32
# 创建数据集
image_dataset = tf.keras.preprocessing.image_dataset_from_directory(
data_dir,
image_size=target_image_size,
batch_size=batch_size,
shuffle=True
)
# 数据预处理函数:调整大小和标准化
def preprocess_image(image, label):
image = tf.image.resize(image, target_image_size)
image = image / 255.0 # 标准化处理
return image, label
# 应用预处理函数到数据集
processed_dataset = image_dataset.map(preprocess_image)
# 打印数据集信息
print("类别数:", len(image_dataset.class_names))
print("训练集样本数:", image_dataset.cardinality().numpy())
# 遍历数据集并显示一个批次的图像
for images, labels in processed_dataset.take(1):
for i in range(batch_size):
print("图像形状:", images[i].shape)
print("标签:", image_dataset.class_names[labels[i]])
在上述代码中,首先使用 tf.keras.preprocessing.image_dataset_from_directory 函数加载图像数据集,将图像调整为目标大小并指定批次大小。然后,定义了一个名为 preprocess_image 的数据预处理函数,该函数对图像进行了大小调整和标准化处理。接着,使用 map 函数将预处理函数应用到数据集中的每个图像。最后,打印输出了一些数据集的基本信息,并遍历了一个批次的图像以显示它们的形状和标签。执行后会输出:
import torchvision.transforms as transforms
from torchvision.datasets import CIFAR10
# 定义转换操作列表,包括RandomCrop
transform = transforms.Compose([
transforms.RandomCrop((32, 32)),
transforms.ToTensor(),
])
# 创建CIFAR-10数据集实例并应用转换操作
dataset = CIFAR10(root='data/', train=True, download=True, transform=transform)
# 获取第一个样本
sample = dataset[0]
# 打印裁剪后的图像张量
print('裁剪后的图像张量:', sample[0])
在上面的输出中, xxx 是我们数据集中的图像文件总数,yyy 将是数据集中的类别数目。接下来的部分会显示每个图像的形状(128x128 的 RGB 图像)和对应的类别标签(class_name 会被实际的类别名替代)。
2. 裁剪(RandomCrop)
在PyTorch中,可以使用类RandomCrop对数据集中的图像进行随机裁剪,从而增加数据的多样性。我们可以指定裁剪后的目标大小,也可以指定裁剪方式(如随机裁剪或中心裁剪)。例如下面是一个裁剪数据集的例子。
实例2-6:使用PyTorch裁剪数据集(源码路径:daima\2\cai.py)
实例文件cai.py的具体实现代码如下所示。
import torchvision.transforms as transforms
from torchvision.datasets import CIFAR10
# 定义转换操作列表,包括RandomCrop
transform = transforms.Compose([
transforms.RandomCrop((32, 32)),
transforms.ToTensor(),
])
# 创建CIFAR-10数据集实例并应用转换操作
dataset = CIFAR10(root='data/', train=True, download=True, transform=transform)
# 获取第一个样本
sample = dataset[0]
# 打印裁剪后的图像张量
print('裁剪后的图像张量:', sample[0])
在上述代码中定义了一个名为transform的转换操作列表,其中包括了RandomCrop操作。通过指定裁剪后的目标大小为(32, 32),将CIFAR-10数据集中的图像进行随机裁剪,裁剪后的图像大小为32x32。然后,创建CIFAR-10数据集实例时应用了这个转换操作。最后,通过打印输出第一个样本的图像张量,可以观察到已经完成了随机裁剪。执行后会输出:
裁剪后的图像张量: tensor([[[0.2314, 0.1686, 0.1961, ..., 0.6196, 0.5961, 0.5804],
[0.0627, 0.0000, 0.0706, ..., 0.4824, 0.4667, 0.4784],
[0.0980, 0.0627, 0.1922, ..., 0.4627, 0.4706, 0.4275],
...,
[0.8157, 0.7882, 0.7765, ..., 0.6275, 0.2196, 0.2078],
[0.7059, 0.6784, 0.7294, ..., 0.7216, 0.3804, 0.3255],
[0.6941, 0.6588, 0.7020, ..., 0.8471, 0.5922, 0.4824]],
[[0.2431, 0.1804, 0.1882, ..., 0.5176, 0.4902, 0.4863],
[0.0784, 0.0000, 0.0314, ..., 0.3451, 0.3255, 0.3412],
[0.0941, 0.0275, 0.1059, ..., 0.3294, 0.3294, 0.2863],
...,
[0.6667, 0.6000, 0.6314, ..., 0.5216, 0.1216, 0.1333],
[0.5451, 0.4824, 0.5647, ..., 0.5804, 0.2431, 0.2078],
[0.5647, 0.5059, 0.5569, ..., 0.7216, 0.4627, 0.3608]],
[[0.2471, 0.1765, 0.1686, ..., 0.4235, 0.4000, 0.4039],
[0.0784, 0.0000, 0.0000, ..., 0.2157, 0.1961, 0.2235],
[0.0824, 0.0000, 0.0314, ..., 0.1961, 0.1961, 0.1647],
...,
[0.3765, 0.1333, 0.1020, ..., 0.2745, 0.0275, 0.0784],
[0.3765, 0.1647, 0.1176, ..., 0.3686, 0.1333, 0.1333],
[0.4549, 0.3686, 0.3412, ..., 0.5490, 0.3294, 0.2824]]])
注意:通过使用Resize和RandomCrop类,可以调整数据集中图像的大小和进行裁剪,以便适应模型的需求和增加数据的多样性。根据具体的任务和数据集特点,可以选择合适的调整大小和裁剪操作。
在 TensorFlow 中,对数据集中的图像进行裁剪通常是为了提取感兴趣的区域,以便用于模型的训练或预测。下面是一个例子,展示了在 TensorFlow 中对图像数据集进行裁剪的过程。假设我们要使用随机生成的图像数据进行裁剪,并且我们要展示的图像数据格式是 (batch_size, height, width, channels)。
实例2-6:使用TensorFlow裁剪数据集(源码路径:daima\2\tcai.py)
实例文件tcai.py的具体实现代码如下所示。
import tensorflow as tf
import numpy as np
# 创建随机图像数据
num_samples = 100
image_height = 128
image_width = 128
num_channels = 3
random_images = np.random.randint(0, 256, size=(num_samples, image_height, image_width, num_channels), dtype=np.uint8)
# 随机生成标签
random_labels = np.random.randint(0, 10, size=num_samples)
# 创建 TensorFlow 数据集对象
image_dataset = tf.data.Dataset.from_tensor_slices((random_images, random_labels))
# 数据预处理函数:裁剪图像
def crop_image(image, label):
cropped_image = tf.image.random_crop(image, size=[crop_height, crop_width, num_channels])
return cropped_image, label
# 定义裁剪的目标区域
crop_height = 50
crop_width = 50
# 应用裁剪函数到数据集
cropped_dataset = image_dataset.map(crop_image)
# 打印数据集信息
print("训练集样本数:", num_samples)
# 遍历数据集并显示一个批次的图像
for images, labels in cropped_dataset.take(1):
for i in range(len(images)):
print("裁剪后的图像形状:", images[i].shape)
print("标签:", labels[i])
在上述代码中,首先创建了随机的图像数据和标签。然后,使用 tf.data.Dataset.from_tensor_slices 函数将数据转换为 TensorFlow 数据集对象。接着,定义了一个名为 crop_image 的数据预处理函数,该函数使用 tf.image.random_crop 函数来随机裁剪图像。最后,使用裁剪函数到数据集,并遍历数据集以显示裁剪后的图像形状和对应的标签。执行后会输出:
训练集样本数: 100
裁剪后的图像形状: (50, 3)
2.2.4 随机翻转和旋转
(1)随机翻转(RandomHorizontalFlip)
在PyTorch程序中,可以使用类RandomHorizontalFlip对数据集中的图像进行随机水平翻转,以增加数据的多样性。例如下面是一个对数据集实现随机翻转的例子。
实例2-7:对数据集实现随机翻转(源码路径:daima\2\fan.py)
实例文件fan.py的具体实现代码如下所示。
import torchvision.transforms as transforms
from torchvision.datasets import CIFAR10
# 定义转换操作列表,包括RandomHorizontalFlip
transform = transforms.Compose([
transforms.RandomHorizontalFlip(p=0.5),
transforms.ToTensor(),
])
# 创建CIFAR-10数据集实例并应用转换操作
dataset = CIFAR10(root='data/', train=True, download=True, transform=transform)
# 获取第一个样本
sample = dataset[0]
# 打印翻转后的图像张量
print('翻转后的图像张量:', sample[0])
在上述代码中定义了一个名为transform的转换操作列表,其中包括了RandomHorizontalFlip操作。通过指定概率p为0.5,每个样本有50%的几率进行水平翻转。然后,创建CIFAR-10数据集实例时应用了这个转换操作。最后,通过打印输出第一个样本的图像张量,可以观察到已经完成了随机水平翻转。执行后会输出:
翻转后的图像张量: tensor([[[0.5804, 0.5961, 0.6196, ..., 0.1961, 0.1686, 0.2314],
[0.4784, 0.4667, 0.4824, ..., 0.0706, 0.0000, 0.0627],
[0.4275, 0.4706, 0.4627, ..., 0.1922, 0.0627, 0.0980],
...,
[0.2078, 0.2196, 0.6275, ..., 0.7765, 0.7882, 0.8157],
[0.3255, 0.3804, 0.7216, ..., 0.7294, 0.6784, 0.7059],
[0.4824, 0.5922, 0.8471, ..., 0.7020, 0.6588, 0.6941]],
[[0.4863, 0.4902, 0.5176, ..., 0.1882, 0.1804, 0.2431],
[0.3412, 0.3255, 0.3451, ..., 0.0314, 0.0000, 0.0784],
[0.2863, 0.3294, 0.3294, ..., 0.1059, 0.0275, 0.0941],
...,
[0.1333, 0.1216, 0.5216, ..., 0.6314, 0.6000, 0.6667],
[0.2078, 0.2431, 0.5804, ..., 0.5647, 0.4824, 0.5451],
[0.3608, 0.4627, 0.7216, ..., 0.5569, 0.5059, 0.5647]],
[[0.4039, 0.4000, 0.4235, ..., 0.1686, 0.1765, 0.2471],
[0.2235, 0.1961, 0.2157, ..., 0.0000, 0.0000, 0.0784],
[0.1647, 0.1961, 0.1961, ..., 0.0314, 0.0000, 0.0824],
...,
[0.0784, 0.0275, 0.2745, ..., 0.1020, 0.1333, 0.3765],
[0.1333, 0.1333, 0.3686, ..., 0.1176, 0.1647, 0.3765],
[0.2824, 0.3294, 0.5490, ..., 0.3412, 0.3686, 0.4549]]])
(2)随机旋转(RandomRotation)
在PyTorch程序中,可以使用类RandomRotation对数据集中的图像进行随机旋转,以增加数据的多样性。例如下面是一个对数据集中的图像进行随机旋转的例子。
实例2-8:对数据集中的图像进行随机旋转(源码路径:daima\2\xuan.py)
实例文件xuan.py的具体实现代码如下所示。
import torchvision.transforms as transforms
from torchvision.datasets import CIFAR10
# 定义转换操作列表,包括RandomRotation
transform = transforms.Compose([
transforms.RandomRotation(degrees=30),
transforms.ToTensor(),
])
# 创建CIFAR-10数据集实例并应用转换操作
dataset = CIFAR10(root='data/', train=True, download=True, transform=transform)
# 获取第一个样本
sample = dataset[0]
# 打印旋转后的图像张量
print('旋转后的图像张量:', sample[0])
在上述代码中定义了一个名为transform的转换操作列表,其中包括了RandomRotation操作。通过指定旋转的角度为30度,每个样本在-30度到+30度之间随机选择旋转角度。然后,创建CIFAR-10数据集实例时应用了这个转换操作。最后,通过打印输出第一个样本的图像张量,可以观察到已经完成了随机旋转。执行后会输出:
旋转后的图像张量: tensor([[[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
...,
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.]],
[[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
...,
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.]],
[[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
...,
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.]]])
通过使用类RandomHorizontalFlip和类RandomRotation,可以在数据集加载和预处理过程中实现随机翻转和旋转,从而增加数据的多样性。根据具体的任务和数据集特点,可以选择合适的翻转和旋转操作。