• 『TensorFlow』第十一弹_队列&多线程&TFRecod文件_我辈当高歌


    TF数据读取队列机制详解

    一、TFR文件多线程队列读写操作

    TFRecod文件写入操作

    import tensorflow as tf
    def _int64_feature(value):
        # value必须是可迭代对象
        # 非int的数据使用bytes取代int64即可
        return tf.train.Feature(int64_list=tf.train.Int64List(value=[value]))
    num_shards = 2
    instance_perPshard = 2
    for i in range(num_shards):
        filename = ('FTR/data.tfrecords-%.5d-of-%.5d' % (i, num_shards))
        writer = tf.python_io.TFRecordWriter(filename)                      #<---------书写器打开
        for j in range(instance_perPshard):
            example = tf.train.Example(features=tf.train.Features(feature={ #<---------书写入缓冲区
                'i':_int64_feature(i),
                'j':_int64_feature(j)
            }))
            writer.write(example.SerializeToString())                       #<---------书写入实际文件
        writer.close()                                                      #<---------书写器关闭
    

    TFRecod文件读取操作

    默认多线程,这个默认的多线程过程用于维护文件名队列

    '''读取TFR'''
    
    files = ["FTR/data.tfrecords-00000-of-00002","FTR/data.tfrecords-00001-of-00002"]
    # files = tf.train.match_filenames_once("FTR/data.tfrecords-*")
    
    # 输入文件名列表
    # 返回QueueRunner & FIFOQueue
    # 打乱顺序&加入队列 和 输出队列获取文件 属于单独的线程
    filename_queue = tf.train.string_input_producer(files, shuffle=False) #<---------输入文件队列
    reader = tf.TFRecordReader()                        #<---------读取器打开
    _,serialized_example = reader.read(filename_queue)  #<---------读取原始文件
    features = tf.parse_single_example(                 #<---------读取解析后文件
        serialized_example,
        features={
            'i':tf.FixedLenFeature([],tf.int64),
            'j':tf.FixedLenFeature([],tf.int64)
        })
    
    with tf.Session() as sess:
        tf.global_variables_initializer().run()
        coord = tf.train.Coordinator() #<---------多线程
        threads = tf.train.start_queue_runners(sess=sess,coord=coord) #<---------文件名队列填充线程启动
        for i in range(6):
            print(sess.run([features['i'],features['j']]))            #<---------实际会话中启动读取过程
        coord.request_stop()           #<---------多线程
        coord.join(threads)            #<---------多线程
    

    TFRecod文件打包操作

    打包机制:

    ——————多线程调用前面的节点计算入队

    ——————批量出队并打包

    所以不需要修改解析读取数据过程为循环之类的,可以说很是方便

    example_batch, label_batch = tf.train.batch([example, label],     #<---------多线程batch生成
                                                batch_size=batch_size,
                                                num_threads=3,
                                                capacity=capacity)
    
    example_batch, label_batch = tf.train.shuffle_batch([example, label],     #<---------多线程随机batch生成
                                                batch_size=batch_size,
                                                num_threads=3,
                                                capacity=capacity,
                                                min_after_dequeue=30)     由于元素太少随机意义就不大了,所以多了个参数
    

     使用范例,

    files = ["FTR/data.tfrecords-00000-of-00002","FTR/data.tfrecords-00001-of-00002"]
    # files = tf.train.match_filenames_once("FTR/data.tfrecords-*")
    
    # 输入文件名列表
    # 返回QueueRunner & FIFOQueue
    # 打乱顺序&加入队列 和 输出队列获取文件 属于单独的线程
    filename_queue = tf.train.string_input_producer(files, shuffle=False) #<---------输入文件队列
    reader = tf.TFRecordReader()                        #<---------读取
    _,serialized_example = reader.read(filename_queue)  #<---------读取
    features = tf.parse_single_example(                 #<---------读取
        serialized_example,
        features={
            'i':tf.FixedLenFeature([],tf.int64),
            'j':tf.FixedLenFeature([],tf.int64)
        })
    
    example, label = features['i'], features['j']
    batch_size = 2
    capacity = 1000 + 3 * batch_size
    
    # 入队单个样例,出队batch
    # 可以指定多个线程同时执行入队操作
    example_batch, label_batch = tf.train.batch([example, label],     #<---------多线程batch生成
                                                batch_size=batch_size,
                                                num_threads=3,
                                                capacity=capacity)
    with tf.Session() as sess:
        tf.global_variables_initializer().run()
        coord = tf.train.Coordinator()                                #<---------多线程管理器
        threads = tf.train.start_queue_runners(sess=sess,coord=coord) #<---------文件名队列填充线程启动
        for i in range(3):
            cur_example_batch, cur_label_batch = sess.run([example_batch, label_batch])
            print(cur_example_batch, cur_label_batch)
        coord.request_stop()                                          #<---------多线程关闭
        coord.join(threads)                         
    

    这个输出每一行前为image(代指),后为label,第一行的数据对实际为0-0,0-1:

    [0 0] [0 1]
    [1 1] [0 1]
    [0 0] [0 1]
    

    二、图片文件使用TFR读写测试

    read的二进制数据直接进行_bytes_feature化就可以写入文件,使用tf.string类型读出图片数据后可以直接decode解码之(推测tf中string对应二进制数据类型)。

    把一张图片写入TFR中:

    import tensorflow as tf
    import matplotlib.pyplot as plt
    
    def _bytes_feature(value):
        return tf.train.Feature(bytes_list=tf.train.BytesList(value=[value]))
    def _int64_feature(value):
        return tf.train.Feature(int64_list=tf.train.Int64List(value=[value]))
    img_raw = tf.gfile.FastGFile('123123.jpeg','rb').read()
    
    filename = ('FTR/image.tfrecords')
    writer = tf.python_io.TFRecordWriter(filename) #<---------书写
    example = tf.train.Example(features=tf.train.Features(feature={ #<---------书写
        'image':_bytes_feature(img_raw),
        'label':_int64_feature(1)
        }))
    writer.write(example.SerializeToString()) #<---------书写
    writer.close()
    

     从TFR中读取图片数据并解码绘制出来:

    filename_queue = tf.train.string_input_producer(['FTR/image.tfrecords'], shuffle=False) #<---------输入文件队列
    reader = tf.TFRecordReader()                        #<---------读取
    _,serialized_example = reader.read(filename_queue)  #<---------读取
    features = tf.parse_single_example(                 #<---------读取
        serialized_example,
        features={
            'image':tf.FixedLenFeature([],tf.string),
            'label':tf.FixedLenFeature([],tf.int64)
        })
    img = tf.image.decode_jpeg(features['image'])
    with tf.Session() as sess:
        tf.global_variables_initializer().run()
    
        coord = tf.train.Coordinator()  # <---------多线程
        threads = tf.train.start_queue_runners(sess=sess, coord=coord)  # <---------文件名队列填充线程启动
        # img_raw, label = sess.run([features['image'], features['label']])
        image = sess.run(img)
        plt.imshow(image)
        plt.show()
        coord.request_stop()  # <---------多线程
        coord.join(threads)  # <---------多线程
    

    三、图片文件直接使用队列读写操作

    仅仅示范了维护图片文件名队列的读写,没有过多的其他操作

    reader = tf.WholeFileReader():新的读取器,应该是范用性二进制文件读取器

    # 导入tensorflow
    import tensorflow as tf
    
    # 新建一个Session
    with tf.Session() as sess:
        # 我们要读三幅图片A.jpg, B.jpg, C.jpg
        filename = ['123.png', '123123.jpeg']
        # string_input_producer会产生一个文件名队列
        filename_queue = tf.train.string_input_producer(filename, shuffle=False, num_epochs=5)
        # reader从文件名队列中读数据。对应的方法是reader.read
        reader = tf.WholeFileReader()                             #<---------注意读取器不一样了
        key, value = reader.read(filename_queue)
        # tf.train.string_input_producer定义了一个epoch变量,要对它进行初始化
        tf.local_variables_initializer().run()
        # 使用start_queue_runners之后,才会开始填充队列
        threads = tf.train.start_queue_runners(sess=sess)
        i = 0
        while True:
            i += 1
            # 获取图片数据并保存
            image_data = sess.run(value)
            with open('test_%d.jpg' % i, 'wb') as f:
                f.write(image_data)
    

    四、队列文件使用范式

    文件名队列创建->读取解析文件->打包解析好的文件->多线程启动图训练(多线程指被使用的部分其实还是文件读取)

    import tensorflow as tf
    
    
    '''创建文件列表'''
    
    files = tf.train.match_filenames_once("Records/output.tfrecords")
    filename_queue = tf.train.string_input_producer(files, shuffle=False)
    
    
    '''解析TFRecord文件里的数据'''
    
    # 读取文件。
    
    reader = tf.TFRecordReader()
    _,serialized_example = reader.read(filename_queue)
    
    # 解析读取的样例。
    features = tf.parse_single_example(
        serialized_example,
        features={
            'image_raw':tf.FixedLenFeature([],tf.string),
            'pixels':tf.FixedLenFeature([],tf.int64),
            'label':tf.FixedLenFeature([],tf.int64)
        })
    
    decoded_images = tf.decode_raw(features['image_raw'],tf.uint8)
    retyped_images = tf.cast(decoded_images, tf.float32)
    labels = tf.cast(features['label'],tf.int32)
    #pixels = tf.cast(features['pixels'],tf.int32)
    images = tf.reshape(retyped_images, [784])
    
    
    '''将文件以100个为一组打包'''
    
    min_after_dequeue = 10000
    batch_size = 100
    capacity = min_after_dequeue + 3 * batch_size
    
    image_batch, label_batch = tf.train.shuffle_batch([images, labels],
                                                        batch_size=batch_size,
                                                        capacity=capacity,
                                                        min_after_dequeue=min_after_dequeue)
    
    
    '''训练模型'''
    
    
    def inference(input_tensor, weights1, biases1, weights2, biases2):
        layer1 = tf.nn.relu(tf.matmul(input_tensor, weights1) + biases1)
        return tf.matmul(layer1, weights2) + biases2
    
    
    # 模型相关的参数
    INPUT_NODE = 784
    OUTPUT_NODE = 10
    LAYER1_NODE = 500
    REGULARAZTION_RATE = 0.0001
    TRAINING_STEPS = 5000
    
    weights1 = tf.Variable(tf.truncated_normal([INPUT_NODE, LAYER1_NODE], stddev=0.1))
    biases1 = tf.Variable(tf.constant(0.1, shape=[LAYER1_NODE]))
    
    weights2 = tf.Variable(tf.truncated_normal([LAYER1_NODE, OUTPUT_NODE], stddev=0.1))
    biases2 = tf.Variable(tf.constant(0.1, shape=[OUTPUT_NODE]))
    
    y = inference(image_batch, weights1, biases1, weights2, biases2)
    
    # 计算交叉熵及其平均值
    cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=y, labels=label_batch)
    cross_entropy_mean = tf.reduce_mean(cross_entropy)
    
    # 损失函数的计算
    regularizer = tf.contrib.layers.l2_regularizer(REGULARAZTION_RATE)
    regularaztion = regularizer(weights1) + regularizer(weights2)
    loss = cross_entropy_mean + regularaztion
    
    # 优化损失函数
    train_step = tf.train.GradientDescentOptimizer(0.01).minimize(loss)
    
    # 初始化回话并开始训练过程。
    with tf.Session() as sess:
        tf.global_variables_initializer().run()
        coord = tf.train.Coordinator()
        threads = tf.train.start_queue_runners(sess=sess, coord=coord)
        # 循环的训练神经网络。
        for i in range(TRAINING_STEPS):
            if i % 1000 == 0:
                print("After %d training step(s), loss is %g " % (i, sess.run(loss)))
    
            sess.run(train_step)
        coord.request_stop()
        coord.join(threads)
    
  • 相关阅读:
    爱摘苹果的小明
    盗梦空间
    九九乘法表
    谁是最好的Coder
    画图
    黑色帽子
    a letter and a number
    运维开发面试题
    python 守护进程daemon
    kubernets 应用部署
  • 原文地址:https://www.cnblogs.com/hellcat/p/6941446.html
Copyright © 2020-2023  润新知