这里的写, 指的是把各种格式的数据(如字符, 图片等)统一转换成Tensorflow的标准支持格式TFRecord.
TFRecord是输入数据统一管理的格式, 它其实是一种二进制文件.
写入: 通过将数据填入到tf.train.Example类, Example的protocol buffer包含了字段的tf.train.Features, 使用数据修改Features, 实现将protocol buffer序列化成一个字符串, 再通过tf.python_io.TFRecordWriter类将序列化的字符串写入到TFRecord中.
读出: 使用tf.TFRecordReader读取器, 通过tf.parse_single_example解析器解析, parse_single_example操作可以将Example protocol buffer解析为张量, 然后用解码器 tf.decode_raw解码.
tf.python_io.TFRecordWriter
把记录写入到TFRecords文件的类.
init() ''' 作用: 创建一个TFRecordWriter对象, 将数据记录到指定的TFRecord文件中. 参数: path: (must)TFRecords文件的路径; options: TFRecordOptions对象; ''' write() ''' 作用: 将一条序列化字符串记录写入到文件中. 参数: record: string, 序列化字符串记录. ''' close() ''' 作用: 关闭TFRecordWriter. '''tf.train.Example
Example是使用某种规则规则化后的数据, 通过使用TFRecordWriter写入到TFRecord中.
Example包含一个键值对数据结构(与dict相同), 使用属性features记录, 因此, 初始化时必须传入这个features参数, 它是一个tf.train.Features对象.
init() ''' 作用: 初始化一个Example. 参数: features: tf.train.Features对象, 其中每条记录的key表示数据的描述, value为固定数据类型的特殊处理的数据. ''' SerializeToString() ''' 作用: 把这个Example序列化成字符串, 将这个字符串通过TFRecordWriter写入到TFRecord中. '''tf.train.Features
协议化的描述数据信息, 结构为键值对, key为字符串, 用来描述数据, value为tf.train.Feature对象, 一个Feature包含一种数据类型的list, list中有若干数据.
list有三种: BytesList, FloatList, Int64List
init() ''' 作用: 初始化一个Features 参数: feature: dict字典, key为数据名称, value为tf.train.Feature对象, 特殊的数据list. ''' tf.train.Features(feature={"image_raw":tf.train.Feature(bytes_list=tf.train.BytesList(value=[image_raw])), "label":tf.train.Feature(int64_list=tf.train.Int64List(value=[train_labels_values[i]]))})tf.train.Feature
一个Feature包含一种数据类型的list, list中有若干数据.
list类型主要有BytesList, FloatList, Int64List三种类型
init() ''' 作用: 初始化一个Feature, 内含数据队列. 参数: bytes_list: 队列数据为byte(一般是字符串)时使用, 将tf.train.BytesList赋给此参数; float_list: 队列数据为float时使用, 将tf.train.FloatList赋给此参数; int64_list: 队列数据为int64时使用, 将tf.train.Int64List赋给此参数. ''' tf.train.Feature(int64_list = tf.train.Int64List(value = [value])) tf.train.Feature(bytes_list = tf.train.BytesList(value = [value])) tf.train.Feature(float_list = tf.train.FloatList(value = [value]))tf.train.BytesList, tf.train.FloatList, tf.train.Int64List
字符, 浮点, 整形三种数据队列
''' 作用: 初始化一个类型的队列, 传入数据 参数: value: 将相应类型的数据放在list中, 赋值给此参数 '''这里使用Kaggle中Getting Started级别的Digit Recognizer题目, 数据是MNIST手写数字的csv格式, 这里使用train.csv作为例子, 实现将csv文件转换为TFRecord的操作.
import numpy as np import pandas as pd import tensorflow as tf train_frame=pd.read_csv(filepath_or_buffer="train.csv") train_labels_frame=train_frame.pop(item="label") train_values=train_frame.values train_labels_values=train_labels_frame.values train_size=train_values.shape[0] writer=tf.python_io.TFRecordWriter(path="train.tfrecords") for i in range(train_size): image_raw=train_values[i].tostring() example=tf.train.Example( features=tf.train.Features( feature={ "image_raw":tf.train.Feature(bytes_list=tf.train.BytesList(value=[image_raw])), "label":tf.train.Feature(int64_list=tf.train.Int64List(value=[train_labels_values[i]])) } ) ) writer.write(record=example.SerializeToString()) writer.close()Tensorflow中, 有三种主要的读取数据文件的读写器类, 有共用的操作文件的Ops.
tf.TextLineReader 用于读取csv文件, 配合tf.decode_csv()方法使用; tf.FixedLengthRecordReader 用于读取二进制编码文件, 配合tf.decode_raw()解码器方法使用; tf.TFRecordReader 用于读取TFRecord文件, 配合tf.parse_single_example()解析器和tf.decode_raw()解码器方法使用.
三个类均继承于父类tf.ReaderBase, 常用的方法有:
read()
使用例子见Tensorflow: 队列操作章节中最后的读取数据的例子.
使用例子:
filename_queue = tf.train.string_input_producer(["file0.csv", "file1.csv"]) reader = tf.TextLineReader() key, value = reader.read(filename_queue) # Default values, in case of empty columns. Also specifies the type of the # decoded result. record_defaults = [[1], [1], [1], [1], [1]] col1, col2, col3, col4, col5 = tf.decode_csv( value, record_defaults=record_defaults) features = tf.concat(0, [col1, col2, col3, col4]) with tf.Session() as sess: # Start populating the filename queue. coord = tf.train.Coordinator() threads = tf.train.start_queue_runners(coord=coord) for i in range(1200): # Retrieve a single instance: example, label = sess.run([features, col5]) coord.request_stop() coord.join(threads)每次read的执行都会从文件中读取一行内容, decode_csv() 操作会解析这一行内容并将其转为张量列表. 如果输入的参数有缺失, record_default参数可以根据张量的类型来设置默认值.
使用例子
def read_and_decode(filename): #根据文件名生成一个队列 filename_queue = tf.train.string_input_producer([filename]) reader = tf.TFRecordReader() _, serialized_example = reader.read(filename_queue) #返回文件名和文件 features = tf.parse_single_example(serialized_example, features={ 'label': tf.FixedLenFeature([], tf.int64), 'img_raw' : tf.FixedLenFeature([], tf.string), }) img = tf.decode_raw(features['img_raw'], tf.uint8) img = tf.reshape(img, [224, 224, 3]) img = tf.cast(img, tf.float32) * (1. / 255) - 0.5 label = tf.cast(features['label'], tf.int32) return img, label