TensorFlow 队列与多线程

正如TensorFlow中的其他组件一样,队列就是TensorFlow图中的节点。这是一种有状态的节点,就像变量一样:其他节点可以修改它的内容。具体来说,其他节点可以把新元素插入到队列后端,也可以把队列前端的元素删除。为了感受一下队列,让我们来看一个非常简单的例子:

# coding:utf-8
import tensorflow as tf

#创建一个先入先出队列,队列最多可以保存两个元素,并制定类行为整型
q=tf.FIFOQueue(2, "int32")
#使用 enqueue_many 函数来初始化队列中的元素。和变量初始化类似,在使用队列之前需要明确的调用这些初始化过程
init = q.enqueue_many(([0, 10],))
#通过 dequeue 取出队列中第一个元素
x = q.dequeue()
y = x+1
#通过 enqueue 将y加入队列
q_inc = q.enqueue([y])

with tf.Session() as sess:
    init.run()
    for _ in range(6):
        v, _ = sess.run([x, q_inc])
        print v 

#输出结果为:
#0
#10
#1
#11
#2
#12

TensorFlow提供了 FIFOQueue 和 RandomShuffleQueue 两种队列。 FIFOQueue 实现的是先进先出的队列,RandomShuffleQueue 会将队列中元素打乱,出队列得到的是当前队列中随机选择的一个。

在 TensorFlow 中,队列不仅仅是一种数据结构,更是“异步张量取值”的一个重要机制。比如多个线程可以同时向一个队列中写元素,或者同时读取一个队列中的元素。TensorFlow提供了两个类来帮助多线程的实现:tf.Coordinator和 tf.QueueRunner。从设计上这两个类必须被一起使用。

Coordinator类用来帮助多个线程协同工作,多个线程同步终止。 其主要方法有:
should_stop():如果线程应该停止则返回True。
request_stop(<exception>): 请求该线程停止。
join(<list of threads>):等待被指定的线程终止。


首先创建一个 Coordinator 对象,然后建立一些使用Coordinator对象的线程。这些线程通常一直循环运行,一直到should_stop()返回True时停止。 任何线程都可以决定计算什么时候应该停止。它只需要调用request_stop(),同时其他线程的should_stop()将会返回True,然后都停下来。

接下来我们通过一个简单的例子来看一下 Coordinator 对象的使用:

# coding:utf-8
import tensorflow as tf
import numpy as np
import threading
import time

#线程中运行的程序,这个程序每隔1秒判断是否需要停止并打印自己的ID
def MyLoop(coord, worker_id):
    while not coord.should_stop():
        #随即停止线程
        if np.random.rand() < 0.1 :
            print "stopinig form id: %d\n" % worker_id,
            coord.request_stop()
        else:
            print "Workinig on id: %d\n" % worker_id,
        #暂停1妙
        time.sleep(1)
#声明一个 tf.train.Coordinator 类来协同多个线程
coord = tf.train.Coordinator()
#创建5个线程
threads = [threading.Thread(target=MyLoop, args=(coord,i)) for i in xrange(5)]
#启动所有的线程
for t in threads: t.start()
#等待所有线程退出
coord.join(threads)


tf.QueueRunner 主要是用于启动多个线程来操作同一个队列,启动这些线程可以通过 tf.Coordinator 来统一管理

# coding:utf-8
#启动5个线程来执行队列的入队操作,其中每一个线程都是将随机数写入队列。于是在每次运行出队操作时,就可以得到一个随机数。

import tensorflow as tf
#声明一个先进先出的队列,队列最多100个元素,类型为实数
queue = tf.FIFOQueue(100, "float")
#定义队列的入队操作
enqueue_op = queue.enqueue([tf.random_normal([1])])

#使用 tf.train.QueueRunner 来创建多个线程运行队列的入队操作
#tf.train.QueueRunner 第一个参数给出了被操作的队列
#[enqueue_op] × 5 表示需要启动5个线程,每个此案城中运行的是enqueue_op操作
qr = tf.train.QueueRunner(queue, [enqueue_op] * 5)

#将 QueueRunner 加入TensorFlow 计算图上制定的集合
tf.train.add_queue_runner(qr)
#定义出队操作
out_tensor = queue.dequeue()

with tf.Session() as sess:
    #使用Coordinator 来协同启动的线程
    coord = tf.train.Coordinator()
    threads = tf.train.start_queue_runners(sess=sess, coord=coord)
    #获取队列中的取值
    for i in range(3):print sess.run(out_tensor)[0]
    #停止所有线程
    coord.request_stop()
    coord.join(threads)






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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值