reader: 适用于原始数据数据形式的Tensorflow Reader

  在库中parallel_reader.py是与reader相关的,它使用多个reader并行处理来提高速度,但文件中定义的类是继承自基类,所以我们先看基类的功能。

class ParallelReader(io_ops.ReaderBase):

基类

  基类是各种不同类型reader的基类,它将'work unit'转换为record,比较典型的’work unit'是文件名,records(键值对形式)就是从这些文件中提取的内容。我们想要每一步只产生一个record,但是显然一个'work unit'可能对应多个record,所以我们需要一个存储'work unit'的queue,只有reader读取完一个‘work unit'中所有record之后,它才能获取下一个'work unit'。

  基类首先使用了一个装饰器,装饰器的主要功能是输出装饰的函数到TF的api,装饰的函数功能不受影响,所以我们可以不用关注它。

@tf_export("ReaderBase")
class ReaderBase(object):

  基类初始化函数检查是否支持eager execution,初始化类变量。

def __init__(self, reader_ref, supports_serialize=False):
    if context.executing_eagerly():
      raise RuntimeError(
          "Readers are not supported when eager execution is enabled. "
          "Instead, please use tf.data to get data into your model.")

    self._reader_ref = reader_ref #实现reader的op
    self._supports_serialize = supports_serialize #reader是否支持序列化状态

  read函数会返回一个record。

def read(self, queue, name=None):
    if isinstance(queue, ops.Tensor):
      queue_ref = queue
    else:
      queue_ref = queue.queue_ref
    if self._reader_ref.dtype == dtypes.resource:
      return gen_io_ops.reader_read_v2(self._reader_ref, queue_ref, name=name)
    else:
      # For compatibility with pre-resource queues, create a ref(string) tensor
      # which can be looked up as the same queue by a resource manager.
      old_queue_op = gen_data_flow_ops.fake_queue(queue_ref)
      return gen_io_ops.reader_read(self._reader_ref, old_queue_op, name=name)

  read_up_to函数返回指定数量的records。

def read_up_to(self, queue, num_records, name=None):
    if isinstance(queue, ops.Tensor):
      queue_ref = queue
    else:
      queue_ref = queue.queue_ref
    if self._reader_ref.dtype == dtypes.resource:
      return gen_io_ops.reader_read_up_to_v2(self._reader_ref,
                                             queue_ref,
                                             num_records,
                                             name=name)
    else:
      # For compatibility with pre-resource queues, create a ref(string) tensor
      # which can be looked up as the same queue by a resource manager.
      old_queue_op = gen_data_flow_ops.fake_queue(queue_ref)
      return gen_io_ops.reader_read_up_to(self._reader_ref,
                                          old_queue_op,
                                          num_records,
                                          name=name)

  num_records_produced函数返回已经产生的record数量。

def num_records_produced(self, name=None):
    if self._reader_ref.dtype == dtypes.resource:
      return gen_io_ops.reader_num_records_produced_v2(self._reader_ref,
                                                       name=name)
    else:
      return gen_io_ops.reader_num_records_produced(self._reader_ref,
                                                    name=name)

  num_work_units_completed函数返回已经完成的work units数量。

def num_work_units_completed(self, name=None):
    if self._reader_ref.dtype == dtypes.resource:
      return gen_io_ops.reader_num_work_units_completed_v2(self._reader_ref,
                                                           name=name)
    else:
      return gen_io_ops.reader_num_work_units_completed(self._reader_ref,
                                                        name=name)

  serialize_state函数产生编码reader状态的一个string tensor。

def serialize_state(self, name=None):
    if self._reader_ref.dtype == dtypes.resource:
      return gen_io_ops.reader_serialize_state_v2(self._reader_ref, name=name)
    else:
      return gen_io_ops.reader_serialize_state(self._reader_ref, name=name)

  restore_state函数将reader状态加载为指定状态。

def restore_state(self, state, name=None):
    if self._reader_ref.dtype == dtypes.resource:
      return gen_io_ops.reader_restore_state_v2(
          self._reader_ref, state, name=name)
    else:
      return gen_io_ops.reader_restore_state(self._reader_ref, state, name=name)

  reset_state函数将reader状态重置。

