TensorflowIO操作

队列和线程

队列:

FIFOQueue(capacity, dtypes, name=‘fifo_queue’)

创建一个以先进先出的顺序对元素进行排队的队列

capacity:整数,可能存储在此队列中的元素数量的上限

dtypes:DType对象列表。长度dtypes必须等于每个队列元素中的张量数,dtype的类型形状决定了后面进队列元素形状。

方法:

dequeue(name=None):出队列

enqueue(vals, name=None):进队列

enqueue_many(vals, name=None)----vals列表或者元组

size(name=None):队列大小

例:完成一个出队列、+1、入队列操作(同步操作):

import tensorflow as tf
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'

# 模拟完成一个出队列、+1、入队列操作(同步操作)
# 1.定义队列
Q = tf.FIFOQueue(3,tf.float32)
# 放入一些数据
enq_many = Q.enqueue_many([[1,2,3]])
# 2.定义读取数据,存数据的过程
out_q = Q.dequeue()
data = out_q + 1
en_q = Q.enqueue(data)

with tf.Session() as sess:
    # 初始化队列
    sess.run(enq_many)
    # 处理数据
    for i in range(10):
        # tensorflow当中,运行操作有依赖性
        sess.run(en_q)
    # 训练数据
    for i in range(Q.size().eval()):
        print(sess.run(Q.dequeue()))

队列管理器:

tf.train.QueueRunner(queue, enqueue_ops=None)----创建一个队列管理器(子线程)

queue:队列

enqueue_ops:添加线程的队列操作列表,[]*2,指定两个线程

create_threads(sess, coord=None,start=False) ----真正开启子线程(在会话中)

start:布尔值,如果True启动线程;如果为False调用者必须调用start()启动线程

coord:线程协调器

return:队列管理器实例

线程协调器:

tf.train.Coordinator() 线程协调员,实现一个简单的机制来协调一组线程的终止

方法:

request_stop() :要求停止

should_stop() 检查是否要求停止

join(threads=None, stop_grace_period_secs=120) 等待线程终止

return:线程协调员实例

例:通过队列管理器来实现变量加1,入队,主线程出队列的操作(异步操作):

import tensorflow as tf
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'

# 通过队列管理器模拟 子线程存入样本 主线程读取样本的操作(异步操作)
# 1.定义一个队列
Q = tf.FIFOQueue(1000,tf.float32)
# 2.定义要做的事情 循环 值+1,放入队列中
var = tf.Variable(0.0)
# 实现一个自增 tf.assign_add() 即 data = var + 1.0  var = var + 1.0
data = tf.assign_add(var,tf.constant(1.0))
en_q = Q.enqueue(data)
# 3.定义队列管理器op,指定多少个子线程,子线程该干什么
qr = tf.train.QueueRunner(Q,enqueue_ops=[en_q])
# 初始化变量的OP
init_op = tf.global_variables_initializer()

with tf.Session() as sess:
    # 初始化变量
    sess.run(init_op)
    # 开启线程协调器
    coord = tf.train.Coordinator()
    # 真正开启子线程
    threads = qr.create_threads(sess,coord= coord,start=True)
    # 主线程,不断读取数据训练
    for i in range(300):
        print(sess.run(Q.dequeue()))
    # 回收子线程
    coord.request_stop()
    coord.join(threads)

文件读取

tensorflow文件读取流程:

1)构造一个文件队列

2)构造文件阅读器,读取队列内容

2.1)csv文件:每次读取一行 2.2)二进制文件:指定一个样本的bytes读取 2.3)图片文件:一张一张读取

3)解码 decode

4)批处理

文件读取API:

1)文件队列构造:

tf.train.string_input_producer(string_tensor,shuffle=True)

将输出字符串(例如文件名)输入到管道队列

string_tensor:含有文件名的1阶张量(即文件路径+文件名)

num_epochs:过几遍数据,默认无限过数据

