zoukankan      html  css  js  c++  java
  • 深度学习原理与框架-Tfrecord数据集的读取与训练(代码) 1.tf.train.batch(获取batch图片) 2.tf.image.resize_image_with_crop_or_pad(图片压缩) 3.tf.train.per_image_stand..(图片标准化) 4.tf.train.string_input_producer(字符串入队列) 5.tf.TFRecord(读

    1.tf.train.batch(image, batch_size=batch_size, num_threads=1) # 获取一个batch的数据

    参数说明:image表示输入图片,batch_size表示一个batch的大小,num_threads表示使用几个线程进行执行

    import tensorflow as tf
    import numpy as np
    def generate_data():
    
        num = 25
        label = np.asarray(range(0, num))
        image = np.random.random([num, 1, 1, 1])
    
        return label, image
    
    def get_batch_data():
    
        labels, images = generate_data()
        images = tf.cast(images, 'float32')
        labels = tf.cast(labels, 'int32')
        input_queue = tf.train.slice_input_producer([images, labels], shuffle=False)
        image_batch, label_batch = tf.train.batch(input_queue, batch_size=10, num_threads=1, capacity=64)
    
        return image_batch, label_batch
    
    image_batch, label_batch = get_batch_data()
    with tf.Session() as sess:
        coord = tf.train.Coordinator()
        threads = tf.train.start_queue_runners(sess=sess, coord=coord)
        i = 0
        for i in range(10):
            image_batch_v, label_batch_v = sess.run([image_batch, label_batch])
            print(image_batch_v, label_batch_v)
    
        coord.request_stop()
        coord.join(threads)
        sess.close()

    实例说明

    2.tf.image.resize_image_with_crop_or_pad(image, IMAGE_SIZE, IMAGE_SIZE) # 表示对图片进行压缩,即变化维度, 相当于tf.resize(操作)

    参数说明:image表示输入图片,IMAGE_SIZE表示变化后的维度

    3.tf.train.per_image_standardization(image) 对图片进行标准化操作

    参数说明:image表示输入的图片

    4.tf.train.string_input_producer(filenames) # 将字符串放入到队列中

    参数说明:filename表示输入的字符串集合

    5. tf.TFRecordReader() # 构建tfr读取器,使用.read() 对文件进行读取

    6. tf.parse_single_example(serialized_exmaple, features={})  解析example数据字符串

    7.tf.train.start_queue_runner(coord=coord, sess=sess) 用来启动线程,进行多线程操作

    参数说明:coord表示线程协调器,sess执行函数支持多线程

    8.tf.train.Coordinator() 用于建立线程协调器, coord.join(threads) 将多线程放入到线程协调器中

    数据说明:使用的数据是Tfrecord数据集,一共3670个数据,每次迭代选取16张图片,输出的结果类别数是5 

    文中的代码主要是分为两个部分:

       第一部分构造flower_input, 读取batch_image, batch_label

       第二部分:构造image_tensor_input和label_tensor_input, 输入到构造的flower_inference模型中进行训练,输出结果为softmax概率值,构造loss和train_op,sess.run进行模型的训练操作

    第一部分:

               第一步:构造flower_input函数,输入为if_random, if_train 

               第二步:根据是否训练,使用[os.path.join(path_data + ''%i) for i in range(0, 2)] 来获得文件的路径filenames

               第三步:使用tf.train.string_input_producer(filenames) , # 输出字符变成一个输入队列中

               第四步:将filename_queue输入到read_and_decode(filename_queue) 输出image_object实例化对象,包含image, label, filename等属性

                              第一步:使用tf.TFRecordReader() 构造reader的读写器

                              第二步:使用_, serialized_example = reader.read(filenames)  获得存储好的example

                              第三步:使用tf.parse_single_example(features={})  获得属性值

                              第四步:实例化_image_object(), 用于储存image,label, filename,width和height

                              第五步:使用image_raw = tf.image.decode_jpeg(feature[image/encoded]) # 对图片进行解码操作

                              第六步:使用tf.image.resize_image_with_crop_or_pad(image_raw) 对图像进行维度的压缩变换

                             第七步:将其他属性label,filename, height,width,使用image_object.label = features['image/labels'] 进行添加, 返回image_object 

                第五步:使用image_object.image 获得image, 使用tf.train.per_image_standardization对image进行标准化操作

                第六步:使用image_object.label获得label属性

                第七步:使用image_object.filename获得filename属性

                第八步:判断是否是随机的batch,如果是随机的使用tf.train.shuffle_batch,如果不是随机的batch,使用tf.train.batch([image, label, filename]) 获得随机的batch,返回image_batch, label_batch, filename_batch 

    第二部分:第一部分,获得了一个batch的数据, 第二部分,建立网络模型

                 第一步:使用tf.placeholder()构建image_tensor_input, 同时对image_batch_out 进行维度的变化,确认其维度为[BATCH_SIZE, 224, 224, 3]

                 第二步:使用tf.placeholder()构建label_tensor_input,同时构造label_offset = -tf.ones([batch_size]) ,然后使用tf.add(label_batch_out, label_offset) 将标签值从1变为0。

                 第三步:构造flower_inference(image_tensor_input)获得logits_batch_out, 对logists_batch 进行维度变化,确认其维度为[BATCH_SIZE, 5]

                             flower_inference是用于构造卷积的模型,网络的结构是卷积层5层,全连接层4层,输出层为[BATCH_SIZE, 5], 结果使用tf.nn.softmax() 

                 第四步: 使用tf.nn.softmax_entropy_logits(logits=logits_out, labels=tf.one_hots(label_tensor_input, depth=5))  构造loss损失函数

                 第五步:使用tf.train.GradientDescentOptimizer().minimize(loss) 构造train_op,降低损失值

                 第六步:使用with tf.Session() as sess 构造sess执行函数

                 第七步:使用sess.run, 进行变量的初始化操作

                 第八步:使用tf.train.Coordinator() 构造coord通道,使用tf.train.start_queue_runners(coord=coord, sess=sess) 构造threads多线程

                 第九步:进行循环,使用sess.run([image_batch, label_batch]) 获得实际的image_batch 和 label_batch 

                 第十步:使用sess.run([train_op, logits_out, loss]) 进行训练操作

                 第十一步:coord.request_stop() 将coord进行关闭

                 第十二步:coord.join(threads) 将多线程添加到通道数,sess.close() 关闭sess

    import tensorflow as tf
    import numpy as np
    import os
    
    data_path = './data/'
    TRAINING_SET_SIZE = 3670
    BATCH_SIZE = 16
    IMAGE_SIZE = 224
    
    def create_Weight(shape):
    
        return tf.Variable(tf.truncated_normal(shape=shape, stddev=0.05))
    
    def creat_biases(shape):
    
        return tf.Variable(tf.constant(0.1, shape=shape))
    
    def conv2d(x, w):
    
        return tf.nn.conv2d(x, w, strides=[1, 1, 1, 1], padding='SAME')
    
    def maxpool(x):
    
        return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')
    
    def flower_inference(image_tensor_input):
        
        # 确认输入的图片的维度为[batchsize, 224, 224, 5]
        x_image = tf.reshape(image_tensor_input, [BATCH_SIZE, IMAGE_SIZE, IMAGE_SIZE, 3])
        # 创建第一层卷积的w
        w_conv1 = create_Weight([5, 5, 3, 32])
        # 第一层卷积的b
        b_conv1 = creat_biases([32])
        # 进行卷积和激活操作
        h_conv1 = tf.nn.relu(conv2d(x_image, w_conv1) + b_conv1)
        # 进行池化操作
        h_pool1 = maxpool(h_conv1)
        # 第二层卷积的w
        w_conv2 = create_Weight([5, 5, 32, 64])
        # 第二层卷积的b
        b_conv2 = creat_biases([64])
        # 卷积和激活操作
        h_conv2 = tf.nn.relu(conv2d(h_pool1, w_conv2) + b_conv2)
        # 池化操作
        h_pool2 = maxpool(h_conv2)
        # 第三层卷积的w
        w_conv3 = create_Weight([5, 5, 64, 128])
        # 第三层卷积的b
        b_conv3 = creat_biases([128])
        # 卷积和激活操作
        h_conv3 = tf.nn.relu(conv2d(h_pool2, w_conv3) + b_conv3)
        # 池化操作
        h_pool3 = maxpool(h_conv3)
        # 第四层卷积的w
        w_conv4 = create_Weight([5, 5, 128, 256])
        # 第四层卷积的b
        b_conv4 = creat_biases([256])
        # 进行卷积和激活操作
        h_conv4 = tf.nn.relu(conv2d(h_pool3, w_conv4) + b_conv4)
        # 进行池化操作
        h_pool4 = maxpool(h_conv4)
        # 第五层卷积的w
        w_conv5 = create_Weight([5, 5, 256, 256])
        # 第五层卷积的b
        b_conv5 = creat_biases([256])
        # 进行卷积和激活操作
        h_conv5 = tf.nn.relu(conv2d(h_pool4, w_conv5) + b_conv5)
        # 池化操作
        h_pool5 = maxpool(h_conv5)
        # 将卷积后的结果进行维度的变换,以便后续进行全连接操作
        fcIn = tf.reshape(h_pool5, [-1, 7*7*256])
        # 第一层全连接的w
        w_fc1 = create_Weight([7*7*256, 2048])
        # 第一层全连接的b
        b_fc1 = creat_biases([2048])
        # 点乘和激活操作
        h_fc1 = tf.nn.relu(tf.matmul(fcIn, w_fc1) + b_fc1)
        # dropout操作
        h_fc1_dropout = tf.nn.dropout(h_fc1, 1.0)
        # 第二层全连接的w
        w_fc2 = create_Weight([2048, 256])
        # 第二层全连接的b
        b_fc2 = creat_biases([256])
        # 点乘和激活操作
        h_fc2 = tf.nn.relu(tf.matmul(h_fc1_dropout, w_fc2) + b_fc2)
        # 第三层全连接层
        w_fc3 = create_Weight([256, 64])
        b_fc3 = creat_biases([64])
        h_fc3 = tf.nn.relu(tf.matmul(h_fc2, w_fc3) +b_fc3)
        # 第四层全连接输出层
        w_fc4 = create_Weight([64, 5])
        b_fc4 = creat_biases([5])
        # 对输出的结果使用softmax获得概率值
        y_prob = tf.nn.softmax(tf.matmul(h_fc3, w_fc4) + b_fc4)
    
        return y_prob
    
    
    
    class _image_object:
        # 构造实例化属性
        def __init__(self):
            # 存放图片,高度,宽度,名字和标签属性
            self.image = tf.Variable([], dtype=tf.string)
            self.height = tf.Variable([], dtype=tf.int64)
            self.width = tf.Variable([], dtype=tf.int64)
            self.filename = tf.Variable([], dtype=tf.string)
            self.label = tf.Variable([], dtype=tf.int32)
    
    def read_and_decode(filename_queue):
        # 构造TFR的读写器
        reader = tf.TFRecordReader()
        # 使用reader.read(filename_queue)读出存入的exmaple数据
        _, serialized_exmaple = reader.read(filename_queue)
        # 使用tf.parse_single_example, 获得数据中属性对应的数据
        features = tf.parse_single_example(serialized_exmaple, features={
            'image/encoded':tf.FixedLenFeature([], tf.string),
            'image/height': tf.FixedLenFeature([], tf.int64),
            'image/width': tf.FixedLenFeature([], tf.int64),
            'image/filename': tf.FixedLenFeature([], tf.string),
            'image/class/label': tf.FixedLenFeature([], tf.int64)
        })
        # 获得编码的图片数据
        image_decode = features['image/encoded']
        # 使用tf.image.decode_jpeg 对图片进行解码操作
        image_raw = tf.image.decode_jpeg(image_decode, channels=3)
        # 实例化函数,用于进行数据集合的存储
        image_object = _image_object()
        # 使用tf.image.resize_image_with_crop_or_pad进行维度的变换和压缩,并存储到image.object
        image_object.image = tf.image.resize_image_with_crop_or_pad(image_raw,IMAGE_SIZE, IMAGE_SIZE)
        # 将label属性存储到image_object.label中
        image_object.label = features['image/class/label']
        # 将filename属性存储到image_object.filename中
        image_object.filename = features['image/filename']
        # 将height属性存储到image_object.height中
        image_object.height = features['image/height']
        # 将width属性存储到image_object.width中
        image_object.width = features['image/width']
        # 返回数据集合image_object
        return image_object
    
    # 第一步:创建flower_input,用于进行数据的创建,输入为是否训练和是否获得随机的batch值
    def flower_input(if_train=True, if_random=True):
        # 第二步:如果是进行训练,获得训练集的文件地址
        if if_train:
            filenames = [os.path.join(data_path, 'train-0000%d-of-00002.tfrecord'%i) for i in range(0, 2)]
        else:
            filenames = [os.path.join(data_path, 'eval-0000%d-of-00002.tfrecord'%i) for i in range(0, 2)]
        # 判断文件是否存在,如果不存在返回错误提醒
        for f in filenames:
            if not tf.gfile.Exists(f):
                raise ValueError('the file is not exits', f)
        # 第三步:使用tf.train.string_input_producer()将数据输入到队列中
        filename_queue = tf.train.string_input_producer(filenames)
        # 第四步:构造函数获得数据集合
        image_object = read_and_decode(filename_queue)
        # 使用tf.image.per_image_standardization对图片进行标准化
        image = tf.image.per_image_standardization(image_object.image)
        # 获得图片的标签
        label = image_object.label
        # 获得图片的文件名
        filename = image_object.filename
        # 如果是随机获得标签,使用tf.train.shuffle_batch
        if if_random:
            min_fraction_of_example_in_queue = 0.4
            min_queue_examples = int(min_fraction_of_example_in_queue * TRAINING_SET_SIZE)
            num_preprocess_threads = 1
            image_batch, label_batch, filename_batch = tf.train.shuffle_batch(
                [image, label, filename],
                batch_size = BATCH_SIZE,
                num_threads = num_preprocess_threads,
                capacity = min_queue_examples + 3 * BATCH_SIZE,
                min_after_dequeue = min_queue_examples
            )
            # 返回batch的image,label,filename
            return image_batch, label_batch, filename_batch
        else:
            # 如果不是随机获得数据,使用tf.train.batch
            image_batch, label_batch, filename_batch = tf.train.batch(
                [image, label, filename],
                batch_size = BATCH_SIZE,
                num_threads = 1
            )
            #返回batch的image,label,filename
            return image_batch, label_batch, filename_batch
    
    
    
    
    
    
    def flower_trian():
        # 第一部分:使用tf.train.batch获得一个batch的数据
        image_batch_out, label_batch_out, filename_batch = flower_input(if_train=True, if_random=False)
        # 第二部分:构造模型,进行模型的训练,使用sess.run()获得上述的实际数据
        # 第一步:使用tf.placeholder初始化输入图像,并对image_batch_out确认维度
        image_tensor_input = tf.placeholder(tf.float32, [BATCH_SIZE, 224, 224, 3])
        image_batch = tf.reshape(image_batch_out, [BATCH_SIZE, IMAGE_SIZE, IMAGE_SIZE, 3])
        # 第二步:使用tf.placeholder初始化标签值,并构造-1的[batch_size]大小,与标签进行加和,使得标签值变成从0开始
        label_tensor_input = tf.placeholder(tf.int64, [BATCH_SIZE])
        label_offset = -tf.ones([BATCH_SIZE], dtype=tf.int64, name='label_offset')
        label_batch = tf.add(label_batch_out, label_offset)
        # 第三步:构造模型,带入image_tensor_input获得5个类别的概率值,维度为[BATCHSIZE, 5]
        logits_batch_out = flower_inference(image_tensor_input)
        logits_batch = tf.reshape(logits_batch_out, [BATCH_SIZE, 5])
        # 第四步:使用tf.nn.sotfmax_cross(logist=logits_batch, labels=tf.one_hot() 进行对标签进行one_hot编码
        loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=tf.one_hot(label_tensor_input, depth=5), logits=logits_batch))
        # 第五步:使用tf.train.Gradient降低损失值loss
        train_op = tf.train.GradientDescentOptimizer(0.0001).minimize(loss)
    
        saver = tf.train.Saver()
        # 第六步:使用tf.Session() 构造sess执行函数
        with tf.Session() as sess:
            # 第七步:对参数进行初始化操作
            sess.run(tf.global_variables_initializer())
            # 第八步:使用tf.train.Coordinator构造通道数
            coord = tf.train.Coordinator()
            # 第九步:使用tf.train.start_queue_runners构造sess的多线程threads
            threads = tf.train.start_queue_runners(coord=coord, sess=sess)
    
            for i in range(TRAINING_SET_SIZE * 10):
                # 第十步:使用sess.run获得实际的batch的label,image
                image_batch_v, label_batch_v, filename_batch_v = sess.run([image_batch, label_batch, filename_batch])
                # 第十一步:进行实际的train_op, loss, logits的执行
                _, infer_out, loss_out = sess.run([train_op, logits_batch, loss], feed_dict={image_tensor_input:image_batch_v, label_tensor_input:label_batch_v})
                # 打印结果
                if (i % 10 == 0):
                    print('infer_out')
                    print(infer_out)
                    print('loss_out')
                    print(loss_out)
            # 第十一步:关闭线程        
            coord.request_stop()
            # 第十二步:将线程进行添加,和关闭sess
            coord.join(threads)
            sess.close()
    
    
    flower_trian()

     

            

                              

               

                 

  • 相关阅读:
    云计算之路-阿里云上:基于Xen的IO模型进一步分析“黑色0.1秒”问题团队
    上周热点回顾(5.5-5.11)团队
    云计算之路-阿里云上:原来“黑色0.1秒”发生在socket读取数据时团队
    云计算之路-阿里云上:读取缓存时的“黑色0.1秒”团队
    云计算之路-阿里云上:“黑色30秒”走了,“黑色1秒”来了,真相也许大白了团队
    云计算之路-阿里云上:神奇的“黑色30秒”再次出现,究竟是谁的错?团队
    上周热点回顾(4.28-5.4)团队
    云计算之路-阿里云上:从ASP.NET线程角度对“黑色30秒”问题的全新分析团队
    上周热点回顾(4.21-4.27)团队
    云计算之路-阿里云上:借助IIS Log Parser Studio分析“黑色30秒”问题团队
  • 原文地址:https://www.cnblogs.com/my-love-is-python/p/10584919.html
Copyright © 2011-2022 走看看