前言

在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.2for 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:breakcoord.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中的源代码

6.1 Tensorflow笔记(基础篇):队列与线程相关推荐

  1. 7.3 TensorFlow笔记(基础篇):加载数据之从队列中读取

    前言 整体步骤 在TensorFlow中进行模型训练时,在官网给出的三种读取方式,中最好的文件读取方式就是将利用队列进行文件读取,而且步骤有两步: 1. 把样本数据写入TFRecords二进制文件 2 ...

  2. 7.1 TensorFlow笔记(基础篇):加载数据之预加载数据与填充数据

    TensorFlow加载数据 TensorFlow官方共给出三种加载数据的方式: 1. 预加载数据 2. 填充数据 预加载数据的缺点: 将数据直接嵌在数据流图中,当训练数据较大时,很消耗内存.填充的方 ...

  3. 7.2 TensorFlow笔记(基础篇): 生成TFRecords文件

    前言 在TensorFlow中进行模型训练时,在官网给出的三种读取方式,中最好的文件读取方式就是将利用队列进行文件读取,而且步骤有两步: 1. 把样本数据写入TFRecords二进制文件 2. 从队列 ...

  4. 1.1 Tensorflow笔记(基础篇): 图与会话,变量

    图与会话 import tensorflow as tf import os# 取消打印 cpu,gpu选择等的各种警告 # 设置TF_CPP_MIN_LOG_LEVEL 的等级,1.1.0以后设置2 ...

  5. 小猪猪C++笔记基础篇(四)数组、指针、vector、迭代器

    小猪猪C++笔记基础篇(四) 关键词:数组,Vector. 一.数组与指针 数组相信大家学过C语言或者其他的语言都不陌生,简单的就是同一个变量类型的一组数据.例如:int a[10],意思就是从a开始 ...

  6. Redis学习笔记①基础篇_Redis快速入门

    若文章内容或图片失效,请留言反馈.部分素材来自网络,若不小心影响到您的利益,请联系博主删除. 资料链接:https://pan.baidu.com/s/1189u6u4icQYHg_9_7ovWmA( ...

  7. 小何同学的leetcode刷题笔记 基础篇(01)整数反转

    小何同学的leetcode刷题笔记 基础篇(01)整数反转[07] *** [01]数学取余法*** 对数字进行数位操作时,常见的方法便是用取余的方法提取出各位数字,再进行操作 操作(1):对10取余 ...

  8. Google Map 开发笔记——基础篇(Javascript )

    Google Map 开发笔记--基础篇 说明: 一.使用入门: 1.在您需要显示地图的 html 页面嵌入这段 script 2.地图 DOM 元素 3.初始化地图 二.地图画点.线.面 1.标记( ...

  9. MySQL学习笔记-基础篇1

    MySQL 学习笔记–基础篇1 目录 MySQL 学习笔记--基础篇1 1. 数据库概述与MySQL安装 1.1 数据库概述 1.1.1 为什么要使用数据库 1.2 数据库与数据库管理系统 1.2.1 ...

最新文章

  1. 如果让我重新设计一款Android App
  2. c matlab 混合编程 调试,64位MATLAB和C混合编程以及联合调试
  3. Draft-微软出品的云原生下的本地开发辅助工具
  4. 富人为什么会富,穷人为什么穷?看完你就懂
  5. 算法小白——基本排序算法入门
  6. android bitmap转image
  7. Linux中,Tomcat 怎么承载高并发(深入Tcp参数 backlog)
  8. 博客园使用攻略之如何添加自己的js文件
  9. linux定时开关机脚本,linux下实现定时关机
  10. 数据库系统概论--课后习题
  11. 用花生壳搭建个人简易静态网站
  12. matlab环境下图像分形维数的计算,MATLAB环境下图像分形维数的计算_杨书申
  13. 鲲鹏920的服务器芯片,鲲鹏920芯片是什么芯片
  14. 终于找到可转载的摄影基础知识贴了
  15. AI新技术:利用神经网络对图片进行超级压缩
  16. 二层交换机与三层交换机区别详解~
  17. TIM_SetCompare1(TIM14,625); 但是这个办法对TIM4行不通。TIM4使用TIM_OCInitStructure.TIM_Pulse = dutyCycle;
  18. java怎样断开http请求_http post请求管道断开
  19. 为激情为生---“激情团队宣言”
  20. SQL数据库管理—DBCC数据库修复

热门文章

  1. ubuntu下使用crontab定时器
  2. Linux 内核将要支持最新龙芯 3A2000/3B2000
  3. DOS下查看局域网的ip使用情况,以及ip对应的主机名
  4. 干货 | 携程度假无线前端架构演进之路
  5. 对话行癫:解密阿里云顶层设计和底层逻辑
  6. Google MapReduce有啥巧妙优化?
  7. 阿里员工都是这样排查Java问题的,附工具单
  8. 中国SaaS死或生之一:“网红”CRM的大起大落
  9. Spring Boot 最核心的 3 个注解详解
  10. android studio编辑页面案例,2.4、Android Studio使用主题编辑器设计主题