def reset(self, name=None):
    if self._reader_ref.dtype == dtypes.resource:
      return gen_io_ops.reader_reset_v2(self._reader_ref, name=name)
    else:
      return gen_io_ops.reader_reset(self._reader_ref, name=name)

  还有supports_serialize函数和reader_ref函数则是返回相应类变量,至此基类中所有的函数都已经介绍完毕,可以看到,主要实现reader功能的是reader函数,其他函数则是查看reader状态。(由于gen_io_ops为c++代码实现,这里不予介绍。)

Parallel_reader

  Parallel_reader是并行使用多个reader提高速度,它的构造函数利用参数构造多个reader,每个reader并行地读取不同的文件,异步地将文件入队到队列(common_queue)中。对列中dtypes必须是[tf.string, tf.string]。

def __init__(self,
               reader_class,
               common_queue,
               num_readers=4,
               reader_kwargs=None):
    if len(common_queue.dtypes) != 2:
      raise TypeError('common_queue.dtypes must be [tf.string, tf.string]')
    for dtype in common_queue.dtypes:
      if not dtype.is_compatible_with(tf_dtypes.string):
        raise TypeError('common_queue.dtypes must be [tf.string, tf.string]')

    reader_kwargs = reader_kwargs or {}
    self._readers = [reader_class(**reader_kwargs) for _ in range(num_readers)]
    self._common_queue = common_queue

  read函数用QueueRunner执行入队操作后,再从队列中返回一个record。

def read(self, queue, name=None):
    self._configure_readers_by(queue)
    return self._common_queue.dequeue(name=name)

  read_up_to函数是返回多个record。

def read_up_to(self, queue, num_records, name=None):
    self._configure_readers_by(queue)
    return self._common_queue.dequeue_up_to(num_records, name)

def _configure_readers_by(self, queue):
    enqueue_ops = []
    for reader in self._readers:
      enqueue_ops.append(self._common_queue.enqueue(reader.read(queue)))

    queue_runner.add_queue_runner(
        queue_runner.QueueRunner(self._common_queue, enqueue_ops))

  num_records_produced函数和num_work_units_completed函数,这两个函数功能和基类中同名函数一样。

def num_records_produced(self, name=None):
    num_records = [r.num_records_produced() for r in self._readers]
    return math_ops.add_n(num_records, name=name)

def num_work_units_completed(self, name=None):
    num_work_units = [r.num_work_units_completed() for r in self._readers]
    return math_ops.add_n(num_work_units, name=name)

  num_readers函数和common_queue函数则是返回相关属性,至此Parallel_reader函数中所有函数就全部介绍完了,可以看出它的主要作用只是对多个reader的工作使用多线程处理。

                                                     最新一次编辑在:21:36:28 2018-07-16     

