6.1 Tensorflow笔记(基础篇):队列与线程

原创 2017年08月04日 21:49:40

前言

在Tensorflow的实际应用中,队列与线程是必不可少,主要应用于数据的加载等,不同的情况下使用不同的队列,主线程与其他线程异步进行数据的训练与读取,所以队列与线程的知识也是Tensorflow必须要学会的重要知识
另一方面,Tensorflow作为符号编程框架,在构图后,加载数据有三种方式,预加载与填充数据都存在,数据量大消耗内存等情况的出现.使用第三种方式文件读取避免了前两者的缺点,但是其实现则必须要使用队列与此线程,因此为了进一步的学习,也需要在这个时候掌握队列与线程的知识

FIFOQueue : 先入先出的队列

# 在使用循环神经网络时,希望读入的训练样本是有序的,就要用到FIFOQueue

# 先创建一个先入先出的队列,初始化队列插入0.1,0.2,0.3三个数字
q = tf.FIFOQueue(3,tf.float32)
init = q.enqueue_many(([0.1,0.2,0.3],))
# 定义出队,+1,入队操作
x = q.dequeue()
y = x+1
q_inc = q.enqueue(y)

with tf.Session() as sess:
    sess.run(init)
    # quelen = sess.run(q.size())
    for i in range(2):
        sess.run(q_inc) # 执行两次操作,队列中的值变为0.3,1.1,1.2

    for j in range(sess.run(q.size())):
        print(sess.run(q.dequeue())) # 输出队列的值

运行结果

0.3
1.1
1.2

RandomShuffleQueue:随机队列

 随机队列,再出队列时,是以随机的顺序产生元素的
# 例如,我们在训练一些图像样本时,使用CNN的网络结构,希望可以无序的读入训练样本
q = tf.RandomShuffleQueue(capacity=10,min_after_dequeue=2,dtypes=tf.float32)
# capacity 队列最大长度,min_after_dequeue 出队后最小的长度
with tf.Session() as sess :
    for i in range(0,10): # 10次入队
        sess.run(q.enqueue(i))

    for i in range(0,8): # 8次出队
        print(sess.run(q.dequeue()))

# 在队列长度等于最小值时,执行出队操作,会发生阻断
# 在队列长度等于最大值时,执行入队操作,会发生阻断

# 解除阻断的一种方法---设置等待时间
# run_options = tf.RunOptions(time_out_in_ms = 100000) # 等待十秒
# try:
#     sess.run(q.dequeue(),options=run_options)
# except tf.errors.DeadlineExceededError:
#     print('out of range')

运行结果:

1.0
6.0
3.0
0.0
7.0
4.0
8.0
9.0

队列管理器

q = tf.FIFOQueue(1000, tf.float32)
counter = tf.Variable(0.0)  # 计数器
increment_op = tf.assign_add(counter, tf.constant(1.0))  # 操作给计数器加一
enquence_op = q.enqueue(counter)  # 操作: 让计数器加入队列

# 创建一个队列管理器QueueRunner,用这两个操作相对列q中添加元素,目前我们只使用一个线程
qr = tf.train.QueueRunner(q, enqueue_ops=[increment_op, enquence_op] * 1)

# 启动一个会话,从队列管理器qr中创建线程

# 主线程
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    enquence_threads = qr.create_threads(sess, start=True)  # 启用入队线程
    # 主线程
    for i in range(10):
        print(sess.run(q.dequeue()))

# tensorflow.python.framework.errors_impl.CancelledError: Run call was cancelled

运行结果:

187.0
190.0
195.0
201.0
206.0
209.0
214.0
219.0
223.0
230.0

报错:......

线程和协调器

使用协调器来管理线程
这是要注意的的是在队列线程关闭后,再执行出队操作,将会报错”tf.errors.OutOfRange”
第一点会报错很好理解,队列关闭自然不能出队了(如果你学过数据结构那么你应该能够理解队列的意义,如果没能理解,建议重新掌握队列这一基本概念),
第二点则需要注意一下,报的错误是超出范围,而非队列不存在,希望当你遇到这个错误的时候能够想到,实际上可能是队列线程已经被取消了,而非真的超出了范围.

q = tf.FIFOQueue(1000, tf.float32)
counter = tf.Variable(0.0)  # 计数器
increment_op = tf.assign_add(counter, tf.constant(1.0))  # 操作给计数器加一
enquence_op = q.enqueue(counter)  # 操作: 让计数器加入队列

# 第一种情况,在关闭其他线程之后(除主线程之外的其它线程),调用出队操作
print('第一种情况,在关闭其他线程之后(除主线程之外的其它线程),调用出队操作')
# 创建一个队列管理器QueueRunner,用这两个操作相对列q中添加元素,目前我们只使用一个线程
qr = tf.train.QueueRunner(q, enqueue_ops=[increment_op, enquence_op] * 1)


# 主线程
sess = tf.Session()
sess.run(tf.global_variables_initializer())

# Coordinator: 协调器, 协调线程间的关系,可以视为一种信号量,用来做同步
coord = tf.train.Coordinator()

# 启动入队线程,协调器是线程的参数
enqueue_threads = qr.create_threads(sess,coord=coord,start=True)

