TensorFlow2.0(6):利用data模块进行数据预处理(上)

简介: TensorFlow2.0(6):利用data模块进行数据预处理(上)

1 创建


对于创建Dataset对象,官方文档中总结为两种方式,我将这两种方式细化后总结为4中方式:


(1)通过Dataset中的range()方法创建包含一定序列的Dataset对象。


  • range()


range()方法是Dataset内部定义的一个的静态方法,可以直接通过类名调用。另外,Dataset中的range()方法与Python本身内置的range()方法接受参数形式是一致的,可以接受range(begin)、range(begin, end)、range(begin, end, step)等多种方式传参。


import tensorflow as tfimport numpy as np


dataset1 = tf.data.Dataset.range(5)type(dataset1)


tensorflow.python.data.ops.dataset_ops.RangeDataset


注:RangeDataset是Dataset的一个子类。Dataset对象属于可迭代对象, 可通过循环进行遍历:


for i in dataset1:    print(i)    print(i.numpy())


tf.Tensor(0, shape=(), dtype=int64)
0
tf.Tensor(1, shape=(), dtype=int64)
1
tf.Tensor(2, shape=(), dtype=int64)
2
tf.Tensor(3, shape=(), dtype=int64)
3
tf.Tensor(4, shape=(), dtype=int64)
4


可以看到,range()方法创建的Dataset对象内部每一个元素都以Tensor对象的形式存在,可以通过numpy()方法访问真实值。


  • from_generator()


如果你觉得range()方法不够灵活,功能不够强大,那么你可以尝试使用from_generator()方法。from_generator()方法接收一个可调用的生成器函数最为参数,在遍历from_generator()方法返回的Dataset对象过程中不断生成新的数据,减少内存占用,这在大数据集中很有用。


def count(stop):  i = 0  while i<stop:    print('第%s次调用……'%i)    yield i    i += 1


dataset2 = tf.data.Dataset.from_generator(count, args=[3], output_types=tf.int32, output_shapes = (), )


a = iter(dataset2)


next(a)


第0次调用……
<tf.Tensor: id=46, shape=(), dtype=int32, numpy=0>


next(a)


第1次调用……
<tf.Tensor: id=47, shape=(), dtype=int32, numpy=1>


for i in dataset2:    print(i)    print(i.numpy())


第0次调用……
tf.Tensor(0, shape=(), dtype=int32)
0
第1次调用……
tf.Tensor(1, shape=(), dtype=int32)
1
第2次调用……
tf.Tensor(2, shape=(), dtype=int32)
2


**(2)通过接收其他类型的集合类对象创建Dataset对象。**这里所说的集合类型对象包含Python内置的list、tuple,numpy中的ndarray等等。这种创建Dataset对象的方法大多通过from_tensors()和from_tensor_slices()两个方法实现。这两个方法很常用,重点说一说。


  • from_tensors()


from_tensors()方法接受一个集合类型对象作为参数,返回值为一个TensorDataset类型对象,对象内容、shape因传入参数类型而异。


当接收参数为list或Tensor对象时,返回的情况是一样的,因为TensorFlow内部会将list先转为Tensor对象,然后实例化一个Dataset对象:


a = [0,1,2,3,4]dataset1 = tf.data.Dataset.from_tensors(a)dataset1_n = tf.data.Dataset.from_tensors(np.array(a))dataset1_t = tf.data.Dataset.from_tensors(tf.constant(a))


dataset1,next(iter(dataset1))


(<TensorDataset shapes: (5,), types: tf.int32>,
 <tf.Tensor: id=67, shape=(5,), dtype=int32, numpy=array([0, 1, 2, 3, 4], dtype=int32)>)


dataset1_n,next(iter(dataset1_n))


(<TensorDataset shapes: (5,), types: tf.int64>,
 <tf.Tensor: id=73, shape=(5,), dtype=int64, numpy=array([0, 1, 2, 3, 4])>)


dataset1_t,next(iter(dataset1_t))


(<TensorDataset shapes: (5,), types: tf.int32>,
 <tf.Tensor: id=79, shape=(5,), dtype=int32, numpy=array([0, 1, 2, 3, 4], dtype=int32)>)


多维结构也是一样的:


a = [0,1,2,3,4]b = [5,6,7,8,9]dataset2 = tf.data.Dataset.from_tensors([a,b])dataset2_n = tf.data.Dataset.from_tensors(np.array([a,b]))dataset2_t = tf.data.Dataset.from_tensors(tf.constant([a,b]))


dataset2,next(iter(dataset2))


(<TensorDataset shapes: (2, 5), types: tf.int32>,
 <tf.Tensor: id=91, shape=(2, 5), dtype=int32, numpy=
 array([[0, 1, 2, 3, 4],
        [5, 6, 7, 8, 9]], dtype=int32)>)


