Tensorflow中资料集(tf.data.Dataset)的入门使用示例
Tensorflow中tf.data.Dataset是最常用的资料集类,我们也使用这个类做转换资料、迭代资料等操作。一般来说,在昨晚特征预处理之后,我们都是用这个类来载入资料,构造算法的输入,它本身自带的repeat/shuffle/batch等操作也非常方便我们使用。但是初学者可能容易搞混。本文构造了一个简单的资料来说明如何使用这个类,并循环迭代输出。

本文目录如下:
引入必要的包使用numpy构造资料集将numpy资料转换成Dataset获取资料迭代器建立了迭代器之后就可以循环资料了使用tqdm循环输出使用Dataset管理资料集需要首先定义资料来源,我们可以使用numpy或者tensor定义的资料作为资料来源来定义Dataset,假设我们有如下numpy定义的程式码。
1、引入必要的包
import numpy as npimport tensorflow as tf
2、使用numpy构造资料集
seed = 1000 # 定义随机数产生的方式data_size = 10 # 资料集大小
n_repeats = 10 # 资料集重复的次数,这个值就是平常我们见到的max_epoch
batch_size = 6 # 批处理的大小
np.random.seed(seed)
# 在这里我们定义两个特征集合和一个标签集合,features1有三列特征,features2有4列特征,labels是0-2之间的一种
features1 = np.random.random((data_size, 3))
features2 = np.random.random((data_size, 4))
labels = np.random.randint(0, 3, data_size)
# 打印测试
print(features1)
print(features2)
print(labels)
3、将numpy资料转换成Dataset
一般我们常使用tf.data.Dataset.from_tensor_slices方法载入资料。同时,Dataset提供了repeat()和batch()方法方便我们建立循环的资料,repeat引数给定一个整型值就可以使资料重复几份,而batch则是将资料以多少条进行批处理,也就是按照batch引数大小切割资料。
注意,repeat和batch的先后顺序不一样 ,结果是不同的,先repeat再batch会把资料先复制N份变成一个大资料,然后batch是根据这个大的资料来做的。例如,上面我们构造了10个数据,先repeat10份就有100个,再假设batch设定为6,那么最终资料是100/6+1=17份,那么也就是循环17次,如果先batch设定为6,那么资料先变成了10/6+1=2份,再repeat10次就有了20份资料了,循环要20次。这个一定要注意。
# dataset = tf.data.Dataset.from_tensor_slices((features1, features2, labels)).repeat(10).batch(6)
dataset = tf.data.Dataset.from_tensor_slices((features1, features2, labels)).batch(batch_size).repeat(n_repeats)
4、获取资料迭代器
资料准备完成之后需要获取资料迭代器供后面迭代使用,Tensorflow建立迭代器的方法有四种,其中单词迭代器和可初始化的迭代器是最常见的两种:# 单次迭代器只能循环使用一次资料,而且单次迭代器不需要手动显示呼叫sess.run()进行初始化即可使用
iterator = dataset.make_one_shot_iterator()
# 可初始化的迭代器可以重新初始化进行循环,但是需要手动显示呼叫sess.run()才能循环
iterator = dataset.make_initializable_iterator()
# 建立了迭代器之后,我们获取迭代器结果便于后面的执行,注意,这里不会产生迭代,只是建立tensorflow的计算图,因此不会消耗迭代
next_element = iterator.get_next()
5、建立了迭代器之后就可以循环资料了
迭代器循环的停止通过捕获资料越界的错误进行count = 0
with tf.Session() as sess:
# 这是显示初始化,当我们的迭代器是dataset.make_initializable_iterator()的时候,才需要呼叫这个方法,否则不需要
sess.run(iterator.initializer)
# 无线循环资料,直到越界
while True:
try:
features1_batch, features2_batch, labels_batch = sess.run(next_element)
count += 1
print(count)
except tf.errors.OutOfRangeError:
break
这里的count输出与上面repeat和batch的先后顺序有关,大家可以自己更换程式码检视。
6、使用tqdm循环输出
除了上述捕获越界错误外,我们也可手动计算epoch循环次数和batch循环次数来确定终止的情况。可以配合tqdm包进行输出。tqdm是一个快速,可扩充套件的Python进度条,可以在 Python 长循环中新增一个进度提示资讯,使用者只需要封装任意的迭代器 tqdm(iterator)即可。我们先引入必要的包:import time
from tqdm import trange
接下来我们使用自己计算的结果循环:
# 注意,这里例项总数显然是先repeat再batch的结果,要根据实际情况做改变
total_instances = data_size * n_repeats
steps_per_epoch = data_size // batch_size if data_size / batch_size == 0 else data_size // batch_size + 1
with tf.Session() as sess:
sess.run(iterator.initializer)
for epoch in range(n_repeats):
tqr = trange(steps_per_epoch, desc="%2d" % (epoch + 1), leave=False)
for _ in tqr:
features1_batch, features2_batch, labels_batch = sess.run(next_element)
# 由于这里循环没有计算过程,速度很快,看不到进度条,我们加了暂停0.5秒便于观察结果
time.sleep(0.5)
# 由于所有资料都已经循环完毕,如下程式码将会报越界的错误,证明我们是对的
sess.run(next_element)
我们可以看到如下的进度条:

以上就是Tensorflow中dataset的读取、循环使用的基本概念。
完整程式码点选了解更多,并在原文底部中有Github的连结。