return:具有输出字符串的队列

2)构造文件阅读器

根据文件格式,选择对应的文件阅读器

tf.TextLineReader()

阅读文本文件、逗号分隔值(CSV)格式,默认按行读取

return:读取器实例

tf.FixedLengthRecordReader(record_bytes)

要读取每个记录是固定数量字节的二进制文件

record_bytes:整型,指定每次读取的字节数

return:读取器实例

tf.TFRecordReader()

读取TfRecords文件

上述三种文件阅读器有一个共同的读取方法:

read(file_queue):从队列中指定数量内容返回一个Tensors元组(key文件名字,value默认的内容(行,字节))

3)文件内容解码器

tf.decode_csv(records,record_defaults=None,field_delim = None,name = None)

将CSV转换为张量,与tf.TextLineReader搭配使用

records:tensor型字符串,每个字符串是csv中的记录行

field_delim:默认分割符”,”

record_defaults:参数决定了所得张量的类型,并设置一个值。在输入字符串中缺少使用默认值。

tf.decode_raw(bytes,out_type,little_endian = None,name = None)

将字节转换为一个数字向量表示,字节为一字符串类型的张量,与函数tf.FixedLengthRecordReader搭配使用,二进制读取为uint8格式

4)批处理

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:留下队列里的张量个数,能够保持随机打乱

文件读取案例:

import tensorflow as tf
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'

def csvread(filelist):
    """
    读取CSV文件
    :param filelist: 文件路径+名字的列表
    :return: 读取的内容
    """
    # 2.构造文件的队列
    file_queue = tf.train.string_input_producer(file_list)
    # 3.构造csv阅读器读取队列数据(按行读取)
    reader = tf.TextLineReader()
    key,value =reader.read(file_queue)
    # 4.解码
    # record_defaults:指定每一个样本的每一列的类型,指定默认值
    records = [["None"],["None"]]
    name,label = tf.decode_csv(value,record_defaults=records)
    # 5.想要读取多个数据,就需要批处理
    name_batch,label_batch = tf.train.batch([name,label],batch_size=9,num_threads=1,capacity=9)
    return name_batch,label_batch
if __name__ == '__main__':
    # 1.找到文件,放入列表  路径+名字 ->列表当中
    filename = os.listdir("E:/PythonProject/tf/test/")
    file_list = [os.path.join("E:/PythonProject/tf/test/",file) for file in filename]
    name,label = csvread(file_list)
    # 开启会话运行结果
    with tf.Session() as sess:
        # 定义一个线程协调器
        coord = tf.train.Coordinator()
        # 开启读文件的线程
        threads = tf.train.start_queue_runners(sess,coord=coord)
        # 打印读取的内容
        print(sess.run([name,label]))
        # 回收线程
        coord.request_stop()
        coord.join()

图片处理

图像基本知识

图像数字化三要素:长度、宽度、通道数

单通道:灰度值[0-255],一个像素点只有一个值

三通道:RGB,一个像素点由三个值组成

三要素与张量的关系:

例–指定3-D张量:[height,width,channels]----[长度,宽度,通道数]

图像基本操作

目的:

1)增加图片数据的统一性

2)所有图片转换成指定大小

3)缩小图片数据量,防止增加开销

操作:缩放图片大小

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,图像的新尺寸

返回4-D格式或者3-D格式图片

图像读取API

图像读取器

tf.WholeFileReader()----将文件的全部内容作为值输出的读取器

return:读取器实例

read(file_queue):输出将是一个文件名(key)和该文件的内容(value)

图像解码器

tf.image.decode_jpeg(contents)----将JPEG编码的图像解码为uint8张量

return:uint8张量,3-D形状[height, width, channels]

tf.image.decode_png(contents)----将PNG编码的图像解码为uint8或uint16张量

return:张量类型,3-D形状[height, width, channels]

图片批处理案例流程

1)构造图片文件队列