# 主线程

for i in range(0,10):
    print(sess.run(q.dequeue()))

coord.request_stop() # 通知其他线程关闭
coord.join(enqueue_threads) # join 操作等待其他线程结束,其他所有线程关闭之后,这一函数才能返回


print('第二种情况: 在队列线程关闭之后,调用出队操作-->处理tf.errors.OutOfRange错误')

# q启动入队线程
enqueue_threads = qr.create_threads(sess,coord=coord,start=True)

# 主线程
coord.request_stop() # 通知其他线程关闭

for j in range(0,10):
    try:
        print(sess.run(q.dequeue()))
    except tf.errors.OutOfRangeError:
        break

coord.join(enqueue_threads) # join 操作等待其他线程结束,其他所有线程关闭之后,这一函数才能返回

运行结果:

第一种情况,在关闭其他线程之后(除主线程之外的其它线程),调用出队操作
5.0
7.0
10.0
17.0
23.0
29.0
34.0
38.0
46.0
52.0
第二种情况: 在队列线程关闭之后,调用出队操作-->处理tf.errors.OutOfRange错误
53.0
53.0
53.0
53.0
53.0
53.0
53.0
53.0
53.0
53.0

更详细的内容你可以参考github中的源代码

版权声明:欢迎转载,共同学习,但请尊重版权,标明出处:http://blog.csdn.net/fontthrone

关于tensorflow 的数据读取线程管理QueueRunner

TensorFlow的Session对象是可以支持多线程的,因此多个线程可以很方便地使用同一个会话(Session)并且并行地执行操作。然而,在Python程序实现这样的并行运算却并不容易。所有线程都...
  • sunquan_ok
  • sunquan_ok
  • 2016年07月05日 16:08
  • 7488

Tensorflow 多线程设置

Tensorflow 多线程设置 一. 通过 ConfigProto 设置多线程  (具体参数功能及描述见  tensorflow/core/protobuf/config.proto) 在...
  • s_sunnyy
  • s_sunnyy
  • 2017年06月08日 16:40
  • 1303

TensorFlow学习系列(五):如何使用队列和多线程优化输入管道

这篇教程是翻译Morgan写的TensorFlow教程,作者已经授权翻译,这是原文。 目录TensorFlow学习系列(一):初识TensorFlowTensorFlow学习系列(二):形状和动态维度...
  • CoderPai
  • CoderPai
  • 2017年04月02日 15:17
  • 3621

Tensorflow并行计算:多核(multicore),多线程(multi-thread),图分割(Graph Partition)

Tensorflow的并行计算:多核,多线程,图分割(Graph Partition) 利用tensorflow训练深度神经网络模型需要消耗很长时间,因为并行化计算就为提升运行速度提供了...
  • rockingdingo
  • rockingdingo
  • 2017年02月18日 08:54
  • 9510

【TensorFlow】数据处理(队列和多线程)

项目已上传至 GitHub —— queue-threading QueueTensorFlow 提供了两种列队 FIFOQueue:先进先出队列 RandomShuffleQueue:随机出队队列 ...
  • White_Idiot
  • White_Idiot
  • 2017年12月17日 23:32
  • 195

【Tensorflow】超大规模数据集解决方案:通过线程来预取(上)

环境Tensorflow1.2(这是最新的一个版本),python2.7 这是我重点要讲的解决方案,我怕篇幅过长,分成了两篇,上篇介绍一下预备的东西,下篇来进行实验 一.Tensorflow中的队列机...
  • mao_xiao_feng
  • mao_xiao_feng
  • 2017年07月02日 16:39
  • 1509

TensorFlow使用next_batch()读取/tensorflow.python.framework.errors_impl.InvalidArgumentError: Expect 3 fi

分批次读取csv文件,如图: 源代码: import tensorflow as tf import numpy as np def readMyFileFormat(fileNameQueue...
  • gsww404
  • gsww404
  • 2017年09月25日 15:06
  • 1985

tensorflow编程一些需要知道的 - 3

做训练时,我们往往要处理大批量的数据,这时如果有个可以异步读取的方式,那么处理程序会更加灵活和高效。FIFOQueue 、RandomShuffleQueue 便是tensorflow提供的一些通过队...
  • mao_feng
  • mao_feng
  • 2017年02月03日 14:41
  • 1060

TensorFlow(三)之多线程

本博文参考TensorFlow实战Google深度学习框架(郑泽宇,顾思宇),仅用作学习 一、TFRecord输入数据格式 TFRecord是tensorflow中存储数据的统一格式。可以统一不同...
  • chenglong_123
  • chenglong_123
  • 2018年01月16日 21:01
  • 45

TensorFlow 基础知识笔记之队列和线程

TensorFlow 基础知识笔记之队列和线程和 TensorFlow 中的其他组件一样, 队列(queue)本身也是图中的一个节点,是一种有状态的节点,其他节点,如入队节点(enqueue)和出队节...
  • ggwcr
  • ggwcr
  • 2017年09月18日 12:46
  • 352
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:6.1 Tensorflow笔记(基础篇):队列与线程
举报原因:
原因补充:

(最多只允许输入30个字)