tf.contrib.slim.data数据加载(1) reader的更多相关文章

  1. tf.contrib.slim.data数据加载 综述

    TF-Slim为了方便加载各种数据类型(如TFRocords或者文本文件)的数据,创建了这个库. Dataset 这里的数据库与通常意义下数据库是不同的,这里数据库是python一个类,它负责将原始数 ...

  2. iOS教程:如何使用Core Data – 预加载和引入数据

    这是接着上一次<iOS教程:Core Data数据持久性存储基础教程>的后续教程,程序也会使用上一次制作完成的. 再上一个教程中,我们只做了一个数据模型,之后我们使用这个数据模型中的数据创 ...

  3. spark SQL(三)数据源 Data Source----通用的数据 加载/保存功能

    Spark SQL 的数据源------通用的数据 加载/保存功能 Spark SQL支持通过DataFrame接口在各种数据源上进行操作.DataFrame可以使用关系变换进行操作,也可以用来创建临 ...

  4. Tensorflow 2.0 datasets数据加载

    导入包 import tensorflow as tf from tensorflow import keras 加载数据 tensorflow可以调用keras自带的datasets,很方便,就是有 ...

  5. tensorflow学习--数据加载

    文章主要来自Tensorflow官方文档,同时加入了自己的理解以及部分代码 数据读取 TensorFlow程序读取数据一共有3种方法: 供给数据(Feeding): 在TensorFlow程序运行的每 ...

  6. python多种格式数据加载、处理与存储

    多种格式数据加载.处理与存储 实际的场景中,我们会在不同的地方遇到各种不同的数据格式(比如大家熟悉的csv与txt,比如网页HTML格式,比如XML格式),我们来一起看看python如何和这些格式的数 ...

  7. flask+sqlite3+echarts3+ajax 异步数据加载

    结构: /www | |-- /static |....|-- jquery-3.1.1.js |....|-- echarts.js(echarts3是单文件!!) | |-- /templates ...

  8. 浅谈Entity Framework中的数据加载方式

    如果你还没有接触过或者根本不了解什么是Entity Framework,那么请看这里http://www.entityframeworktutorial.net/EntityFramework-Arc ...

  9. 实现虚拟模式的动态数据加载Windows窗体DataGridView控件 .net 4.5 (一)

    实现虚拟模式的即时数据加载Windows窗体DataGridView控件 .net 4.5 原文地址 :http://msdn.microsoft.com/en-us/library/ms171624 ...

随机推荐

  1. 路径规划算法之Bellman-Ford算法

    最近由于工作需要一直在研究Bellman-Ford算法,这也是我第一次用C++编写代码. 1.Bellman-Ford算法总结 (1)Bellman-Ford算法计算从源点(起始点)到任意一点的最短路 ...

  2. VS发布网站时,报错提示:“未能将文件xxx复制到xxx,未能找到文件xx”三种解决方案!

    发布网站时候大家可能会遇到这样的情况,就是报错提示说:“未能将文件xxx复制到xxx,未能找到文件xx”,这个问题一般来说有三种解决方案,个人倾向第三种,如图: 解决方案如下: 方案一.把系统提示缺失 ...

  3. C++变量/函数命名规范

    ## 参照Google C++编程规范之变量命名 1. 变量 变量名一律小写,单词间以下划线相连.类的成员变量以下划线结尾. 普通变量命名 举例: string window_name; // OK ...

  4. 切换npm源地址

    全局安装nrm (npm源管理工具) npm install -g nrm 查看所有的源地址   * 代表当前的源地址 nrm ls * npm ----- https://registry.npmj ...

  5. Consumer高级特性

    Queue队列的消息一般是按照顺序各个队列依次获取消息,每次获取一个.所以假设有两个队列queue1,queue2,发送的消息为1.2.3.4.5.则默认情况下queue1获取到的消息为1.3.5,q ...

  6. 论文笔记:Image Smoothing via L0 Gradient Minimization

    今天要分享的这篇论文是我个人最喜欢的论文之一,它的思想简单.巧妙,而且效果还相当不错.这篇论文借助数学上的 \(L_0\) 范数工具对图像进行平滑,同时保留重要的边缘特征,可以实现类似水彩画的效果(见 ...

  7. sql 常见错误总结

    1.根据一张表更新另一张表的数据. . 写法轻松,更新效率高: update table1 set field1=table2.field1, field2=table2.field2 from ta ...

  8. Centos6.8安装php5.6

    检查当前安装的PHP包 yum list installed | grep php 如果有安装的PHP包,先删除他们, 如: yum remove php.x86_64 php-cli.x86_64 ...

  9. 深度探索C++对象模型

    深度探索C++对象模型 什么是C++对象模型: 语言中直接支持面向对象程序设计的部分. 对于各个支持的底层实现机制. 抽象性与实际性之间找出平衡点, 需要知识, 经验以及许多思考. 导读 这本书是C+ ...

  10. Laravel-google-authenticator--Google验证码

    开发前的准备 安装Laravel 安装二维码生成器QrCode,没有安装也可以,接下来会安装 安装拓展 1.运行如下代码安装拓展包: composer require "earnp/lara ...