2)构造图片阅读器

3)读取图片数据

4)处理图片数据

import tensorflow as tf
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'

def picread(filelist):
    """
    读取狗图片并转换成张量
    :param filelist:文件路径 + 名字的列表
    :return:每张图片的张量
    """
    # 2.构造文件队列
    file_queue = tf.train.string_input_producer(filelist)
    # 3.构造阅读器去读取图片内容(默认按照一张一张照片读取)
    reader = tf.WholeFileReader()
    key,value = reader.read(file_queue)
    # 4.对读取的图片数据进行解码
    image = tf.image.decode_jpeg(value)
    # 5.处理图片的大小(统一大小)
    image_resize = tf.image.resize_images(image,[200,200])
    # 注意:一定要把样本的形状固定 [200,200,3],在批处理的时候要求所有数据形状必须定义
    image_resize.set_shape([200,200,3])
    # 6.批处理
    image_batch = tf.train.batch([image_resize],batch_size=5,num_threads=1,capacity=5)

    return image_batch
if __name__ == '__main__':
    # 1.找到文件,放入列表  路径+名字 ->列表当中
    filename = os.listdir("E:/PythonProject/tf/data/")
    file_list = [os.path.join("E:/PythonProject/tf/data/", file) for file in filename]
    image_batch = picread(file_list)
    # 开启会话运行结果
    with tf.Session() as sess:
        # 定义一个线程协调器
        coord = tf.train.Coordinator()
        # 开启读文件的线程
        threads = tf.train.start_queue_runners(sess, coord=coord)
        # 打印读取的内容
        print(sess.run([image_batch]))
        # 回收线程
        coord.request_stop()
        coord.join()

CIFAR-10数据集:

基本信息:

CIFAR-10数据集包含10个类别的60000个32x32彩色图像,每个类别6000个图像。有50000张训练图像和10000张测试图像。10个类别为:飞机( airplane )、汽车( automobile )、鸟类( bird )、猫( cat )、鹿( deer )、狗( dog )、蛙类( frog )、马( horse )、船( ship )和卡车( truck )。

数据集分为五个训练批次和一个测试批次,每个批次具有10000张。图像测试批的数据里,取10类中的每一类随机取1000张,抽剩下的就随机排列组成了训练批。注意一个训练批中的各类图像并不一定数量相同,总的来看训练批每一类都有5000张图。

下载地址:https://www.cs.toronto.edu/~kriz/cifar.html

二进制版本:

二进制版本包含文件data_batch_1.bin、data_batch_2.bin…data_batch_5.bin以及test_batch.bin。这些文件的每个格式如下:

<1 x标签> <3072 x像素>
...
<1 x标签> <3072 x像素>

换句话说,第一个字节是第一张图片的标签,它是0-9范围内的数字。接下来的3072个字节是图像像素的值。前1024个字节为红色通道值,后1024个为绿色,最后1024个为蓝色。

每个文件都包含10000个这样的3073字节“行”的图像。因此,每个文件的长度应恰好为30730000字节。

还有另一个文件,名为batchs.meta.txt。。这是一个ASCII文件,它将0-9范围内的数字标签映射到有意义的类名称。它只是10个类名的列表,每行一个。第i行上的类名称对应于数字标签i。

二进制文件读取:

import tensorflow as tf
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'

# 定义cifar的数据等命令行参数
FlAGS = tf.app.flags.FLAGS
tf.app.flags.DEFINE_string("cifar_dir","E:/PythonProject/tf/cifar10/cifar-10-bin-batches/","文件夹的目录")

