tensorflow中 tf.train.slice_input_producer() 函数和 tf.train.batch() 函数

2024-06-12 12:32

本文主要是介绍tensorflow中 tf.train.slice_input_producer() 函数和 tf.train.batch() 函数,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

原创:https://blog.csdn.net/dcrmg/article/details/79776876

别人总结的转载方便自己以后看

tensorflow数据读取机制

tensorflow中为了充分利用GPU,减少GPU等待数据的空闲时间,使用了两个线程分别执行数据读入和数据计算。

具体来说就是使用一个线程源源不断的将硬盘中的图片数据读入到一个内存队列中,另一个线程负责计算任务,所需数据直接从内存队列中获取。

tf在内存队列之前,还设立了一个文件名队列,文件名队列存放的是参与训练的文件名,要训练 N个epoch,则文件名队列中就含有N个批次的所有文件名。 示例图如下:


图片来至于 https://zhuanlan.zhihu.com/p/27238630)

在N个epoch的文件名最后是一个结束标志,当tf读到这个结束标志的时候,会抛出一个 OutofRange 的异常,外部捕获到这个异常之后就可以结束程序了。而创建tf的文件名队列就需要使用到 tf.train.slice_input_producer 函数。


tf.train.slice_input_producer


tf.train.slice_input_producer是一个tensor生成器,作用是按照设定,每次从一个tensor列表中按顺序或者随机抽取出一个tensor放入文件名队列。


[python]  view plain copy
  1. slice_input_producer(tensor_list, num_epochs=None, shuffle=True, seed=None,  
  2.                          capacity=32, shared_name=None, name=None)  

  • 第一个参数 tensor_list:包含一系列tensor的列表,表中tensor的第一维度的值必须相等,即个数必须相等,有多少个图像,就应该有多少个对应的标签。
  • 第二个参数num_epochs: 可选参数,是一个整数值,代表迭代的次数,如果设置 num_epochs=None,生成器可以无限次遍历tensor列表,如果设置为 num_epochs=N,生成器只能遍历tensor列表N次。
  • 第三个参数shuffle: bool类型,设置是否打乱样本的顺序。一般情况下,如果shuffle=True,生成的样本顺序就被打乱了,在批处理的时候不需要再次打乱样本,使用 tf.train.batch函数就可以了;如果shuffle=False,就需要在批处理时候使用 tf.train.shuffle_batch函数打乱样本。
  • 第四个参数seed: 可选的整数,是生成随机数的种子,在第三个参数设置为shuffle=True的情况下才有用。
  • 第五个参数capacity:设置tensor列表的容量。
  • 第六个参数shared_name:可选参数,如果设置一个‘shared_name’,则在不同的上下文环境(Session)中可以通过这个名字共享生成的tensor。
  • 第七个参数name:可选,设置操作的名称。


tf.train.slice_input_producer定义了样本放入文件名队列的方式,包括迭代次数,是否乱序等,要真正将文件放入文件名队列,还需要调用tf.train.start_queue_runners 函数来启动执行文件名队列填充的线程,之后计算单元才可以把数据读出来,否则文件名队列为空的,计算单元就会处于一直等待状态,导致系统阻塞。


tf.train.slice_input_producer 和 tf.train.start_queue_runners 使用:

[python]  view plain copy
  1. import tensorflow as tf  
  2.   
  3. images = ['img1''img2''img3''img4''img5']  
  4. labels= [1,2,3,4,5]  
  5.   
  6. epoch_num=8  
  7.   
  8. f = tf.train.slice_input_producer([images, labels],num_epochs=None,shuffle=False)  
  9.   
  10. with tf.Session() as sess:  
  11.     sess.run(tf.global_variables_initializer())  
  12.     coord = tf.train.Coordinator()  
  13.     threads = tf.train.start_queue_runners(sess=sess, coord=coord)  
  14.     for i in range(epoch_num):  
  15.         k = sess.run(f)  
  16.         print '************************'  
  17.         print (i,k)  
  18.   
  19.     coord.request_stop()  
  20.     coord.join(threads)  


tf.train.slice_input_producer函数中shuffle=False,不对tensor列表乱序,输出:

[python]  view plain copy
  1. ************************  
  2. (0, ['img1'1])  
  3. ************************  
  4. (1, ['img2'2])  
  5. ************************  
  6. (2, ['img3'3])  
  7. ************************  
  8. (3, ['img4'4])  
  9. ************************  
  10. (4, ['img5'5])  
  11. ************************  
  12. (5, ['img1'1])  
  13. ************************  
  14. (6, ['img2'2])  
  15. ************************  
  16. (7, ['img3'3])  


如果设置shuffle=True,输出乱序:

[python]  view plain copy
  1. ************************  
  2. (0, ['img5'5])  
  3. ************************  
  4. (1, ['img4'4])  
  5. ************************  
  6. (2, ['img1'1])  
  7. ************************  
  8. (3, ['img3'3])  
  9. ************************  
  10. (4, ['img2'2])  
  11. ************************  
  12. (5, ['img3'3])  
  13. ************************  
  14. (6, ['img2'2])  
  15. ************************  
  16. (7, ['img1'1])  