dataset2_n,next(iter(dataset2_n))


(<TensorDataset shapes: (2, 5), types: tf.int64>,
 <tf.Tensor: id=97, shape=(2, 5), dtype=int64, numpy=
 array([[0, 1, 2, 3, 4],
        [5, 6, 7, 8, 9]])>)


dataset2_t,next(iter(dataset2_t))


(<TensorDataset shapes: (2, 5), types: tf.int32>,
 <tf.Tensor: id=103, shape=(2, 5), dtype=int32, numpy=
 array([[0, 1, 2, 3, 4],
        [5, 6, 7, 8, 9]], dtype=int32)>)


当接收参数为数组就不一样了,此时Dataset内部内容为一个tuple,tuple的元素是原来tuple元素转换为的Tensor对象:


a = [0,1,2,3,4]b = [5,6,7,8,9]dataset3 = tf.data.Dataset.from_tensors((a,b))


for i in dataset3:    print(type(i))    print(i)    for j in i:        print(j)


<class 'tuple'>
(<tf.Tensor: id=112, shape=(5,), dtype=int32, numpy=array([0, 1, 2, 3, 4], dtype=int32)>, <tf.Tensor: id=113, shape=(5,), dtype=int32, numpy=array([5, 6, 7, 8, 9], dtype=int32)>)
tf.Tensor([0 1 2 3 4], shape=(5,), dtype=int32)
tf.Tensor([5 6 7 8 9], shape=(5,), dtype=int32)


  • from_tensor_slices()


from_tensor_slices()方法返回一个TensorSliceDataset类对象,TensorSliceDataset对象比from_tensors()方法返回的TensorDataset对象支持更加丰富的操作,例如batch操作等,因此在实际应用中更加广泛。返回的TensorSliceDataset对象内容、shape因传入参数类型而异。


当传入一个list时,时将list中元素逐个转换为Tensor对象然后依次放入Dataset中,所以Dataset中有多个Tensor对象:


a = [0,1,2,3,4]dataset1 = tf.data.Dataset.from_tensor_slices(a)


dataset1


<TensorSliceDataset shapes: (), types: tf.int32>


for i,elem in enumerate(dataset1):    print(i, '-->', elem)


0 --> tf.Tensor(0, shape=(), dtype=int32)
1 --> tf.Tensor(1, shape=(), dtype=int32)
2 --> tf.Tensor(2, shape=(), dtype=int32)
3 --> tf.Tensor(3, shape=(), dtype=int32)
4 --> tf.Tensor(4, shape=(), dtype=int32)


a = [0,1,2,3,4]b = [5,6,7,8,9]dataset2 = tf.data.Dataset.from_tensor_slices([a,b])


dataset2


<TensorSliceDataset shapes: (5,), types: tf.int32>


for i,elem in enumerate(dataset2):    print(i, '-->', elem)


0 --> tf.Tensor([0 1 2 3 4], shape=(5,), dtype=int32)
1 --> tf.Tensor([5 6 7 8 9], shape=(5,), dtype=int32)


当传入参数为tuple时,会将tuple中各元素转换为Tensor对象,然后将第一维度对应位置的切片进行重新组合成一个tuple依次放入到Dataset中,所以在返回的Dataset中有多个tuple。这种形式在对训练集和测试集进行重新组合是非常实用。


a = [0,1,2,3,4]b = [5,6,7,8,9]dataset1 = tf.data.Dataset.from_tensor_slices((a,b))


dataset1


<TensorSliceDataset shapes: ((), ()), types: (tf.int32, tf.int32)>


for i in dataset1:    print(i)


(<tf.Tensor: id=143, shape=(), dtype=int32, numpy=0>, <tf.Tensor: id=144, shape=(), dtype=int32, numpy=5>)
(<tf.Tensor: id=145, shape=(), dtype=int32, numpy=1>, <tf.Tensor: id=146, shape=(), dtype=int32, numpy=6>)
(<tf.Tensor: id=147, shape=(), dtype=int32, numpy=2>, <tf.Tensor: id=148, shape=(), dtype=int32, numpy=7>)
(<tf.Tensor: id=149, shape=(), dtype=int32, numpy=3>, <tf.Tensor: id=150, shape=(), dtype=int32, numpy=8>)
(<tf.Tensor: id=151, shape=(), dtype=int32, numpy=4>, <tf.Tensor: id=152, shape=(), dtype=int32, numpy=9>)


c = ['a','b','c','d','e']dataset3 = tf.data.Dataset.from_tensor_slices((a,b,c))


dataset3


<TensorSliceDataset shapes: ((), (), ()), types: (tf.int32, tf.int32, tf.string)>


