制作数据集是机器学习和深度学习任务中的关键步骤之一,它涉及收集、整理和准备数据,以便用于模型的训练、验证和测试。
2.3.1 自定义数据集
在PyTorch中可以通过创建自定义类Dataset的方式来制作数据集,自定义的数据集类需要继承torch.utils.data.Dataset,并实现__len__()和__getitem__()方法。例如下面是一个在PyTorch中自定义数据集并使用的例子。
实例2-11:制作自己的数据集并使用(源码路径:daima\2\zi.py)
实例文件zi.py的具体实现代码如下所示。
import torch
from torch.utils.data import Dataset, DataLoader
class CustomDataset(Dataset):
def __init__(self, data, targets):
self.data = data
self.targets = targets
def __len__(self):
return len(self.data)
def __getitem__(self, index):
x = self.data[index]
y = self.targets[index]
return x, y
# 创建数据集
data = torch.randn(100, 3, 32, 32) # 假设有100个3通道的32x32图像
targets = torch.randint(0, 10, (100,)) # 假设有100个目标类别(0到9之间)
dataset = CustomDataset(data, targets)
# 创建数据加载器
batch_size = 10
dataloader = DataLoader(dataset, batch_size=batch_size, shuffle=True)
# 遍历数据加载器
for batch_data, batch_targets in dataloader:
# 在这里对每个小批量的数据进行操作
print("Batch data size:", batch_data.size())
print("Batch targets:", batch_targets)
在上述代码中,首先定义了一个CustomDataset类来创建自定义数据集。然后,我们使用随机生成的数据和目标类别创建了一个实例。接下来,使用类DataLoader来创建数据加载器。通过指定批次大小和是否进行洗牌等参数,我们可以对数据集进行批次处理。最后,使用for循环遍历数据加载器,每次迭代获得一个小批量的数据和对应的目标类别。在这个例子中,我们只是简单地打印出每个小批量的数据大小和目标类别。执行后会输出:
Batch data size: torch.Size([10, 3, 32, 32])
Batch targets: tensor([8, 0, 0, 4, 1, 0, 8, 2, 2, 3])
Batch data size: torch.Size([10, 3, 32, 32])
Batch targets: tensor([4, 5, 2, 0, 9, 2, 1, 8, 8, 3])
Batch data size: torch.Size([10, 3, 32, 32])
Batch targets: tensor([0, 8, 4, 0, 0, 4, 8, 3, 7, 2])
Batch data size: torch.Size([10, 3, 32, 32])
Batch targets: tensor([2, 1, 4, 1, 0, 4, 5, 3, 5, 6])
Batch data size: torch.Size([10, 3, 32, 32])
Batch targets: tensor([7, 0, 7, 9, 1, 3, 9, 7, 5, 3])
Batch data size: torch.Size([10, 3, 32, 32])
Batch targets: tensor([6, 7, 6, 3, 9, 9, 0, 8, 0, 3])
Batch data size: torch.Size([10, 3, 32, 32])
Batch targets: tensor([4, 3, 6, 3, 6, 1, 8, 2, 2, 5])
Batch data size: torch.Size([10, 3, 32, 32])
Batch targets: tensor([1, 0, 0, 6, 3, 3, 3, 7, 0, 8])
Batch data size: torch.Size([10, 3, 32, 32])
Batch targets: tensor([6, 2, 7, 9, 5, 7, 9, 2, 7, 8])
Batch data size: torch.Size([10, 3, 32, 32])
Batch targets: tensor([1, 9, 6, 1, 3, 7, 3, 3, 2, 5])
从Tensorflow 2.0开始,提供了专门用于实现数据输入的接口tf.data.Dataset,能够以快速且可扩展的方式加载和预处理数据,帮助开发者高效的实现数据的读入、打乱(shuffle)、增强(augment)等功能。请看下面的实例,演示了使用tf.data创建数据集并进行训练和评估的过程。
实例2-12:使用tf.data创建数据集并进行训练和评估(源码路径:daima\2\xun01.py)
实例文件xun01.py的具体实现代码如下所示。
# 首先,让我们创建一个训练数据集实例
train_dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train))
# 洗牌并切片数据集.
train_dataset = train_dataset.shuffle(buffer_size=1024).batch(64)
# 现在我们得到了一个测试数据集.
test_dataset = tf.data.Dataset.from_tensor_slices((x_test, y_test))
test_dataset = test_dataset.batch(64)
#由于数据集已经处理批处理,所以我们不传递“batch\u size”参数。
model.fit(train_dataset, epochs=3)
#还可以对数据集进行评估或预测.
print("Evaluate评估:")
result = model.evaluate(test_dataset)
dict(zip(model.metrics_names, result))
在上述代码中,使用dataset的内置函数shuffle()将数据打乱,此函数的参数值越大,混乱程度就越大。另外,还可以使用dataset的其它内置函数操作数据:
- batch(4):按照顺序取出4行数据,最后一次输出可能小于batch;
- repeat():设置数据集重复执行指定的次数,在batch操作输出完毕后再执行。如果在之前,相当于先把整个数据集复制两次。为了配合输出次数,一般repeat()的参数默认为空。
在作者电脑中执行后会输出:
Epoch 1/3
782/782 [==============================] - 2s 2ms/step - loss: 0.3395 - sparse_categorical_accuracy: 0.9036
Epoch 2/3
782/782 [==============================] - 2s 2ms/step - loss: 0.1614 - sparse_categorical_accuracy: 0.9527
Epoch 3/3
782/782 [==============================] - 2s 2ms/step - loss: 0.1190 - sparse_categorical_accuracy: 0.9648
Evaluate评估:
157/157 [==============================] - 0s 2ms/step - loss: 0.1278 - sparse_categorical_accuracy: 0.9633
{'loss': 0.12783484160900116,
'sparse_categorical_accuracy': 0.9632999897003174}
上述这段输出结果是一个 TensorFlow 模型训练和评估的结果,接下来将详细讲解每个输出部分的含义:
- Epoch 1/3:这部分显示了模型训练的 epoch 数量,以及总共的训练步数。每个 epoch 都会将训练数据分成多个小批次进行训练。
- loss: 0.3395 - sparse_categorical_accuracy: 0.9036:这部分显示了每个 epoch 结束后的训练结果。其中 "loss" 表示模型的损失值,"sparse_categorical_accuracy" 表示模型的稀疏分类准确率。例如,在第一个 epoch 结束时,模型的损失为 0.3395,稀疏分类准确率为 0.9036。
- Evaluate 评估:这部分显示了模型在验证集(或测试集)上的评估结果。例如,在评估过程中,模型的损失为 0.1278,稀疏分类准确率为 0.9633。
- {'loss': 0.12783484160900116, 'sparse_categorical_accuracy': 0.9632999897003174}:这部分显示了一个字典,其中包含了评估结果的具体数值。您可以通过这些数值进一步分析模型的性能。
综合起来,上述这段输出表示您的 TensorFlow 模型经过三个 epoch 的训练,在训练集上的损失逐渐减小,稀疏分类准确率逐渐增加。在验证集上的评估结果也表现出较好的性能,损失较低,准确率较高。这是一个很好的迹象,说明您的模型在这个任务上取得了不错的结果。
2.3.2 制作简易图片数据集
假设在当前程序的“data1”目录中保存了一些图片,请看下面的实例,演示了使用PyTorch将“data1”目录中的图片制作成数据集的过程。
实例2-12:使用PyTorch将指定图片制作成数据集(源码路径:daima\2\image.py)
实例文件image.py的具体实现代码如下所示。
import os
from PIL import Image
import torch
from torch.utils.data import Dataset
from torchvision.transforms import ToTensor
class ImageDataset(Dataset):
def __init__(self, root_dir):
self.root_dir = root_dir
self.image_paths = os.listdir(root_dir)
self.transform = ToTensor()
def __len__(self):
return len(self.image_paths)
def __getitem__(self, index):
image_path = os.path.join(self.root_dir, self.image_paths[index])
image = Image.open(image_path)
image = self.transform(image)
return image
# 图片所在的目录
data_dir = "data1"
# 创建数据集实例
dataset = ImageDataset(data_dir)
# 访问数据集
image = dataset[0] # 获取第一张图片
print("Image shape:", image.shape)
在上述代码中定义了一个ImageDataset类来创建自定义的图像数据集。在__init__方法中,我们传入图片所在的目录root_dir,并获取该目录下的所有图片文件名。方法__len__()返回数据集的长度,即照片的数量。方法__getitem__()用于获取数据集中的样本。在这个例子中,我们根据索引获取对应的图片路径,并打开并转换为张量格式。执行后会输出:
Image shape: torch.Size([3, 400, 300])
通过创建数据集实例,可以像访问列表一样获取数据集中的样本。例如在上面的例子中,dataset[0]表示获取第一张图片的张量表示。
请看下面的实例,演示了使用TensorFlow将“data1”目录中的图片制作成数据集的过程。
实例2-12:使用TensorFlow将指图片制作成数据集(源码路径:daima\2\timage.py)
实例文件timage.py的具体实现代码如下所示。
import tensorflow as tf
import os
from tensorflow.keras.preprocessing.image import load_img, img_to_array
# 数据集文件夹路径
data_dir = "data1" # 替换为你的数据集文件夹路径
# 获取所有图片文件的路径
image_paths = [os.path.join(data_dir, filename) for filename in os.listdir(data_dir) if filename.endswith(".jpg")]
# 加载图片并转换为张量
images = [img_to_array(load_img(img_path)) for img_path in image_paths]
# 创建标签(示例中假设所有图片属于同一类别,你可以根据实际情况修改)
labels = [0] * len(images)
# 创建 TensorFlow 数据集对象
image_dataset = tf.data.Dataset.from_tensor_slices((images, labels))
# 打印数据集信息
print("图片数量:", len(images))
# 遍历数据集并显示一个批次的图像
for image, label in image_dataset.take(1):
print("图像形状:", image.shape)
print("标签:", label)
在上述代码中,首先获取了所有图片文件的路径,然后使用 TensorFlow 的图片处理工具将图片加载并转换为张量。接着,创建了一个标签列表,每个图片对应一个标签。最后,使用 tf.data.Dataset.from_tensor_slices 函数将图片和标签制作成 TensorFlow 数据集对象。执行后会输出:
图片数量: 3
图像形状: (400, 300, 3)
标签: tf.Tensor(0, shape=(), dtype=int32)
注意:上述实例中的标签 0 只是一个示例。在实际情况中,你可能需要根据图片的内容设置正确的标签。另外,上述代码并没有将制作的数据集文件保存到硬盘上,而是在内存中创建了一个 TensorFlow 数据集对象,这个数据集对象包含了图像数据和对应的标签。
2.3.3 制作有标签的数据集
接下来继续用“data1”目录中的图片制作出有标签的数据集,在制作数据集时,通常需要将每个样本与其对应的标签关联起来。对于图像分类任务,可以通过在数据集中包含图像及其对应的标签来实现。例如下面是一个在PyTorch中制作带有标签的数据集的例子。
实例2-13:使用PyTorch制作带有标签的数据集(源码路径:daima\2\biaoqian.py)
实例文件biaoqian.py的具体实现代码如下所示。
import os
from PIL import Image
import torch
from torch.utils.data import Dataset
from torchvision.transforms import ToTensor
class ImageDataset(Dataset):
def __init__(self, root_dir, transform=None):
self.root_dir = root_dir
self.image_paths = os.listdir(root_dir)
self.transform = transform
def __len__(self):
return len(self.image_paths)
def __getitem__(self, index):
image_path = os.path.join(self.root_dir, self.image_paths[index])
image = Image.open(image_path)
if self.transform:
image = self.transform(image)
label = self.get_label(image_path)
return image, label
def get_label(self, image_path):
# 在这里根据图片路径获取对应的标签
# 这里仅作示例,假设图片文件名中包含标签信息
label = image_path.split("_")[0] # 假设图片文件名为"label_image.jpg"
return label
# 图片所在的目录
data_dir = "data1"
# 创建数据集实例
transform = ToTensor() # 可以根据需要添加其他的数据预处理操作
dataset = ImageDataset(data_dir, transform=transform)
# 访问数据集
image, label = dataset[0] # 获取第一张图片及其对应的标签
print("Image shape:", image.shape)
print("Label:", label)
在上述代码的类ImageDataset中添加了get_label方法来根据图片路径获取对应的标签,这里仅作示例,假设图片文件名中包含了标签信息,我们通过简单的字符串操作来提取标签。在方法__getitem__()中,除了返回图片的张量表示,还返回了对应的标签。执行后会输出:
Image shape: torch.Size([3, 400, 300])
Label: data1\100.jpg
通过创建带有标签的数据集实例,我们可以像之前一样访问数据集,但现在每个样本都包含了图片及其对应的标签。例如在上面的例子中,dataset[0]返回了第一张图片的张量表示及其对应的标签。
在“data3”目录中有两个子目录:“lou”和“car”,里面分别保存了楼的照片和汽车照片。如果想要使用 TensorFlow 将它们制作成带有标签的数据集,可以使用 tf.keras.preprocessing.image_dataset_from_directory 函数。下面是是一个示例代码,展示了将这两个子目录制作成带有标签的数据集的过程。
实例2-13:使用PyTorch制作带有标签的数据集(源码路径:daima\2\tbiaoqian.py)
实例文件tbiaoqian.py的具体实现代码如下所示。
import tensorflow as tf
# 数据集文件夹路径
data_dir = "data3" # 替换为你的数据集文件夹路径
# 创建数据集
batch_size = 32
image_size = (128, 128) # 图像大小
# 使用 tf.keras.preprocessing.image_dataset_from_directory 创建数据集
train_dataset = tf.keras.preprocessing.image_dataset_from_directory(
data_dir,
batch_size=batch_size,
image_size=image_size,
validation_split=0.2, # 划分训练集和验证集
subset="training",
seed=1337, # 随机种子,保持可重现性
labels="inferred", # 自动从文件夹结构推断标签
label_mode="int", # 标签的数据类型,"int" 表示整数标签
class_names=["lou", "car"]
)
validation_dataset = tf.keras.preprocessing.image_dataset_from_directory(
data_dir,
batch_size=batch_size,
image_size=image_size,
validation_split=0.2,
subset="validation",
seed=1337,
labels="inferred",
label_mode="int",
class_names=["lou", "car"]
)
# 打印数据集信息
print("训练集样本数:", train_dataset.cardinality().numpy())
print("验证集样本数:", validation_dataset.cardinality().numpy())
# 遍历数据集并显示一个批次的图像和标签
for images, labels in train_dataset.take(1):
for i in range(len(images)):
print("图像形状:", images[i].shape)
print("标签:", labels[i])
上述代码使用 tf.keras.preprocessing.image_dataset_from_directory 函数创建带有标签的数据集。它加载指定文件夹中的图像,并根据文件夹结构和参数设置创建数据集。然后,它打印出数据集的信息,包括训练集和验证集的样本数,以及一个批次的图像形状和标签。执行后回输出:
Found 6 files belonging to 2 classes.
Using 4 files for training.
Found 6 files belonging to 2 classes.
Using 2 files for validation.
训练集样本数: 1
验证集样本数: 1
图像形状: (32, 128, 128, 3)
标签: 1
图像形状: (32, 128, 128, 3)
标签: 0
源码和数据下载:https://download.csdn.net/download/asd343442/88731434