10张图帮你搞定tensorflow数据读取机制

author author     2022-09-04     217

关键词:

导读在学习tensorflow的过程中,有很多小伙伴反映读取数据这一块很难理解。确实这一块官方的教程比较简略,网上也找不到什么合适的学习材料。今天这篇文章就以图片的形式,用最简单的语言,为大家详细解释一下tensorflow的数据读取机制,文章的最后还会给出实战代码以供参考。

一、tensorflow读取机制图解

首先需要思考的一个问题是,什么是数据读取?以图像数据为例,读取数据的过程可以用下图来表示:

技术分享

假设我们的硬盘中有一个图片数据集0001.jpg,0002.jpg,0003.jpg……我们只需要把它们读取到内存中,然后提供给GPU或是CPU进行计算就可以了。这听起来很容易,但事实远没有那么简单。事实上,我们必须要把数据先读入后才能进行计算,假设读入用时0.1s,计算用时0.9s,那么就意味着每过1s,GPU都会有0.1s无事可做,这就大大降低了运算的效率。

如何解决这个问题?方法就是将读入数据和计算分别放在两个线程中,将数据读入内存的一个队列,如下图所示:

技术分享

读取线程源源不断地将文件系统中的图片读入到一个内存的队列中,而负责计算的是另一个线程,计算需要数据时,直接从内存队列中取就可以了。这样就可以解决GPU因为IO而空闲的问题!

而在tensorflow中,为了方便管理,在内存队列前又添加了一层所谓的“文件名队列”。

为什么要添加这一层文件名队列?我们首先得了解机器学习中的一个概念:epoch。对于一个数据集来讲,运行一个epoch就是将这个数据集中的图片全部计算一遍。如一个数据集中有三张图片A.jpg、B.jpg、C.jpg,那么跑一个epoch就是指对A、B、C三张图片都计算了一遍。两个epoch就是指先对A、B、C各计算一遍,然后再全部计算一遍,也就是说每张图片都计算了两遍。

tensorflow使用文件名队列+内存队列双队列的形式读入文件,可以很好地管理epoch。下面我们用图片的形式来说明这个机制的运行方式。如下图,还是以数据集A.jpg, B.jpg, C.jpg为例,假定我们要跑一个epoch,那么我们就在文件名队列中把A、B、C各放入一次,并在之后标注队列结束。

技术分享

程序运行后,内存队列首先读入A(此时A从文件名队列中出队):

技术分享

再依次读入B和C:

技术分享

技术分享

此时,如果再尝试读入,系统由于检测到了“结束”,就会自动抛出一个异常(OutOfRange)。外部捕捉到这个异常后就可以结束程序了。这就是tensorflow中读取数据的基本机制。如果我们要跑2个epoch而不是1个epoch,那只要在文件名队列中将A、B、C依次放入两次再标记结束就可以了。

二、tensorflow读取数据机制的对应函数

如何在tensorflow中创建上述的两个队列呢?

对于文件名队列,我们使用tf.train.string_input_producer函数。这个函数需要传入一个文件名list,系统会自动将它转为一个文件名队列。

此外tf.train.string_input_producer还有两个重要的参数,一个是num_epochs,它就是我们上文中提到的epoch数。另外一个就是shuffle,shuffle是指在一个epoch内文件的顺序是否被打乱。若设置shuffle=False,如下图,每个epoch内,数据还是按照A、B、C的顺序进入文件名队列,这个顺序不会改变:

技术分享

如果设置shuffle=True,那么在一个epoch内,数据的前后顺序就会被打乱,如下图所示:

技术分享

在tensorflow中,内存队列不需要我们自己建立,我们只需要使用reader对象从文件名队列中读取数据就可以了,具体实现可以参考下面的实战代码。

除了tf.train.string_input_producer外,我们还要额外介绍一个函数:tf.train.start_queue_runners。初学者会经常在代码中看到这个函数,但往往很难理解它的用处,在这里,有了上面的铺垫后,我们就可以解释这个函数的作用了。

在我们使用tf.train.string_input_producer创建文件名队列后,整个系统其实还是处于“停滞状态”的,也就是说,我们文件名并没有真正被加入到队列中(如下图所示)。此时如果我们开始计算,因为内存队列中什么也没有,计算单元就会一直等待,导致整个系统被阻塞。

技术分享

而使用tf.train.start_queue_runners之后,才会启动填充队列的线程,这时系统就不再“停滞”。此后计算单元就可以拿到数据并进行计算,整个程序也就跑起来了,这就是函数tf.train.start_queue_runners的用处。

