[置顶] 云端TensorFlow读取数据IO的高效方式
低效的IO方式
最近通过观察PAI平台上TensoFlow用户的运行情况,发现大家在数据IO这方面还是有比较大的困惑,主要是因为很多同学没有很好的理解本地执行TensorFlow代码和分布式云端执行TensorFlow的区别。本地读取数据是server端直接从client端获得graph进行计算,而云端服务server在获得graph之后还需要将计算下发到各个worker处理(具体原理可以参考视频教程-Tensorflow高级篇:https://tianchi.aliyun.com/competition/new_articleDetail.html)。

本文通过读取一个简单的CSV文件为例,帮助大家快速了解如何使用TensorFlow高效的读取数据。CSV文件如下:
1,1,1,1,1
2,2,2,2,2
3,3,3,3,3
首先我们来看下大家容易产生问题的几个地方。
1.不建议用python本地读取文件的方式
PAI支持python的自带IO方式,但是需要将数据源和代码打包上传的方式使用,这种读取方式是将数据写入内存之后再计算,效率比较低,不建议使用。范例代码如下:
import csv
csv_reader=csv.reader(open('csvtest.csv'))
for row in csv_reader:
print(row)
2.尽量不要用第三方库的读取文件方法
很多同学使用第三方库的一些数据IO的方式进行数据读取,比如TFLearn、Panda的数据IO方式,这些方法很多都是通过封装PYTHON的读取方式实现的,所以在PAI平台使用的时候也会造成效率低下问题。
3.尽量不要用preload的方式读取文件
很多人在用PAI的服务的时候表示GPU并没有比本地的CPU速度快的明显,主要问题可能就出在数据IO这块。preload的方式是先把数据全部都读到内存中,然后再通过session计算,比如feed的读取方式。这样要先进行数据读取,再计算,不同步造成性能浪费,同时因为内存限制也无法支持大数据量的计算。举个例子:假设我们的硬盘中有一个图片数据集0001.jpg,0002.jpg,0003.jpg……我们只需要把它们读取到内存中,然后提供给GPU或是CPU进行计算就可以了。这听起来很容易,但事实远没有那么简单。事实上,我们必须要把数据先读入后才能进行计算,假设读入用时0.1s,计算用时0.9s,那么就意味着每过1s,GPU都会有0.1s无事可做,这就大大降低了运算的效率。

下面我们看下高效的读取方式。
高效的IO方式
高效的TensorFlow读取方式是将数据读取转换成OP,通过session run的方式拉去数据。另外,读取线程源源不断地将文件系统中的图片读入到一个内存的队列中,而负责计算的是另一个线程,计算需要数据时,直接从内存队列中取就可以了。这样就可以解决GPU因为IO而空闲的问题!

下面我们看下代码,如何在PAI平台通过OP的方式读取数据:
import argparse
import tensorflow as tf
import os
FLAGS=None
def main(_):
dirname = os.path.join(FLAGS.buckets, "csvtest.csv")
reader=tf.TextLineReader()
filename_queue=tf.train.string_input_producer([dirname])
key,value=reader.read(filename_queue)
record_defaults=[[''],[''],[''],[''],['']]
d1, d2, d3, d4, d5= tf.decode_csv(value, record_defaults, ',')
init=tf.initialize_all_variables()
with tf.Session() as sess:
sess.run(init)
coord = tf.train.Coordinator()
threads = tf.train.start_queue_runners(sess=sess,coord=coord)
for i in range(4):
print(sess.run(d2))
coord.request_stop()
coord.join(threads)
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('--buckets', type=str, default='',
help='input data path')
parser.add_argument('--checkpointDir', type=str, default='',
help='output model path')
FLAGS, _ = parser.parse_known_args()
tf.app.run(main=main)
- dirname:OSS文件路径,可以是数组,方便下一阶段shuffle
- reader:TF内置各种reader API,可以根据需求选用
- tf.train.string_input_producer:将文件生成队列
- tf.decode_csv:是一个splite功能的OP,可以拿到每一行的特定参数
- 通过OP获取数据,在session中需要tf.train.Coordinator()和tf.train.start_queue_runners(sess=sess,coord=coord)
在代码中,我们的输入是3行5个字段:
1,1,1,1,1
2,2,2,2,2
3,3,3,3,3
我们循环输出4次,打印出第2个字段。结果如图:

输出结果也证明了数据结构是成队列。
其它
我的微信公众号(长期分享机器学习干货):凡人机器学习
PAI notebook功能上线,支持在线修改代码并且内置各种深度学习框架,欢迎使用:https://data.aliyun.com/product/learn
- 强烈推荐视频教程:https://tianchi.aliyun.com/competition/new_articleDetail.html
- 本文参考了互联网上《十图详解TensorFlow数据读取机制(附代码)》一文,关于图片的读取方式也可以参考这篇文章,感谢原作者。
[置顶] 云端TensorFlow读取数据IO的高效方式的更多相关文章
- 云端TensorFlow读取数据IO的高效方式
低效的IO方式 最近通过观察PAI平台上TensoFlow用户的运行情况,发现大家在数据IO这方面还是有比较大的困惑,主要是因为很多同学没有很好的理解本地执行TensorFlow代码和分布式云端执行T ...
- 第十二节,TensorFlow读取数据的几种方法以及队列的使用
TensorFlow程序读取数据一共有3种方法: 供给数据(Feeding): 在TensorFlow程序运行的每一步, 让Python代码来供给数据. 从文件读取数据: 在TensorFlow图的起 ...
- TensorFlow读取数据的三种方法
tensortlfow数据读取有三种方式 placehold feed_dict:从内存中读取数据,占位符填充数据 queue队列:从硬盘读取数据 Dataset:同时支持内存和硬盘读取数据 plac ...
- tensorflow读取数据的方式
转载:https://blog.csdn.net/u014038273/article/details/77989221 TensorFlow程序读取数据一共有四种方法(一般针对图像): 供给数据(F ...
- Tensorflow 载入数据的三种方式
Tensorflow 数据读取有三种方式: Preloaded data: 预加载数据 Feeding: Python产生数据,再把数据喂给后端. Reading from file: 从文件中直接读 ...
- tensorflow读取数据
线程和队列 在使用TensorFlow进行异步计算时,队列是一种强大的机制. 为了感受一下队列,让我们来看一个简单的例子.我们先创建一个“先入先出”的队列(FIFOQueue),并将其内部所有元素初始 ...
- [置顶] Redis String类型数据常用的16条命令总结
Redis String类型数据常用的16条命令总结 描述:String 类型是最简单的类型,一个Key对应一个Value,String类型是二进制安全的.Redis的String可以包含任何数据,比 ...
- TensorFlow queue多线程读取数据
一.tensorflow读取机制图解 我们必须要把数据先读入后才能进行计算,假设读入用时0.1s,计算用时0.9s,那么就意味着每过1s,GPU都会有0.1s无事可做,这就大大降低了运算的效率. 解决 ...
- tensorflow之数据读取探究(1)
Tensorflow中之前主要用的数据读取方式主要有: 建立placeholder,然后使用feed_dict将数据feed进placeholder进行使用.使用这种方法十分灵活,可以一下子将所有数据 ...
随机推荐
- Dive into Spring framework -- 了解基本原理(一)
在继续我们的分析之前,推荐各位静心来读一下<<Expert_OneOne_J2EE_Design_and_Development>> 第四章, 正如spring BeanFac ...
- 教你如何使用理解懒Redis是更好的Redis
前言 大家都知道 Redis 是单线程的.真正的内行会告诉你,实际上 Redis 并不是完全单线程,因为在执行磁盘上的特定慢操作时会有多线程.目前为止多线程操作绝大部分集中在 I/O 上以至于在不同线 ...
- 利用Java.util.UUID来生成唯一ID(用来做数据库主键好用)
UUID(Universally Unique Identifier)全局唯一标识符,是指在一台机器上生成的数字,它保证对在同一时空中的所有机器都是唯一的.按照开放软件基金会(OSF)制定的标准计算, ...
- Knockout结合Bootstrap创建动态UI--产品列表管理
本篇文章结合Bootstrap创建一个比较完整的应用,对产品列表进行管理,包括产品的增加.删除.修改. 需要的引用 <script type='text/javascript' src='htt ...
- 设计模式--策略模式C++实现
策略模式C++实现 1定义 (Strategy Pattern)定义一组算法,将每个算法都封装起来,并且使他们可以相互替换 也叫政策模式 2类图 3实现 class Strategy{ protect ...
- LightOJ - 1151概率dp+高斯消元
概率dp+高斯消元 https://vjudge.net/problem/LightOJ-1151 题意:刚开始在1,要走到100,每次走的距离1-6,超过100重来,有一些点可能有传送点,可以传送到 ...
- 解决无法启动mysql服务错误1069
之前在服务器上修改了my.ini文件 mysql就一直无法启动 后来把my.ini改回原来的,还是无法启动并报1069错误 在网上查了一下,基本上都是说修改mysql密码,再重新启动,试了一下没作用, ...
- 常用git命令(一)
git add 命令. 这是个多功能命令:可以用它开始跟踪新文件,或者把已跟踪的文件放到暂存区,还能用于合并时把有冲突的文件标记为已解决状态等. 将这个命令理解为“添加内容到下一次提交中”而不是“将一 ...
- IOS-涂鸦
// // PaintView.m // IOS_0224_涂鸦 // // Created by ma c on 16/2/24. // Copyright © 2016年 博文科技. All ri ...
- 优先队列PriorityQueue实现 大小根堆 解决top k 问题
转载:https://www.cnblogs.com/lifegoesonitself/p/3391741.html PriorityQueue是从JDK1.5开始提供的新的数据结构接口,它是一种基于 ...