for i in dataset3:    print(i)


(<tf.Tensor: id=162, shape=(), dtype=int32, numpy=0>, <tf.Tensor: id=163, shape=(), dtype=int32, numpy=5>, <tf.Tensor: id=164, shape=(), dtype=string, numpy=b'a'>)
(<tf.Tensor: id=165, shape=(), dtype=int32, numpy=1>, <tf.Tensor: id=166, shape=(), dtype=int32, numpy=6>, <tf.Tensor: id=167, shape=(), dtype=string, numpy=b'b'>)
(<tf.Tensor: id=168, shape=(), dtype=int32, numpy=2>, <tf.Tensor: id=169, shape=(), dtype=int32, numpy=7>, <tf.Tensor: id=170, shape=(), dtype=string, numpy=b'c'>)
(<tf.Tensor: id=171, shape=(), dtype=int32, numpy=3>, <tf.Tensor: id=172, shape=(), dtype=int32, numpy=8>, <tf.Tensor: id=173, shape=(), dtype=string, numpy=b'd'>)
(<tf.Tensor: id=174, shape=(), dtype=int32, numpy=4>, <tf.Tensor: id=175, shape=(), dtype=int32, numpy=9>, <tf.Tensor: id=176, shape=(), dtype=string, numpy=b'e'>)


对比总结一下from_generator()、from_tensor()、from_tensor_slices()这三个方法:


  • from_tensors()在形式上与from_tensor_slices()很相似,但其实from_tensors()方法出场频率上比from_tensor_slices()差太多,因为from_tensor_slices()的功能更加符合实际需求,且返回的TensorSliceDataset对象也提供更多的数据处理功能。from_tensors()方法在接受list类型参数时,将整个list转换为Tensor对象放入Dataset中,当接受参数为tuple时,将tuple内元素转换为Tensor对象,然后将这个tuple放入Dataset中。
  • from_generator()方法接受一个可调用的生成器函数作为参数,在遍历Dataset对象时,通过通用生成器函数继续生成新的数据供训练和测试模型使用,这在大数据集合中很实用。
  • from_tensor_slices()方法接受参数为list时,将list各元素依次转换为Tensor对象,然后依次放入Dataset中;更为常见的情况是接受的参数为tuple,在这种情况下,要求tuple中各元素第一维度长度必须相等,from_tensor_slices()方法会将tuple各元素第一维度进行拆解,然后将对应位置的元素进行重组成一个个tuple依次放入Dataset中,这一功能在重新组合数据集属性和标签时很有用。另外,from_tensor_slices()方法返回的TensorSliceDataset对象支持batch、shuffle等等功能对数据进一步处理。


(3)通过读取磁盘中的文件(文本、图片等等)来创建Dataset。**tf.data中提供了TextLineDataset、TFRecordDataset等对象来实现此功能。这部分内容比较多,也比较重要,我打算后续用专门一篇博客来总结这部分内容。

相关文章
|
3月前
|
机器学习/深度学习 TensorFlow API
TensorFlow 2常用模块
【8月更文挑战第18天】TensorFlow 2常用模块。
44 11
|
6月前
|
机器学习/深度学习 自然语言处理 算法
【Tensorflow深度学习】优化算法、损失计算、模型评估、向量嵌入、神经网络等模块的讲解(超详细必看)
【Tensorflow深度学习】优化算法、损失计算、模型评估、向量嵌入、神经网络等模块的讲解(超详细必看)
100 1
|
机器学习/深度学习 TensorFlow 算法框架/工具
tensorflow.keras常用模块介绍
tensorflow.keras常用模块介绍
uiu
|
机器学习/深度学习 PyTorch TensorFlow
TensorFlow 2 基础概念语法与常用模块
TensorFlow 2 基础概念语法与常用模块
uiu
124 0
TensorFlow 2 基础概念语法与常用模块
|
数据采集 大数据 异构计算
TensorFlow2.0(6):利用data模块进行数据预处理(下)
TensorFlow2.0(6):利用data模块进行数据预处理(下)
|
TensorFlow 算法框架/工具 计算机视觉
二、cmd、pycharm下同时导入tensorflow,cv2模块,Anaconda导入tensorflow(超级详细步骤)
二、cmd、pycharm下同时导入tensorflow,cv2模块,Anaconda导入tensorflow(超级详细步骤)
二、cmd、pycharm下同时导入tensorflow,cv2模块,Anaconda导入tensorflow(超级详细步骤)
|
机器学习/深度学习 大数据 TensorFlow
TensorFlow Hub介绍:TensorFlow中可重用的机器学习模块库
本文对TensorFlow Hub库的介绍,并举例说明其用法。
7536 0
|
机器学习/深度学习 TensorFlow API