1.作用是将数据处理成模型能看懂的语言,比如图像中将png,jpeg等格式的文件转换成numpy array的格式。并进行缩放,旋转,亮度变化等各种预处理
paddle数据预处理的特点:对数据管道相关的场景进行了高级封装,通过非常少量代码,即可实现数据的处理
2.数据管道的组成:框架内置数据集,自定义数据集,数据增强,数据采样,数据加载。共五个部分。其中框架内置数据集和自定义数据集为数据的主要来源。学习时可以使用框架内置数据集,使用方便。工作时一般都是自定义数据集了
内置数据集查看命令
print('视觉相关数据集:', paddle.vision.datasets.__all__)
print('自然语言相关数据集:', paddle.text.datasets.__all__)
运行结果:
视觉相关数据集: [‘DatasetFolder’, ‘ImageFolder’, ‘MNIST’, ‘FashionMNIST’, ‘Flowers’, ‘Cifar10’, ‘Cifar100’, ‘VOC2012’]
自然语言相关数据集: [‘Conll05st’, ‘Imdb’, ‘Imikolov’, ‘Movielens’, ‘UCIHousing’, ‘WMT14’, ‘WMT16’]
可以看到一般常用的数据集都在里面了
调用方法:
train_data=paddle.vision.datasets.模型名称(mode='train')
test_data=paddle.vision.datasets.模型名(mode='test')
当然,使用前别忘了import paddle
查看数据内容:
查看数据在notebook里一般使用matplotlib.pyplot模块,别名plt
train_data_0, train_label_0 = np.array(train_dataset[0][0]), train_dataset[0][1]
train_data_0 = train_data_0.reshape([28, 28])
plt.figure(figsize=(2, 2))
plt.imshow(train_data_0, cmap=plt.cm.binary)
print('train_data0 label is: ' + str(train_label_0))
train_dataset 是一个 map-style 式的数据集,我们可以通过下标直接获取单个样本的图像数据与标签,从而进行可视化。
map-style 是指可以通过下标的方式来获取指定样本,除此之外,还有 iterable-style 式的数据集,只能通过迭代的方式来获取样本
自定义使用map-style 的 paddle.io.Dataset 基类 和 iterable-style 的 paddle.io.IterableDataset 基类 ,来完成数据集定义。此外,针对一些特殊的场景,飞桨框架也提供了 paddle.io.TensorDataset 基类,可以直接处理 Tensor 数据为 dataset,一键完成数据集的定义。
paddle.io.Dataset的使用方式:
是最推荐使用的API,来完成数据的定义。使用 paddle.io.Dataset,最后会返回一个 map-style 的 Dataset 类。可以用于后续的数据增强、数据加载等。而使用 paddle.io.Dataset 也非常简单,只需要按格式完成以下四步即可:
class MyDataset(paddle.io.Dataset):
"""
步骤一:继承paddle.io.Dataset类
"""
def __init__(self, mode='train'):
"""
步骤二:实现构造函数,定义数据读取方式,划分训练和测试数据集
"""
super(MyDataset, self).__init__()
if mode == 'train':
self.data = [
['train_image_0.jpg', '1'],
['train_image_1.jpg', '2'],
['train_image_2.jpg', '3'],
['train_image_3.jpg', '4'],
]
else:
self.data = [
['test_image_0.jpg', '1'],
['test_image_1.jpg', '2'],
['test_image_2.jpg', '3'],
['test_image_3.jpg', '4'],
]
def _load_img(self, image_path):
# 实际使用时使用Pillow相关库进行图片读取即可,这里我们对数据先做个模拟
image = np.random.randn(32, 32, 3)
return image
def __getitem__(self, index):
"""
步骤三:实现__getitem__方法,定义指定index时如何获取数据,并返回单条数据(训练数据,对应的标签)
"""
image = self._load_img(self.data[index][0])
label = self.data[index][1]
return image, np.array(label, dtype='int64')
def __len__(self):
"""
步骤四:实现__len__方法,返回数据集总数目
"""
return len(self.data)
# 测试定义的数据集
train_dataset = MyDataset(mode='train')
test_dataset = MyDataset(mode='test')
print('=============train dataset=============')
for image, label in train_dataset:
print('image shape: {}, label: {}'.format(image.shape, label))
print('=============evaluation dataset=============')
for image, label in test_dataset:
print('image shape: {}, label: {}'.format(image.shape, label))
运行结果
=============train dataset=============
image shape: (32, 32, 3), label: 1
image shape: (32, 32, 3), label: 2
image shape: (32, 32, 3), label: 3
image shape: (32, 32, 3), label: 4
=============evaluation dataset=============
image shape: (32, 32, 3), label: 1
image shape: (32, 32, 3), label: 2
image shape: (32, 32, 3), label: 3
image shape: (32, 32, 3), label: 4
paddle.io.TensorDataset的使用方式
上面介绍了两种数据集的定义方式,分别通过继承 paddle.io.Dataset 与 paddle.io.IterableDataset 就可以实现。不过,还有一种场景,如果我们已经有了Tensor类型的数据,想要快速、直接的创建 Dataset ,而不去实现 paddle.io.Dataset 的各种方法,可以么?这时,我们就可以使用 paddle.io.TensorDataset ,直接将 Tensor 类型的 数据与标签传入 TensorDataset 类即可
from paddle.io import TensorDataset
input_np = np.random.random([2, 3, 4]).astype('float32')
input_tensor = paddle.to_tensor(input_np)
label_np = np.random.random([2, 1]).astype('int32')
label_tensor = paddle.to_tensor(label_np)
dataset = TensorDataset([input_tensor, label_tensor])
for i in range(len(dataset)):
input, label = dataset[i]
print(input, label)
运行结果
Tensor(shape=[3, 4], dtype=float32, place=CUDAPlace(0), stop_gradient=True,
[[0.91451722, 0.94088864, 0.52030772, 0.80783033],
[0.74379814, 0.18669823, 0.41893899, 0.89299613],
[0.67413408, 0.82801068, 0.02079745, 0.95862854]]) Tensor(shape=[1], dtype=int32, place=CUDAPlace(0), stop_gradient=True,
[0])
Tensor(shape=[3, 4], dtype=float32, place=CUDAPlace(0), stop_gradient=True,
[[0.30733261, 0.82390237, 0.99652219, 0.93594497],
[0.62558615, 0.83836132, 0.34213212, 0.72257715],
[0.80075997, 0.38913822, 0.25709155, 0.00520579]]) Tensor(shape=[1], dtype=int32, place=CUDAPlace(0), stop_gradient=True,
[0])
可以看出,我们将Tensor类型的 input 与 label 直接传入TensorDataset中,就可以完成 Dataset 的定义,完全不需要实现上述自定义的那四个步骤