数据管道Dataset
知识树
1.Dataset类相关操作
1.1 Dataset类创建数据集
tf.data.Dataset 类创建数据集,对数据集实例化。
最常用的如:
- tf.data.Dataset.from_tensors() :创建Dataset对象, 合并输入并返回具有单个元素的数据集。
- tf.data.Dataset.from_tensor_slices() :创建一个Dataset对象,输入可以是一个 或者多个 tensor,若是多个 tensor,需要以元组或者字典等形式组装起来
- tf.data.Dataset. from_generator() :迭代生成所需的数据集,一般数据量较大时使用。
注:Dataset可以看作是相同类型“元素”的有序列表。在实际使用时,单个“元素” 可以是向量,也可以是字符串、图片,甚至是tuple或者dict。
1.2 Dataset类数据转换
Dataset包含了非常丰富的数据转换功能:
- map(f): 对数据集中的每个元素应用函数 f ,得到一个新的数据集(这部分往往结合 tf.io 进行读写和解码文件, tf.image 进行图像处理)
- shuffle(buffer_size) :将数据集打乱(设定一个固定大小的缓冲区(Buffer),取出前 buffer_size 个元素放入,并从缓冲区中随机采样,采样后的数据用后续数据替换)
- repeat(count):数据集重复次数
- batch(batch_size) :将数据集分成批次,即对每 batch_size 个元素,使用 tf.stack() 在第 0 维合并,成为一个元素
- flat_map(): 将map函数映射到数据集的每一个元素,并将嵌套的Dataset压平。
flat_map()程序案例1:
import tensorflow as tf
a = tf.data.Dataset.range(1, 6) # ==> [ 1, 2, 3, 4, 5 ]
# NOTE: New lines indicate "block" boundaries.
b=a.flat_map(lambda x: tf.data.Dataset.from_tensors(x).repeat(6))
for item in b:
print(item.numpy(),end=', ')
下面运行出 程序结果
。
1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5,
flat_map()程序案例2:
import tensorflow as tf
dataset = tf.data.Dataset.from_tensor_slices([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
dataset_flat = dataset.flat_map(lambda x: tf.data.Dataset.from_tensor_slices(x))
for line in dataset:
print(line)
下面运行出 程序结果
。
tf.Tensor([1 2 3], shape=(3,), dtype=int32)
tf.Tensor([4 5 6], shape=(3,), dtype=int32)
tf.Tensor([7 8 9], shape=(3,), dtype=int32)
flat_map()程序案例3:
import tensorflow as tf
dataset = tf.data.Dataset.from_tensor_slices([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
dataset_flat = dataset.flat_map(lambda x: tf.data.Dataset.from_tensor_slices(x))
for line in dataset_flat:
print(line)
下面运行出 程序结果
。
tf.Tensor(1, shape=(), dtype=int32)
tf.Tensor(2, shape=(), dtype=int32)
tf.Tensor(3, shape=(), dtype=int32)
tf.Tensor(4, shape=(), dtype=int32)
tf.Tensor(5, shape=(), dtype=int32)
tf.Tensor(6, shape=(), dtype=int32)
tf.Tensor(7, shape=(), dtype=int32)
tf.Tensor(8, shape=(), dtype=int32)
tf.Tensor(9, shape=(), dtype=int32)
- interleave(): 效果类似flat_map,但可以将不同来源的数据夹在一起
- take(): 截取数据集中的前若干个元素
- filter: 过滤掉某些元素
- zip: 将两个长度相同的Dataset横向铰合
zip程序案例1:
a = tf.data.Dataset.range(1, 4) # ==> [ 1, 2, 3 ]
b = tf.data.Dataset.range(4, 7) # ==> [ 4, 5, 6 ]
ds = tf.data.Dataset.zip((a, b))
for line in ds:
print(line)
下面运行出 程序结果
。
(<tf.Tensor: id=182, shape=(), dtype=int64, numpy=1>, <tf.Tensor: id=183, shape=(), dtype=int64, numpy=4>)
(<tf.Tensor: id=184, shape=(), dtype=int64, numpy=2>, <tf.Tensor: id=185, shape=(), dtype=int64, numpy=5>)
(<tf.Tensor: id=186, shape=(), dtype=int64, numpy=3>, <tf.Tensor: id=187, shape=(), dtype=int64, numpy=6>)
zip程序案例2:
a = tf.data.Dataset.range(1, 4) # ==> [ 1, 2, 3 ]
b = tf.data.Dataset.range(4, 7) # ==> [ 4, 5, 6 ]
ds = tf.data.Dataset.zip((b, a))
for line in ds:
print(line)
下面运行出 程序结果
。
(<tf.Tensor: id=194, shape=(), dtype=int64, numpy=4>, <tf.Tensor: id=195, shape=(), dtype=int64, numpy=1>)
(<tf.Tensor: id=196, shape=(), dtype=int64, numpy=5>, <tf.Tensor: id=197, shape=(), dtype=int64, numpy=2>)
(<tf.Tensor: id=198, shape=(), dtype=int64, numpy=6>, <tf.Tensor: id=199, shape=(), dtype=int64, numpy=3>)
- concatenate: 将两个Dataset纵向连接
concatenate程序案例:
a = tf.data.Dataset.range(1, 4) # ==> [ 1, 2, 3 ]
b = tf.data.Dataset.range(4, 7) # ==> [ 4, 5, 6 ]
ds = a.concatenate(b)
for line in ds:
print(line)
下面运行出 程序结果
。
tf.Tensor(1, shape=(), dtype=int64)
tf.Tensor(2, shape=(), dtype=int64)
tf.Tensor(3, shape=(), dtype=int64)
tf.Tensor(4, shape=(), dtype=int64)
tf.Tensor(5, shape=(), dtype=int64)
tf.Tensor(6, shape=(), dtype=int64)
- reduce: 执行归并操作
interleave()是Dataset的类方法,所以interleave是作用在一个Dataset上的。
首先该方法会从该Dataset中取出cycle_length个element,然后对这些element apply map_func, 得到cycle_length个新的Dataset对象。然后从这些新生成的Dataset对象中取数据,每个Dataset对象一次取block_length个数据。当新生成的某个Dataset的对象 取尽时,从原Dataset中再取一个element,然后apply map_func,以此类推。