Tensorflow Dataset API 入门

有时候文件做成的tfrecord可能会有几十G,想先直接从众多的图像文件构建Dataset ?
下面的内容应该能帮到你


简介看下面参考文献第一个,他讲的很清楚了

本篇笔记脉络如下
- 1 创建
- 2 变换
- 3 获取 样本Tensors
- 4 使用
- 5 Performance Considerations
- reference

1 创建

因为图像很多,我们不能将图像全部读到Dataset里,所以这一步我们先在Dataset里存放所有文件路径

filelist = os.listdir(img_dir)
# lable_list = ... # 标签列表根据自己的情况获取
# 两个tensor
t_flist = tf.constant(filelist)
t_labellist = tf.constant(lable_list)
# 构造 Dataset
dataset = tf.data.Dataset().from_tensor_slices(t_flist, t_labellist)

至此构造完成,set里面就是一个个样本 [file, label]

2 变换

常用的有这么几个,逐一介绍
- cache
- map
- shuffle
- repeat
- batch
- prefetch

最后给出常用组合

cache

将dataset缓存在内存或者本地硬盘

cache(filename='')

就一个参数 tf.string类型的tf.Tensor,表示文件系统里的一个文件路径,默认是内存

map

map(
    map_func,
    num_parallel_calls=None
)

两个参数
- 第一个map函数,用来变换样本
- 并发数,一般填cpu线程数

针对上面的图像,我们需要将 [file, label] 变换到 [img_data, label],所以函数形式如下

def _mapfunc(file, label):
  with tf.device('/cpu:0'):
    img_raw = tf.read_file(file)
    decoded = tf.image.decode_bmp(img_raw)
    resized = tf.image.resize_images(decoded, [h, w])
  return resized, label
  # 上面return还可以加上文件名,这里的个数随意
  # 下面 Iter.get_next().run 返回的每个成员和这里对应

GPU和CPU异步处理整个计算图,GPU集中于各种大数据量的计算,所以图像解码的任务交给CPU,这是google的建议

shuffle

打乱set里的样本,各种样本混在一起后必须要的操作

shuffle(
    buffer_size,
    seed=None,
    reshuffle_each_iteration=None
)

reshuffle_each_iteration 默认 True
buffer_size 比样本数+1

常用组合

dset = dataset.map(_mapfunc)

3 获取 样本Tensors

先是迭代器
- make_one_shot_iterator()
- make_initializable_iterator(shared_name=None)

还有俩没列出来,用到的时候再加进来吧

然后是 样本Tensors

get_next(name=None)
  • Returns a nested structure of tf.Tensors containing the next element.

样例代码

_iter = dset.make_one_shot_iterator()
next_one = _iter.get_next() # type: tuple

4 使用

把next_one 当成 tensor 开始构建图
比如算个全局平均池化

img, label = next_one
# tf 1.4 这个tensor没有dim的信息,各种op都报dim的错误
# 一般会报 channel 最后这个维度为 None
# 必须加这个reshape
out.set_shape([-1, -1, -1, 3])
out = tf.reshape(img, [-1, h, w, c])
out = tf.reduce_mean(out, axis=(1, 2)) # channels last
# out shape: (n, c)
ValueError: The channel dimension of the inputs should be defined. Found `None`.

5 Performance Considerations

上面那些变换很好用,但是顺序对性能有些影响

Map and Batch

map用到了自定义函数,如果很短就会导致调用开销(overhead)大,所以推荐batch之后map
不过map函数要处理batch,就要加循环了,针对我上面的map,我只能想到用tf.while_loop

Map and Cache

官方言:如果map函数开销大,只要你内存或者硬盘放得下,就map -> cache。
因为不用cache时,这个map每次都在GPU需要前计算,如果mapfunc开销大,
确实会拖慢GPU的脚步,提前算好并缓存能减少突发需求的等待时间
不过上面prefetch里也提到了,n达到一定值就够了,不需要全部。
这个Cache的作用可能会沦为减少频繁的硬盘读

Map and Interleave / Prefetch / Shuffle

后面仨会一直占用一块缓存(缓存了dataset里的元素),如果map改变了样本的大小,
这个顺序就会影响内存使用

Repeat and Shuffle

官方推荐用 tf.contrib.data.shuffle_and_repeat,不行就
shuffle -> repeat

reference

TensorFlow全新的数据读取方式:Dataset API入门教程
https://zhuanlan.zhihu.com/p/30751039
Importing Data
https://www.tensorflow.org/programmers_guide/datasets
Module: tf.data
https://www.tensorflow.org/versions/master/api_docs/python/tf/local_variables
Introduction to TensorFlow Datasets and Estimators
https://developers.googleblog.com/2017/09/introducing-tensorflow-datasets.html
Input Pipeline Performance Guide
https://github.com/tensorflow/tensorflow/blob/master/tensorflow/docs_src/performance/datasets_performance.md

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值