Tensorflow: 文件读写

xiaoxiao2021-02-28  89

写文件

这里的写, 指的是把各种格式的数据(如字符, 图片等)统一转换成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中, 赋值给此参数 '''

生成TFRecord例子

读取csv文件, 并转为TFRecord

这里使用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()

读取图片, 转换为TFRecord格式

from PIL import Image # 这里使用PIL包读取图片 def _int64_feature(value): return tf.train.Feature(int64_list = tf.train.Int64List(value = [value])) def _bytes_feature(value): return tf.train.Feature(bytes_list = tf.train.BytesList(value = [value])) def convert_to(data_path, name): rows = 64 cols = 64 depth = DEPTH for ii in range(12): writer = tf.python_io.TFRecordWriter(name + str(ii) + '.tfrecords') for img_name in os.listdir(data_path)[ii*16384 : (ii+1)*16384]: img_path = data_path + img_name img = Image.open(img_path) h, w = img.size[:2] j, k = (h - OUTPUT_SIZE) / 2, (w - OUTPUT_SIZE) / 2 box = (j, k, j + OUTPUT_SIZE, k+ OUTPUT_SIZE) img = img.crop(box = box) img = img.resize((rows,cols)) img_raw = img.tobytes() example = tf.train.Example(features = tf.train.Features(feature = { 'height': _int64_feature(rows), 'weight': _int64_feature(cols), 'depth': _int64_feature(depth), 'image_raw': _bytes_feature(img_raw)})) writer.write(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()

FixedLengthRecordReader

init() ''' 作用: 生成一个每次读取固定长度数据的读取器. 参数: record_bytes: (must)整数, 固定的读取长度; header_bytes: 整数, 头数据长度, 默认为0; footer_bytes: 整数, 尾数据长度, 默认为0; name: Op的名字; '''

使用例子见Tensorflow: 队列操作章节中最后的读取数据的例子.

TextLineReader

init() ''' 作用: 生成一个每次读取一行内容的读取器 参数: skip_header_lines: 整数, 需要跳过的头行数, 默认为0; name: Op的名称. '''

使用例子:

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参数可以根据张量的类型来设置默认值.

TFRecordReader

init() ''' 作用: 生成一个每次从TFRecord中读取一个Features数据的读取器 参数: name: Op的名称; options: TFRecordOptions; '''

使用例子

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

辅助读取文件数据的函数

tf.decode_csv() ''' 作用: 将读取的csv记录(字符串)解析并转换成Tensor, csv文件中的每一列将会对应一个Tensor. 参数: records: (must)string类型的Tensor, 里面每个string代表csv中的一行, 代表一条记录; record_defaults: (must)list of Tensor, 每个Tensor对应一列, 当列中的数据为空时, 使用对应的Tensor填补输出结果; field_delim: string, 指明一条记录(一行)之间各列的分界符, 默认为','; name: op的名称. 输出: list of tensor, list长度与record_defaults相同, 各个tensor的shape相同. ''' tf.decode_raw() ''' 作用: 将bytes of string转换为指定类型的数据. 参数: bytes: (must)string类型的Tensor, 所有的元素长度相同; out_type: (must)指明输出数据的类型, tf.DType; little_endian: (不明)bool, 默认为True, 无视out_type参数, 将数据转为单字节格式, 类似uint8; name: op的名称. 输出: out_type类型的Tensor, 维度比bytes入参Tensor多一维; 多出的一维的值等于将bytes中单个string元素, 用out_type分割后产生的数据的长度. ''' tf.parse_single_example() ''' 作用: 将一个Example proto 转为features指定格式的key: Tensor数据. 参数: serialized: (must)只含一条string元素的Tensor, 代表一条序列化的Example数据; features: (must)dict, 类似于存储时的features, key为字符串描述, 但value为tf.FixedLenFeature对象. name: op的名称; example_names: 只含一条string元素的Tensor, 表示Example的名称. 输出: dict, key为features参数中的key, value为转换出来的Tensor, 类型为string. ''' tf.FixedLenFeature ''' 作用: 固定长度Feature(tf.train.Feature)解析配置类, 用来描述Feature的属性, 以供tf.parse_single_example()方法解析. 参数: (继承于collections.namedtuple("FixedLenFeature",["shape", "dtype", "default_value"])类.) 第一: 数据的shape, 指定为[], 表示不指明; 第二: 数据的类型dtype, tf.DType; 第三: 数据缺失时默认的填补数据default_value, 必须与shape和dtype适应. ''' tf.FixedLenFeature([], tf.int64) tf.FixedLenFeature([], tf.string)
转载请注明原文地址: https://www.6miu.com/read-47380.html

最新回复(0)