tf.train.batch


tf.train.batch是一个tensor队列生成器,作用是按照给定的tensor顺序,把batch_size个tensor推送到文件队列,作为训练一个batch的数据,等待tensor出队执行计算。

[python]  view plain copy
  1. batch(tensors, batch_size, num_threads=1, capacity=32,  
  2.           enqueue_many=False, shapes=None, dynamic_pad=False,  
  3.           allow_smaller_final_batch=False, shared_name=None, name=None)  
  • 第一个参数tensors:tensor序列或tensor字典,可以是含有单个样本的序列;
  • 第二个参数batch_size: 生成的batch的大小;
  • 第三个参数num_threads:执行tensor入队操作的线程数量,可以设置使用多个线程同时并行执行,提高运行效率,但也不是数量越多越好;
  • 第四个参数capacity: 定义生成的tensor序列的最大容量;
  • 第五个参数enqueue_many: 定义第一个传入参数tensors是多个tensor组成的序列,还是单个tensor;
  • 第六个参数shapes: 可选参数,默认是推测出的传入的tensor的形状;
  • 第七个参数dynamic_pad: 定义是否允许输入的tensors具有不同的形状,设置为True,会把输入的具有不同形状的tensor归一化到相同的形状;
  • 第八个参数allow_smaller_final_batch: 设置为True,表示在tensor队列中剩下的tensor数量不够一个batch_size的情况下,允许最后一个batch的数量少于batch_size, 设置为False,则不管什么情况下,生成的batch都拥有batch_size个样本;
  • 第九个参数shared_name: 可选参数,设置生成的tensor序列在不同的Session中的共享名称;
  • 第十个参数name: 操作的名称;

如果tf.train.batch的第一个参数 tensors 传入的是tenor列表或者字典,返回的是tensor列表或字典,如果传入的是只含有一个元素的列表,返回的是单个的tensor,而不是一个列表。

以下举例: 一共有5个样本,设置迭代次数是2次,每个batch中含有3个样本,不打乱样本顺序:

[python]  view plain copy
  1. # -*- coding:utf-8 -*-  
  2. import tensorflow as tf  
  3. import numpy as np  
  4.   
  5. # 样本个数  
  6. sample_num=5  
  7. # 设置迭代次数  
  8. epoch_num = 2  
  9. # 设置一个批次中包含样本个数  
  10. batch_size = 3  
  11. # 计算每一轮epoch中含有的batch个数  
  12. batch_total = int(sample_num/batch_size)+1  
  13.   
  14. # 生成4个数据和标签  
  15. def generate_data(sample_num=sample_num):  
  16.     labels = np.asarray(range(0, sample_num))  
  17.     images = np.random.random([sample_num, 2242243])  
  18.     print('image size {},label size :{}'.format(images.shape, labels.shape))  
  19.   
  20.     return images,labels  
  21.   
  22. def get_batch_data(batch_size=batch_size):  
  23.     images, label = generate_data()  
  24.     # 数据类型转换为tf.float32  
  25.     images = tf.cast(images, tf.float32)  
  26.     label = tf.cast(label, tf.int32)  
  27.   
  28.     #从tensor列表中按顺序或随机抽取一个tensor  
  29.     input_queue = tf.train.slice_input_producer([images, label], shuffle=False)  
  30.   
  31.     image_batch, label_batch = tf.train.batch(input_queue, batch_size=batch_size, num_threads=1, capacity=64)  
  32.     return image_batch, label_batch  
  33.   
  34. image_batch, label_batch = get_batch_data(batch_size=batch_size)  
  35.   
  36. with tf.Session() as sess:  
  37.     coord = tf.train.Coordinator()  
  38.     threads = tf.train.start_queue_runners(sess, coord)  
  39.     try:  
  40.         for i in range(epoch_num):  # 每一轮迭代  
  41.             print '************'  
  42.             for j in range(batch_total): #每一个batch  
  43.                 print '--------'  
  44.                 # 获取每一个batch中batch_size个样本和标签  
  45.                 image_batch_v, label_batch_v = sess.run([image_batch, label_batch])  
  46.                 # for k in  
  47.                 print(image_batch_v.shape, label_batch_v)  
  48.     except tf.errors.OutOfRangeError:  
  49.         print("done")  
  50.     finally:  
  51.         coord.request_stop()  
  52.     coord.join(threads)  
输出:

[python]  view plain copy
  1. ************  
  2. --------  
  3. ((32242243), array([012], dtype=int32))  
  4. --------  
  5. ((32242243), array([340], dtype=int32))  
  6. ************  
  7. --------  
  8. ((32242243), array([123], dtype=int32))  
  9. --------  
  10. ((32242243), array([401], dtype=int32))  

每次生成的batch中含有3个样本,不打乱次序,所以生成的tensor序列是按照‘0,1,2,3,4,0,1,2,3……’排列的。