class CifarRead(object):
    """
    完成读取二进制文件,写进tfrecords,再读取tfrecords
    """
    def __init__(self,filelist):
        # 文件列表
        self.file_list = filelist
        # 定义读取图片的一些属性
        self.height = 32
        self.width = 32
        self.channel = 3
        # 二进制文件每张图片的字节
        self.label_bytes = 1
        self.image_bytes = self.height * self.width * self.channel
        self.bytes = self.label_bytes + self.image_bytes
    def read_and_decode(self):
        # 1.构造文件队列
        file_queue = tf.train.string_input_producer(self.file_list)
        # 2.构建二进制文件读取器,读取内容
        reader = tf.FixedLengthRecordReader(self.bytes)
        key,value = reader.read(file_queue)
        # 3.解码内容,二进制文件内容的解码
        label_image = tf.decode_raw(value,tf.uint8)
        # 4.分割出图片(特征值)和标签数据(目标值)
        label = tf.cast(tf.slice(label_image,[0],[self.label_bytes]),tf.int32)
        image = tf.slice(label_image,[self.label_bytes],[self.image_bytes])
        # 5.对图片的特征数据进行形状的改变
        image_reshape = tf.reshape(image,[self.height,self.width,self.channel])
        # 6.批处理数据
        image_batch , label_batch = tf.train.batch([image_reshape,label],batch_size=10,num_threads=1,capacity=10)
        return image_batch,label_batch

if __name__ == '__main__':
    filename = os.listdir(FlAGS.cifar_dir)
    filelist = [os.path.join(FlAGS.cifar_dir,file)for file in filename if file[-3:] == "bin"]
    cf = CifarRead(filelist)
    image_batch,label_batch = cf.read_and_decode()
    # 开启会话运行结果
    with tf.Session() as sess:
        # 定义一个线程协调器
        coord = tf.train.Coordinator()
        # 开启读文件的线程
        threads = tf.train.start_queue_runners(sess, coord=coord)
        # 打印读取的内容
        print(sess.run([image_batch,label_batch]))
        # 回收线程
        coord.request_stop()
        coord.join()

TFRecords分析、存取:

TFRecords是Tensorflow设计的一种内置文件格式,是一种二进制文件,它能更好的利用内存,更方便复制和移动。

文件格式:*.tfrecords

写入文件内容:Example协议块

TFRecords存储:

1、建立TFRecord存储器

tf.python_io.TFRecordWriter(path)----写入tfrecords文件

path: TFRecords文件的路径

方法:

write(record):向文件中写入一个字符串记录

close():关闭文件写入器

注:字符串为一个序列化的Example,Example.SerializeToString()

2、构造每个样本的Example协议块

tf.train.Example(features=None)----写入tfrecords文件

features:tf.train.Features类型的特征实例

return:example格式协议块

tf.train.Features(feature=None)----构建每个样本的信息键值对

feature:字典数据,key为要保存的名字,value为tf.train.Feature实例

return:Features类型

tf.train.Feature(options)

options:例如:bytes_list=tf.train. BytesList(value=[Bytes]),int64_list=tf.train. Int64List(value=[Value])

example = tf.train.Example(features=tf.train.Features(feature={
   "image":tf.train.Feature(bytes_list=tf.train. BytesList(value=[Bytes]))
   "label":tf.train.Feature(int64_list=tf.train. Int64List(value=[Value]))
}))
import tensorflow as tf
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'

# 定义cifar的数据等命令行参数
FlAGS = tf.app.flags.FLAGS
tf.app.flags.DEFINE_string("cifar_dir","E:/PythonProject/tf/cifar10/cifar-10-bin-batches/","文件夹的目录")
tf.app.flags.DEFINE_string("cifar_tfrecords","E:/PythonProject/tf/tmp/cifar.tfrecords","存进tfrecords的文件")

