TensorFlow--IO操作
- TensorFlow 异步IO操作的原理
- 如下如, 文件对列用来存储需要读取文件或者文本, 阅读器用来不断从对列中获取文件进行内容的读取, Deoder用来对读取出来的内容进行解码, 结果对列用来存储读取的结果
- IO操作是真正的多线程(异步)
- 操作流程如下图
- IO操作是怎么实现异步的
- 当数据量很大时,入队操作从硬盘中读取数据,放入内存中,主线程需要等待入队操作完成,才能进行训练。会话里可以运行多个线程,实现异步读取。
TensorFlow--队列
- 队列的创建
- Q = tf.FIFOQueue(capacity, dtypes, name="fifo_queue") 创建先进先出的对列,按照顺序出对列
- capacity: 整数, 对列的容量
- dtypes: dtype 数据类型
- tf.RandomShuffleQueue() 创建随机出队的对列
- 队列的操作
- Q.dequeue() 出列操作
- Q.enqueue(vals) 单个元素入队
- Q.enqueue_many(vals) 多个元素入队
- vals: 列表或者元组, 包含需要入队的元素
- Q.size() 返回一个tensor类型的对象, value是对列的大小
- 使用示例
TensorFlow--对列管理器
- 队列管理器的作用
- 当直接通过对列的方法向队列中添加数据的时候, 需要等待数据添加完成才能执行下一步操作, 这样的操作不是异步的
- 当我们想一边自动的向对列中添加数据, 一边进行其他的操作的时候, 我们可以使用对列管理器
- 其会自动的绑定对列和一些对对列的操作, 并另外开启线程执行绑定的操作
- 对列管理器的创建
- qr = tf.train.QueueRunner(queue, enqueue_ops=None) 创建对列管理器
- queue: 绑定到对列管理器的对列
- enqueue_ops: 代表对列操作列表,每个操作会创建一个子线程来执行
- 创建线程让对列管理器执行
- thd = qr.create_threads(sess, coord=None, start=False) 创建线程来执行队列管理器绑定的方法
- start: True, 直接启动队列管理器线程。False, 需要手动调用start来让线程运行
- coord:线程协调器
- return: 返回线程对象
- 线程资源问题的解决
- 问题:
- 当在会话中开启线程的时候, 当使用with方式开启线程并执行后, 当主线程结束后, 由于with方式开启会话会对资源进行回收
- 这时候子线程失去会话资源, 会导致程序崩溃
- 解决方法
- 使用线程协调器
TensorFlow--线程协调器
- 线程协调器的作用
- 实现一个简单的机制来协调一组线程的终止阻塞等操作
- 创建线程协调器
- coord = tf.train.Coordinator() 创建线程斜体其起
- 线程协调器的方法
- coord.request_stop() 终止绑定在线程协调器的所有线程
- coord.should_stop() 检查是否满足停止条件,如果满足便退出线程
- coord.join(threads=None) 阻塞等待线程结束
- 使用代码示例
文件读取
- 文件队列的创建
- tf.train.string_input_producer(string_tensor, num_opochs=None, shuffle=True) 创建文件队列,用来存储即将操作的文件
- string_tensor: 含有文件名的1阶张量
- num_epochs: 过几遍数据,默认无限过数据
- return: 输出字符串的队列
- 文件队列线程开启操作
- 作用:开启线程创建图中定义的对列,并将设置的待读取内容读取到对列中
- thd = tf.train.start_queue_runners(sess=None,coord=None, start=True)
- sess: 所在的会话中
- coord:线程协调器
- start: 是否直接开启线程
- 管道读取批量处理
- 作用
- 可以每次批量的进行文件内容的读取
- 原理是会创建一个批处理对列,
- 当读取文件内容的时候, 批处理对列会预先从文件对列中选取文件,读取内容将对列填满
- 然后根据设定的batch_size, 返回对列中的内容
- 当内容取出后, 再从读取文件将对列填满, 等待下一次的读取
- 使用方法
- tf.train.batch(tensors, batch_size, num_threads=1, capacity=32, name=None) 读取指定大小(个数)的张量
- tensors:可以是包含张量的列表
- batch_size:从队列中读取的批处理大小
- num_threads:进入队列的线程数
- capacity:整数,队列中元素的最大数量
- return: tensors, 读取到内容的数组
- tf.train.shuffle_batch(tensors, batch_size, capacity, min_after_dequeue, num_threads=1) 乱序读取指定大小(个数)的张量
- min_after_dequeue:留下队列里的张量个数,能够保持随机打乱
- 注意:批处理接收的tensow对象必须都是规定了shape,并且统一的对象
- 文件阅读器创建
- 文本阅读器
- Reader = tf.TextLineReader()
- 阅读文本,默认按行读取, 默认分隔符为,
- 二进制文件阅读器
- Reader = tf.FixedLengthRecordReader(record_bytes)
- 阅读二进制文件,可以指定每次读取的字节数
- record_bytes:整型,指定每次读取的字节数
- TFRecord文件阅读器
- Reader = tf.TFRecordReader()
- 读取TfRecords文件
- 图片阅读器
- Reader = tf.WholeFileReader()
- 图片阅读器
- 文件阅读器的方法
- Reader.read(file_queue) 从队列中读取指定数量的内容
- 返回一个Tensors元组(key文件名字,value默认的内容(行或者字节或者图片), tensow类型)
- 文件内容解码器
- 文本文件解码器
- tf.decode_csv(records, record_defaults=None, field_delim = None, name = None)
- 由于从文件中读取的是字符串,需要函数去解析这些字符串到张量
- record_defaults: 字段的默认值,比如[[1],[],['string']],不指定类型(设为空[])也可以
- field_delim: 默认分割符”,”
- records: tensor型字符串,每个字符串是csv中的记录行
- 二进制文件解码器
- tf.decode_raw(bytes, out_type, little_endian=None, name = None)
- 将字符串类型的二进制数据, 转换为uint8 或者int32类型的数据
- 与函数tf.FixedLengthRecordReader搭配使用,将字符串表示的二进制读取为uint8格式
- bytes: 读取到的bytes字节内容
- out_type: 读取后输出的类型
- 图片文件解码器
- 解码方法
- tf.image.decode_jpeg(content, out_type)
- 配合tf.WholiFileReader 使用,
- 将JPEG编码的图像解码为uint8张量
- return:uint8张量,3-D形状[height, width, channels]
- tf.image.decode_png(contents, out_type)
- 将PNG编码的图像解码为uint8或uint16张量
- return:张量类型,3-D形状[height, width, channels]
- 图片的基本操作api
- tf.image.resize_images(images, size) 更改图片尺寸(只能更改尺寸, 不能更改通道)
- images:4-D形状[batch, height, width, channels]或3-D形状的张量[height, width, channels]的图片数据
- size:1-D int32张量:new_height, new_width,图像的新尺寸
- return: 返回4-D格式或者3-D格式图片的tensow类型,并且tensow对象的shape对应通道数为? 不固定类型
- TFRecords文件解码器
- feature = tf.parse_single_example(value,features={
- "image": tf.FixedLenFeature([], tf.string),
- "label": tf.FixedLenFeature([], tf.int64)
- }) 根据协议将TFRecords的内容转化为feature
- image = feature['image'] 通过feature可以读取里面的特征值
- label = feature['label']
- 文件存储器(TFRecords文件存储器)
- 建立TFRecord存储器
- Saver = tf.python_io.TFRecordWriter(path) 建立存储器
- path: TFRecords文件存储的路径
- 存储器的方法
- write(record): 向文件中写入一个字符串记录(下面介绍)
- close(): 关闭文件写入器
- TFRecords存储的字符串记录
- 构造样本的Example协议块
- example = tf.train.Example(features=None) 创建协议块
- features: tf.train.Features类型的特征实例
- feature 特征实例的创建
- feature 的创建
- feature = tf.train.Features(feature=None) 构建每个样本的信息键值对
- feature: 字典数据, key为要保存的名字,value为tf.train.Feature实例
- feature的value的创建
- tf.train. Int64List(value=[Value])
- tf.train. BytesList(value=[Bytes])
- tf.train. FloatList(value=[value])
- TFRecords的字符串记录创建实例
- example = tf.train.Example(features=tf.train.Features(feature={
- "image": tf.train.Feature(bytes_list=tf.train.BytesList(value=[image])),
- "label": tf.train.Feature(int64_list=tf.train.Int64List(value=[label]))
- }))
- 文本文件读取代码示例
- 图片文件的读取示例
- 二进制文件读取示例
- TFRecords文件存储示例
- TFRecords文件读取示例