如果设置每个batch中含有2个样本,打乱次序,即设置 batch_size = 2, tf.train.slice_input_producer函数中 shuffle=True,输出为:

[python]  view plain copy
  1. ************  
  2. --------  
  3. ((22242243), array([30], dtype=int32))  
  4. --------  
  5. ((22242243), array([41], dtype=int32))  
  6. --------  
  7. ((22242243), array([23], dtype=int32))  
  8. ************  
  9. --------  
  10. ((22242243), array([10], dtype=int32))  
  11. --------  
  12. ((22242243), array([24], dtype=int32))  
  13. --------  
  14. ((22242243), array([14], dtype=int32))  

与tf.train.batch函数相对的还有一个tf.train.shuffle_batch函数,两个函数作用一样,都是生成一定数量的tensor,组成训练一个batch需要的数据集,区别是tf.train.shuffle_batch会打乱样本顺序。

这篇关于tensorflow中 tf.train.slice_input_producer() 函数和 tf.train.batch() 函数的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1054222

相关文章

shell编程之函数与数组的使用详解

《shell编程之函数与数组的使用详解》:本文主要介绍shell编程之函数与数组的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录shell函数函数的用法俩个数求和系统资源监控并报警函数函数变量的作用范围函数的参数递归函数shell数组获取数组的长度读取某下的

MySQL高级查询之JOIN、子查询、窗口函数实际案例

《MySQL高级查询之JOIN、子查询、窗口函数实际案例》:本文主要介绍MySQL高级查询之JOIN、子查询、窗口函数实际案例的相关资料,JOIN用于多表关联查询,子查询用于数据筛选和过滤,窗口函... 目录前言1. JOIN(连接查询)1.1 内连接(INNER JOIN)1.2 左连接(LEFT JOI

MySQL中FIND_IN_SET函数与INSTR函数用法解析

《MySQL中FIND_IN_SET函数与INSTR函数用法解析》:本文主要介绍MySQL中FIND_IN_SET函数与INSTR函数用法解析,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友一... 目录一、功能定义与语法1、FIND_IN_SET函数2、INSTR函数二、本质区别对比三、实际场景案例分

C++ Sort函数使用场景分析

《C++Sort函数使用场景分析》sort函数是algorithm库下的一个函数,sort函数是不稳定的,即大小相同的元素在排序后相对顺序可能发生改变,如果某些场景需要保持相同元素间的相对顺序,可使... 目录C++ Sort函数详解一、sort函数调用的两种方式二、sort函数使用场景三、sort函数排序

C语言函数递归实际应用举例详解

《C语言函数递归实际应用举例详解》程序调用自身的编程技巧称为递归,递归做为一种算法在程序设计语言中广泛应用,:本文主要介绍C语言函数递归实际应用举例的相关资料,文中通过代码介绍的非常详细,需要的朋... 目录前言一、递归的概念与思想二、递归的限制条件 三、递归的实际应用举例(一)求 n 的阶乘(二)顺序打印

C/C++错误信息处理的常见方法及函数

《C/C++错误信息处理的常见方法及函数》C/C++是两种广泛使用的编程语言,特别是在系统编程、嵌入式开发以及高性能计算领域,:本文主要介绍C/C++错误信息处理的常见方法及函数,文中通过代码介绍... 目录前言1. errno 和 perror()示例:2. strerror()示例:3. perror(

Kotlin 作用域函数apply、let、run、with、also使用指南

《Kotlin作用域函数apply、let、run、with、also使用指南》在Kotlin开发中,作用域函数(ScopeFunctions)是一组能让代码更简洁、更函数式的高阶函数,本文将... 目录一、引言:为什么需要作用域函数?二、作用域函China编程数详解1. apply:对象配置的 “流式构建器”最

Android Kotlin 高阶函数详解及其在协程中的应用小结

《AndroidKotlin高阶函数详解及其在协程中的应用小结》高阶函数是Kotlin中的一个重要特性,它能够将函数作为一等公民(First-ClassCitizen),使得代码更加简洁、灵活和可... 目录1. 引言2. 什么是高阶函数?3. 高阶函数的基础用法3.1 传递函数作为参数3.2 Lambda

C++中::SHCreateDirectoryEx函数使用方法

《C++中::SHCreateDirectoryEx函数使用方法》::SHCreateDirectoryEx用于创建多级目录,类似于mkdir-p命令,本文主要介绍了C++中::SHCreateDir... 目录1. 函数原型与依赖项2. 基本使用示例示例 1:创建单层目录示例 2:创建多级目录3. 关键注

C++中函数模板与类模板的简单使用及区别介绍

《C++中函数模板与类模板的简单使用及区别介绍》这篇文章介绍了C++中的模板机制,包括函数模板和类模板的概念、语法和实际应用,函数模板通过类型参数实现泛型操作,而类模板允许创建可处理多种数据类型的类,... 目录一、函数模板定义语法真实示例二、类模板三、关键区别四、注意事项 ‌在C++中,模板是实现泛型编程