class CifarRead(object):
    """
    完成读取二进制文件,写进tfrecords,再读取tfrecords
    """
    def __init__(self,filelist):
        # 文件列表
        self.file_list = filelist
        # 定义读取图片的一些属性
        self.height = 32
        self.width = 32
        self.channnel = 3
        # 二进制文件每张图片的字节
        self.label_bytes = 1
        self.image_bytes = self.height * self.width * self.channnel
        self.bytes = self.label_bytes + self.image_bytes
    def read_and_decode(self):
        # 1.构造文件队列
        file_queue = tf.train.string_input_producer(self.file_list)
        # 2.构建二进制文件读取器,读取内容
        reader = tf.FixedLengthRecordReader(self.bytes)
        key,value = reader.read(file_queue)
        # 3.解码内容,二进制文件内容的解码
        label_image = tf.decode_raw(value,tf.uint8)
        # 4.分割出图片(特征值)和标签数据(目标值)
        label = tf.cast(tf.slice(label_image,[0],[self.label_bytes]),tf.int32)
        image = tf.slice(label_image,[self.label_bytes],[self.image_bytes])
        # 5.对图片的特征数据进行形状的改变
        image_reshape = tf.reshape(image,[self.height,self.width,self.channnel])
        # 6.批处理数据
        image_batch , label_batch = tf.train.batch([image_reshape,label],batch_size=10,num_threads=1,capacity=10)
        return image_batch,label_batch
    def write_to_tfrecords(self,image_batch,label_batch):
        """
        将图片的特征值和目标值存进tfrecords
        :param image_batch: 10张图片的特征值
        :param label_batch: 10张图片的目标值
        :return: None
        """
        # 1.构造一个tfrecords存储器
        writer = tf.python_io.TFRecordWriter(FlAGS.cifar_tfrecords)
        # 2.循环将所有样本写入文件,每张图片样本都要构造example协议
        for i in range(10):
            # 取出第i个图片数据的特征值和目标值
            image = image_batch[i].eval().tostring()
            label = label_batch[i].eval()[0]
            # 构造一个样本的example
            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])),
            }))
            # 写入单独的样本
            writer.write(example.SerializeToString())
        # 关闭
        writer.close()

if __name__ == '__main__':
    filename = os.listdir(FlAGS.cifar_dir)
    filelist = [os.path.join(FlAGS.cifar_dir,file)for file in filename if file[-3:] == "bin"]
    cf = CifarRead(filelist)
    image_batch,label_batch = cf.read_and_decode()
    # 开启会话运行结果
    with tf.Session() as sess:
        # 定义一个线程协调器
        coord = tf.train.Coordinator()
        # 开启读文件的线程
        threads = tf.train.start_queue_runners(sess, coord=coord)
        # 存进tfrecords文件
        print("开始存储")
        cf.write_to_tfrecords(image_batch, label_batch)
        print("结束存储")
        # 打印读取的内容
        # print(sess.run([image_batch,label_batch]))
        # 回收线程
        coord.request_stop()
        coord.join()

TFRecords读取方法

同文件阅读器流程,中间需要解析过程解析TFRecords的example协议内存块

tf.parse_single_example(serialized,features=None,name=None)

解析一个单一的Example原型

serialized:标量字符串Tensor,一个序列化的Example

features:dict字典数据,键为读取的名字,值为FixedLenFeature

return:一个键值对组成的字典,键为读取的名字

tf.FixedLenFeature(shape,dtype)

shape:输入数据的形状,一般不指定,为空列表

dtype:输入数据类型,与存储进文件的类型要一致

类型只能是float32,int64,string

import tensorflow as tf
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'

# 定义cifar的数据等命令行参数
FlAGS = tf.app.flags.FLAGS
tf.app.flags.DEFINE_string("cifar_dir","E:/PythonProject/tf/cifar10/cifar-10-bin-batches/","文件夹的目录")
tf.app.flags.DEFINE_string("cifar_tfrecords","E:/PythonProject/tf/tmp/cifar.tfrecords","存进tfrecords的文件")

