当前位置:   article > 正文

TensorFlow. ——数据读取方式_tensorflow 如何读取本地数据

tensorflow 如何读取本地数据

TensorFlow. ——数据读取方式

placehold feed_dict:这是一种常见的方法,在这里不多作讨论,如果一定要使用,尽量在tensorflow里对数据进行预处理会提高效率。
tf.data.Dataset:官方推荐,用tf.data.Dataset读取数据,再用tf内部函数处理数据。

Dataset是创造input pipeline的最佳实践;

  • 第一步:tf.data.Dataset.from_tensor_slices,最好放入文件名列表。
  • 第二步:shuffle:打乱
  • 第三步:map:遍历每一个进行预处理
  • 第四步:batch:得到batch
  • 第五步:得到iterator,batch,Iterator 它提供了主要的方式来从一个dataset中抽取元素。通过Iterator.get_next() 返回的该操作会yields出Datasets中的下一个元素,作为输入pipeline和模型间的接口使用。
    # filename是图片的文件名,label是图片对应的标签
    dataset = tf.data.Dataset.from_tensor_slices((filenames, labels))
    dataset.shuffle(buffer_size=1000) # 如果数据太多,很难完全打乱
    dataset = dataset.map(preprocess)
    dataset = dataset.batch(batch_size=1)
    iterator = tf.compat.v1.data.make_initializable_iterator(dataset)
    batch = iterator.get_next()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
  • tf.data.TextLineDataset():这个函数的输入是一个文件的列表,输出是一个dataset。dataset中的每一个元素就对应了文件中的一行。可以使用这个函数来读入CSV文件。
  • tf.data.FixedLengthRecordDataset():这个函数的输入是一个文件的列表和一个record_bytes,之后dataset的每一个元素就是文件中固定字节数record_bytes的内容。通常用来读取以二进制形式保存的文件,如CIFAR10数据集就是这种形式。
  • tf.data.TFRecordDataset():顾名思义,这个函数是用来读TFRecord文件的,dataset中的每一个元素就是一个TFExample。

注意:Cannot create a tensor proto whose content is larger than 2GB.
从结果很明显可以看出,是一次放入tensor的张量不能超过2G,可是实际中有很多数据集是超过2GB的,所以要么进行一个切分操作:目的是实现将超过2GB的切分到每个小块不超过2G,然后再一个一个处理就行了。最好的方式还是放入文件名,再遍历读取。

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

TensorFlow的Session对象是支持多线程的,可以在同一个会话(Session)中创建多个线程,并行执行。为了充分的利用时间,减少GPU等待的空闲时间,使用了两个线程(文件名队列和内存队列)分别执行数据读入和数据计算。文件名队列源源不断的将硬盘中的图片数据,内存队列负责给GPU送数据,所需数据直接从内存队列中获取。两个线程之间互不干扰,同时运行。
tf.Coordinator和 tf.QueueRunner,这两个类往往一起使用。
在这里插入图片描述

  • tf.train.slice_input_producer():创建一个文件名队列tensor list,文件名队列存放的是参与训练的文件名,要训练N个epoch,则文件名队列中就含有N个批次的所有文件名。然后再对文件进行读取。
    # slice_input_producer 可以生成多维队列(Expected list)
    # string_input_producer会产生一个文件名队列(Expected string and list)
    filename_queue = tf.train.string_input_producer(filename, shuffle=False, num_epochs=1)
    fn_que, fn1_que, lb_que, lb1_que = tf.train.string_input_producer([filename,filename1,label1,label2], shuffle=False, num_epochs=1)
    
    • 1
    • 2
    • 3
    • 4
  • tf.WholeFileReader():图片读取器,批量读取,key表示文件名,value表示读取的内容。注意!!!一定要搭配string_input_producer(),通过文件名批量读取图片,读取后再进行解码,resize,reshape等操作。
     # reader从文件名队列中读数据。对应的方法是reader.read
     reader = tf.WholeFileReader()
     key, value = reader.read(queue)
     # 解码	
     image = tf.image.decode_jpeg(value)
     # resize
     image_resize = tf.image.resize_images(image, [200, 200])
     # reshape
     image_resize.set_shape([200, 200, 3])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
  • tf.train.batch & tf.train.shuffle_batch():作用是按照给定的tensor顺序,把batch_size个tensor推送到文件队列,作为训练一个batch的数据,等待tensor出队执行计算。
    # input_queue可以由解压后的图片和标签构成,输入要是tensor.
    fn_batch, fn1_batch, lb_batch, lb2_batch = tf.train.batch([fn_image,fn1_image, lb_que, lb1_que],batch_size=64,num_threads=1, capacity=64)
          
    
    • 1
    • 2
    • 3
  • tf.train.Coordinator():创建一个线程管理器(协调器)对象。可以用来同时停止多个工作线程并且向那个在等待所有工作线程终止的程序报告异常,该线程捕获到这个异常之后就会终止所有线程。
  • tf.train.start_queue_runners:启动执行文件名队列填充的线程,由多个或单个线程,之后计算单元才可以把数据读出来,否则文件名队列为空的,计算单元就会处于一直等待状态,导致系统阻塞。
    with tf.Session() as sess:
        # 先执行初始化工作
        sess.run(tf.global_variables_initializer())
        sess.run(tf.local_variables_initializer()) # 必要!!
        # 开启一个协调器
        coord = tf.train.Coordinator()
        # 使用start_queue_runners 启动队列填充
        threads = tf.train.start_queue_runners(sess, coord)
        try:
            while not coord.should_stop():
                print('************')
        except tf.errors.OutOfRangeError:  # 如果读取到文件队列末尾会抛出此异常
            print("done! now lets kill all the threads……")
        finally:
            # 协调器coord发出所有线程终止信号
            coord.request_stop() # all threads are asked to stop!
        coord.join(threads)  # 把开启的线程加入主线程,等待threads结束
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
Dataset和queue那个更快:经实验证明,Dataset的速度是queue的1.07倍!!!
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/123834
推荐阅读
相关标签
  

闽ICP备14008679号