技术分享

三、实战代码

我们用一个具体的例子感受tensorflow中的数据读取。如图,假设我们在当前文件夹中已经有A.jpg、B.jpg、C.jpg三张图片,我们希望读取这三张图片5个epoch并且把读取的结果重新存到read文件夹中。

技术分享

对应的代码如下:

# 导入tensorflow
import tensorflow as tf 

# 新建一个Session
with tf.Session() as sess:
    # 我们要读三幅图片A.jpg, B.jpg, C.jpg
    filename = [‘A.jpg‘, ‘B.jpg‘, ‘C.jpg‘]
    # string_input_producer会产生一个文件名队列
    filename_queue = tf.train.string_input_producer(filename, shuffle=False, num_epochs=5)
    # reader从文件名队列中读数据。对应的方法是reader.read
    reader = tf.WholeFileReader()
    key, value = reader.read(filename_queue)
    # tf.train.string_input_producer定义了一个epoch变量,要对它进行初始化
    tf.local_variables_initializer().run()
    # 使用start_queue_runners之后,才会开始填充队列
    threads = tf.train.start_queue_runners(sess=sess)
    i = 0
    while True:
        i += 1
        # 获取图片数据并保存
        image_data = sess.run(value)
        with open(‘read/test_%d.jpg‘ % i, ‘wb‘) as f:
            f.write(image_data)

我们这里使用filename_queue = tf.train.string_input_producer(filename, shuffle=False, num_epochs=5)建立了一个会跑5个epoch的文件名队列。并使用reader读取,reader每次读取一张图片并保存。

运行代码后,我们得到就可以看到read文件夹中的图片,正好是按顺序的5个epoch:

技术分享

如果我们设置filename_queue = tf.train.string_input_producer(filename, shuffle=False, num_epochs=5)中的shuffle=True,那么在每个epoch内图像就会被打乱,如图所示:

技术分享

我们这里只是用三张图片举例,实际应用中一个数据集肯定不止3张图片,不过涉及到的原理都是共通的。

四、总结

这篇文章主要用图解的方式详细介绍了tensorflow读取数据的机制,最后还给出了对应的实战代码,希望能够给大家学习tensorflow带来一些实质性的帮助。如果各位小伙伴还有什么疑问,欢迎评论或私信告诉我,谢谢~

原文地址:http://www.linuxprobe.com/tensorflow-learn.html

本文出自 “小华的博客” 博客,请务必保留此出处http://coderhsf.blog.51cto.com/12629645/1936420

几张图帮你理解docker基本原理及快速入门

写的非常好的一篇文章,不知道为什么被删除了。 利用Google快照,做个存档。快照地址:地址作者地址:青牛什么是dockerDocker是一个开源项目,诞生于2013年初,最初是dotCloud公司内部的一个业余项目。它基于Google公司推出的Go... 查看详情

几张图帮你理解docker基本原理及快速入门

写的非常好的一篇文章,不知道为什么被删除了。 利用Google快照,做个存档。快照地址:地址作者地址:青牛什么是dockerDocker是一个开源项目,诞生于2013年初,最初是dotCloud公司内部的一个业余项目。它基于Google公司推出的Go... 查看详情

这都2021年了还不懂linux?一张思维导图帮你理清思路!建议收藏!

Linux思维导图Linux常用命令Linux网络配置Linux进程管理Linux服务管理只用一张图即可理清思路!!!长图加载有点慢,双击即可看到!持续更新中~~~~需要xmind文件评论区留下邮箱我分享给你! 查看详情

十图详解tensorflow数据读取机制(附代码)(代码片段)

在学习TensorFlow的过程中,有很多小伙伴反映读取数据这一块很难理解。确实这一块官方的教程比较简略,网上也找不到什么合适的学习材料。今天这篇文章就以图片的形式,用最简单的语言,为大家详细解释一下... 查看详情

7个gif动图帮你瞬间理解三角函数

 7个GIF动图帮你瞬间理解三角函数蝌蚪五线谱百家号04-2120:53图片来源:IMGUR 三角函数是数学中研究三角形的一个分支,专门阐述三角形的角度和对应边的关系。有趣的是,定义边角关系的三角函数跟圆的关系也是非常密... 查看详情

java面试必问:多线程的实现和同步机制,一文帮你搞定多线程编程

前言进程:一个计算机程序的运行实例,包含了需要执行的指令;有自己的独立地址空间,包含程序内容和数据;不同进程的地址空间是互相隔离的;进程拥有各种资源和状态信息,包括打开的文件、子进程和信号处理。线程:... 查看详情

