tensorflow读取mysql_TensorFlow读取数据的三种方法

本文详细介绍了TensorFlow中三种数据读取方法:placehold喂补数据,queue队列利用多线程提高效率,以及Dataset API的使用,包括无限循环读取和数据预处理。通过实例展示了如何从内存、硬盘读取数据,并讨论了批处理、数据打乱和数据重复的重要性和方法。
摘要由CSDN通过智能技术生成

placehold feed_dict:从内存中读取数据,占位符填充数据

queue队列:从硬盘读取数据

Dataset:同时支持内存和硬盘读取数据

placehold-feed_dict

先用placehold 占位数据,在Graph中读取数据,数据直接内嵌到Graph中,然后当Graph传入Session是,用feed_dict喂补数据。当数据量比较大的时候,Graph的传输会遇到效率底下问题,特别是数据转换。

importtensorflow as tfimportlibrosa#把数据加载在Graph中

x1 = librosa.load("temp_1.wav", sr=16000)

x2= librosa.load("temp_2.wav", sr=16000)

y=tf.add(x1, x2)

with tf.Session() as sess:print(sess.run(y))

queue队列

如果我们的数据读取算法没有设计多线程的话(即单线程),由于读取数据和处理数据在同一个进程是有先后关系的,意味着数据处理完后必须花时间读取数据,然后才能进行计算处理。这样的一来GPU并没有高效的专一做一件事情,从而大大的降低的效率,queue创建多线程彻底的解决了这个问题。

tensorflow中为了充分的利用时间,减少GPU等待的空闲时间,使用了两个线程(文件名队列和内存队列)分别执行数据读入和数据计算。文件名队列源源不断的将硬盘中的图片数据,内存队列负责给GPU送数据,所需数据直接从内存队列中获取。两个线程之间互不干扰,同时运行。

7999897ed7c54d77f0b11495e1dceb8e.png

因此 tensorflow 在内存队列之前,还要使用tf.train.slice_input_producer函数,创建一个文件名队列,文件名队列存放的是参与训练的文件名,要训练N个epoch,则文件名队列中就含有N个批次的所有文件名。

tf.train.slice_in put_producer()

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

slice_input_producer(tensor_list,

num_epochs=None,

shuffle=True,

seed=None,

capacity=32,

shared_name=None,

name=None)

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

参数:

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:队列容量的大小,为整数

shared_name:可选参数,如果设置一个"shared_name",则在不同的上下文Session中可以通过这个名字共享生成的tensor

name:设置操作的名称

如果tensor_list=[data, lable],其中data.shape=(4000,10),label.shape=[4000,2],则生成器生成的第一个队列

input_quenue[0].shape=(10,)

input_quenue[1].shape=(2,)

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

importtensorflow as tf

images= ["img1", "img2", "img3", "img4", "img5"]

labels= [1, 2, 3, 4, 5]

epoch_num= 8

#文件名队列

input_queue = tf.train.slice_input_producer([images, labels], num_epochs=None, shuffle=False)

with tf.Session() as sess:

sess.run(tf.global_variables_initializer())

coord= tf.train.Coordinator() #创建一个协调器,管理线程

#启动QueueRunner, 执行文件名队列的填充

threads = tf.train.start_queue_runners(sess=sess, coord=coord)for i inrange(epoch_num):

k=sess.run(input_queue)print(i, k)#0[b'img1', 1]

#1[b'img2', 2]

#2[b'img3', 3]

#3[b'img4', 4]

#4[b'img5', 5]

#5[b'img1', 1]

#6[b'img2', 2]

#7[b'img3', 3]

coord.request_stop()

coord.join(threads)

tf.train.batch & tf.train.shuffle_batch()

tf.train.batch(

tensors_list,

batch_size,

num_threads=1,

capacity=32,

enqueue_many=False,

shapes=None,

dynamic_pad=False,

allow_smaller_final_batch=False,

shared_name=None,

name=None

)

tf.train.batch & tf.train.shuffle_batch()这两个函数的参数是一样的,下面我以tf.train.batch讲解为例

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

tensors:一个列表或字典的tensor用来进行入队

batch_size: 每次从队列中获取出队数据的数量

num_threads:用来控制入队tensors线程的数量,如果num_threads大于1,则batch操作将是非确定性的,输出的batch可能会乱序

capacity: 设置队列中元素的最大数量

enqueue_many: 在第一个参数tensors中的tensor是否是单个样本

shapes: 可选,每个样本的shape,默认是tensors的shape

dynamic_pad: Boolean值;允许输入变量的shape,出队后会自动填补维度,来保持与batch内的shapes相同

allow_smaller_final_batch: 设置为True,表示在tensor队列中剩下的tensor数量不够一个batch_size的情况下,允许最后一个batch的数量少于batch_size进行出队, 设置为False,小于batch_size的样本不会做出队处理

shared_name: 可选参数,设置生成的tensor序列在不同的Session中的共享名称;

name: 操作的名称;

以下举例: 一共有5个样本,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值