Python深度学习笔记01——线程队列与tensorflow的io操作(壹)

目录

前言

一、tensorflow与io操作

二、tensorflow队列

1、参数 方法

2、案例实现

三、队列管理器与线程协调器实现异步读取训练

1、队列管理器

2、异步操作

3、线程协调器

总结

 

 


 

前言

关于python深度学习(tensorflow 1.x版本)学习笔记01——线程队列与io操作(壹)

 

一、tensorflow与io操作

  • io操作相对于CPU操作计算来说速度稍慢。

       当读取海量样本时,一次性读取消耗内存;只能一次性进行训练、速度慢。

  • tensorflow:

        ①多线程机制:能够并行地执行任务。②队列。③文件的改善:tfrecords 。

二、tensorflow队列

1、参数 方法

1)tf.FIFOQueue 先进先出队列,按顺序出队列(在训练样本时,希望读入的训练样本是有序的。)

  •      tf.FIFOQueue(capacity, dtypes, name='fifo_queue')

         #capacity:整数。可能存储在此队列中的元素数量的上限。

         #DType对象列表。长度dtypes必须等于每个队列元素中的张量数,dtype的类型形状,决定后面进队列元素形状。

         方法:

      q.dequeue() #获取队列的数据

      q.enqueue(值) #将一个数据添加进队列

      q.enqueue_many(列表或者元组) #将多个数据添加进队列

      q.size() #返回队列的大小

2)tf.RandomShuffleQueue 随机出队列

2、案例实现

import tensorflow as tf

# 模拟一下同步先处理数据,然后才能取数据训练
# tensorflow当中,运行操作(有操作计算)具有依赖性
# 1、首先定义队列
Q = tf.FIFOQueue(3, tf.float32)
# 放入一些数据
enq_many = Q.enqueue_many([[1, 0.1, 0.01], ])
# 2、定义一些读取数据、取数据的过程。#  以下案例模拟定义处理数据的过程:取数据 、*2、 入队列
out_q = Q.dequeue()
data = out_q * 2
en_q = Q.enqueue(data)

with tf.Session() as sess:
    # 初始化队列
    sess.run(enq_many)

    # 进行数据处理
    for i in range(100):
        sess.run(en_q)

    # 训练数据
    for i in range(Q.size().eval()):
        print(sess.run(Q.dequeue()))

例子:同步操作一个(出队列、*2、入队列)以此进行100 次循环的过程,结果如下:

       分析:当数据量很大时,入队操作从硬盘中读取数据,放入内存中,主线程需要等待入队操作完成,才能进行训练。会话里可以运行多个线程,实现异步读取。

三、队列管理器与线程协调器实现异步读取训练

1、队列管理器

  • tf.train.QueueRunner(queue, enqueue_ops=None)

  # queue:A Queue

       # enqueue_ops:添加线程的队列操作列表,[]*2,指定两个线程

  # create_threads(sess, coord=None,start=False) 创建线程来运行给定会话的入队操作

     # start:布尔值,如果True启动线程;如果为False调用者 必须调用start()启动线程

  # coord:线程协调器  用于线程的管理

2、异步操作

  • 通过队列管理器来实现变量加1,入队,主线程出队列的操作,观察效果
# 模拟异步子线程 存入样本,主线程 读取样本
import tensorflow as tf
Q = tf.FIFOQueue(3, tf.float32)# 定义队列

# 1、定义一个队列 容量1000, 类型tf.float32
queue = tf.FIFOQueue(1000, tf.float32)

# 2、定义要做的事情 循环 值,+1 并且入列的操作
var = tf.Variable(0.0)
# assign_add操作 和 enq_op 不是同步执行, assign_add操作有可能执行很多次才会执行enq_op操作
data = tf.assign_add(var, tf.constant(1.0))
en_q = Q.enqueue(data)

# 3、定义队列管理器op,指定多少个子线程,子线程该干什么事情
qr = tf.train.QueueRunner(Q, enqueue_ops=[en_q] * 2)

# 初始化变量的op
init_op = tf.global_variables_initializer()

with tf.Session() as sess:
    # 初始化变量
    sess.run(init_op) 
   
    # 真正开启子线程
    threads = qr.create_threads(sess, start=True)

    # 主线程不断读取数据训练
    for i in range(300):
        print(sess.run(Q.dequeue()))

       报错分析:主线程结束,意味着session关闭,资源释放。这时候有一个问题就是,入队自顾自地去执行,在需要的出队操作完成之后,程序无法结束。需要一个实现线程间的同步,终止其他线程--线程协调器。

3、线程协调器

  • tf.train.Coordinator() 线程协调员,实现一个简单的机制来协调一组线程的终止

  方法:    返回的是线程协调实例

    request_stop()  请求停止

              should_stop() 检查是否要求停止(一般不用)

    join(threads=None, stop_grace_period_secs=120) 等待线程终止

  • 线程协调员实例
 # 模拟异步子线程 存入样本,主线程 读取样本
# 1、定义一个队列 容量1000, 类型tf.float32
queue = tf.FIFOQueue(1000, tf.float32)

# 2、定义要做的事情 循环 值,+1 并且入列的操作
var = tf.Variable(0.0)
# assign_add操作 和 enq_op 不是同步执行, assign_add操作有可能执行很多次才会执行enq_op操作
data = tf.assign_add(var, tf.constant(1.0))
en_q = Q.enqueue(data)

# 3、定义队列管理器op,指定多少个子线程,子线程该干什么事情
qr = tf.train.QueueRunner(Q, enqueue_ops=[en_q] * 2)
# 初始化变量的op
init_op = tf.global_variables_initializer()
# 通过with上下文创建的会话会自动关闭, 主线程已经执行完毕了
with tf.Session() as sess:
    # 初始化变量
    sess.run(init_op)

    # 开启线程管理器
    coord = tf.train.Coordinator()
    # 真正开启子线程
    threads = qr.create_threads(sess=sess, coord=coord, start=True)
    # 主线程不断读取数据训练
    for i in range(300):
        # 主线程deq 出列
        print(sess.run(Q.dequeue()))

    # 进行回收
    coord.request_stop()
    coord.join(threads=threads)

 


总结

       以上是通过学习视频《Python深度学习(tensorflow)》整理学习笔记(附:视频学习地址https://www.bilibili.com/video/BV1Wt411C75s/,本篇主要记录了tensorflow解决读取数据、实现同步模拟、队列管理器和线程协调器实现异步读取训练。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值