class CifarRead(object):
    """
    完成读取二进制文件,写进tfrecords,再读取tfrecords
    """
    def __init__(self,filelist):
        # 文件列表
        self.file_list = filelist
        # 定义读取图片的一些属性
        self.height = 32
        self.width = 32
        self.channnel = 3
        # 二进制文件每张图片的字节
        self.label_bytes = 1
        self.image_bytes = self.height * self.width * self.channnel
        self.bytes = self.label_bytes + self.image_bytes
    def read_and_decode(self):
        # 1.构造文件队列
        file_queue = tf.train.string_input_producer(self.file_list)
        # 2.构建二进制文件读取器,读取内容
        reader = tf.FixedLengthRecordReader(self.bytes)
        key,value = reader.read(file_queue)
        # 3.解码内容,二进制文件内容的解码
        label_image = tf.decode_raw(value,tf.uint8)
        # 4.分割出图片(特征值)和标签数据(目标值)
        label = tf.cast(tf.slice(label_image,[0],[self.label_bytes]),tf.int32)
        image = tf.slice(label_image,[self.label_bytes],[self.image_bytes])
        # 5.对图片的特征数据进行形状的改变
        image_reshape = tf.reshape(image,[self.height,self.width,self.channnel])
        # 6.批处理数据
        image_batch , label_batch = tf.train.batch([image_reshape,label],batch_size=10,num_threads=1,capacity=10)
        return image_batch,label_batch
    def write_to_tfrecords(self,image_batch,label_batch):
        """
        将图片的特征值和目标值存进tfrecords
        :param image_batch: 10张图片的特征值
        :param label_batch: 10张图片的目标值
        :return: None
        """
        # 1.构造一个tfrecords存储器
        writer = tf.python_io.TFRecordWriter(FlAGS.cifar_tfrecords)
        # 2.循环将所有样本写入文件,每张图片样本都要构造example协议
        for i in range(10):
            # 取出第i个图片数据的特征值和目标值
            image = image_batch[i].eval().tostring()
            label = label_batch[i].eval()[0]
            # 构造一个样本的example
            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])),
            }))
            # 写入单独的样本
            writer.write(example.SerializeToString())
        # 关闭
        writer.close()

    def read_from_tfrecords(self):
        # 1.构造文件队列
        file_queue = tf.train.string_input_producer([FlAGS.cifar_tfrecords])
        # 2.构造文件阅读器,读取内容example,value为一个样本的序列化example
        reader = tf.TFRecordReader()
        key, value = reader.read(file_queue)
        # 3.解析example
        features = tf.parse_single_example(value, features={
            "image": tf.FixedLenFeature([], tf.string),
            "label": tf.FixedLenFeature([], tf.int64)
        })
        # 4.解码内容 如果读取的内容格式是string需要解码,如果是int64、float32不需要解码
        image = tf.decode_raw(features["image"],tf.uint8)
        # 固定图片的形状,方便批处理
        image_reshape = tf.reshape(image,[self.height,self.width,self.channnel])
        label = features["label"]
        print(image_reshape,label)
        # 5.进行批处理
        image_batch,label_batch = tf.train.batch([image_reshape,label],batch_size=10,capacity=10)
        return image_batch,label_batch
if __name__ == '__main__':
    filename = os.listdir(FlAGS.cifar_dir)
    filelist = [os.path.join(FlAGS.cifar_dir,file)for file in filename if file[-3:] == "bin"]
    cf = CifarRead(filelist)
    image_batch , label_batch = cf.read_from_tfrecords()
    # image_batch,label_batch = cf.read_and_decode()
    # 开启会话运行结果
    with tf.Session() as sess:
        # 定义一个线程协调器
        coord = tf.train.Coordinator()
        # 开启读文件的线程
        threads = tf.train.start_queue_runners(sess, coord=coord)
        # 存进tfrecords文件
        # print("开始存储")
        # cf.write_to_tfrecords(image_batch, label_batch)
        # print("结束存储")
        # 打印读取的内容
        print(sess.run([image_batch,label_batch]))
        # 回收线程
        coord.request_stop()
        coord.join()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值