redis技术探索帮你完全搞定sentinel运作机制(原理篇)(代码片段)

👮‍每日一句最美好的生活方式是和一群志同道合的人,一起奔跑在理想的路上,回头有一路的故事,低头有坚定的脚步,抬头有清晰的远方!👮‍Sentinel存在的意义👮‍Sentinel出现的前提背景在... 查看详情

tensorflow读取数据之csv格式

tensorflow要想用起来,首先自己得搞定数据输入。官方文档中介绍了几种,1.一次性从内存中读取数据到矩阵中,直接输入;2.从文件中边读边输入,而且已经给设计好了多线程读写模型;3.把网络或者内存中的数据转化为tensorflow... 查看详情

利用tensorflow读取二进制cifar-10数据集

使用Tensorflow读取CIFAR-10二进制数据集觉得有用的话,欢迎一起讨论相互学习~FollowMe参考文献Tensorflow官方文档tf.transpose函数解析tf.slice函数解析CIFAR10/CIFAR100数据集介绍tf.train.shuffle_batch函数解析Pythonurlliburlretrieve函数解析importosimportta... 查看详情

tensorflow显示图片

      Tensorflow在处理数据时,经常加载图像数据,有的时候是直接读取文件,有的则是读取二进制文件,为了更好的理解Tensorflow数据处理模式,先简单讲解显示图片机制,就能更好掌握是否读取正确了。一... 查看详情

redis技术探索帮你完全搞定sentinel运作机制(原理篇)(代码片段)

👮‍每日一句最美好的生活方式是和一群志同道合的人,一起奔跑在理想的路上,回头有一路的故事,低头有坚定的脚步,抬头有清晰的远方!👮‍Sentinel存在的意义👮‍Sentinel出现的前提背景在... 查看详情

shardingsphere帮你搞定数据“一键脱敏”(代码片段)

在真实业务场景中,数据库中经常需要存储某些客户的关键性敏感信息如:身份证号、银行卡号、姓名、手机号码等,此类信息按照合规要求,通常需要实现加密存储以满足合规要求。痛点一:通常的解决方... 查看详情

深度分析:java中如何如理异常,一篇帮你搞定!

异常的背景初识异常我们曾经的代码中已经接触了一些“异常”了.例如:除以0System.out.println(10/0);//执行结果Exceptioninthread"main"java.lang.ArithmeticException:/byzero数组下标越界int[]arr={1,2,3};System.out.println(arr[100]);//执行结果Exceptioninthre 查看详情

深度分析:java中如何如理异常,一篇帮你搞定!

异常的背景初识异常我们曾经的代码中已经接触了一些“异常”了.例如:除以0System.out.println(10/0);//执行结果Exceptioninthread"main"java.lang.ArithmeticException:/byzero数组下标越界int[]arr={1,2,3};System.out.println(arr[100]);//执行结果Exceptioninthre 查看详情

大厂java研发岗面试复盘,从基础到源码统统帮你搞定(代码片段)

CacheasideCacheaside也就是旁路缓存,是比较常用的缓存策略。(1)读请求常见流程应用首先会判断缓存是否有该数据,缓存命中直接返回数据,缓存未命中即缓存穿透到数据库,从数据库查询数据然后回写到... 查看详情

tensorflow------tfrecords的读取实例(代码片段)

TensorFlow------TFRecords的读取实例: importosimporttensorflowastf#定义cifar的数据等命令行参数FLAGS=tf.app.flags.FLAGStf.app.flags.DEFINE_string(‘cifar_dir‘,‘./data/cifar10/cifar-10-batches-bin‘,‘文件的目录‘)tf.app.fl 查看详情

java大厂74道高级面试合集,从基础到源码统统帮你搞定

大数据、算法项目在任何大厂无论是面试还是工作运用都是非常广泛的,我们精选了50个百度、腾讯、阿里等大厂的大数据、算法落地经验甩给大家,千万不要做收藏党哦,空闲时间记得随时看看!如果你没有大... 查看详情

tensorflow机器学习入门——cifar10数据集的读取展示与保存(代码片段)

基本信息官网:http://www.cs.toronto.edu/~kriz/cifar.html共60000张图片:50000张用于训练、10000张用于测试图片大小为:32X32数据集图片分为10类:每类6000张数据集下载解压后的目录结构:读取、打印和保存数据集中指定的图片:importpicklei... 查看详情