CIFAR-10

10类RGB图片:airplane, automobile, bird, cat, deer, dog, frog, horse, ship, truck

图片尺寸32x32,50000张训练图片,10000张测试图片

项目源码:https://github.com/tensorflow/models/tree/master/tutorials/image/cifar10

官方示例代码文件

cifar10.py  建立预测模型

cifar10_input.py  tensorflow中读取训练图片

cifar10_input_test.py  测试用例文件

cifar10_train.py  使用单个cpu或gpu训练模型

cifar10_train_multi_gpu.py  使用多个GPU训练模型

cifar10_eval.py  在测试集上测试模型的性能

数据集数据文件

batches.meta.txt  存储每个类别的英文名称

data_batch_1.bin  训练数据1,每个文件以二进制存储了10000张32x32的彩色图片和对应的标签,1000个样本中每个样本由3073个字节组成,第一个字节为标签,剩下3072个字节为图像数据

data_batch_2.bin  训练数据2

data_batch_3.bin  训练数据3

data_batch_4.bin  训练数据4

data_batch_5.bin  训练数据5

test_batch.bin  测试图像和测试图像的标签

代码解析

cifar10_input.py

  1 from __future__ import absolute_import
  2 from __future__ import division
  3 from __future__ import print_function
  4 import os
  5 from six.moves import xrange  # pylint: disable=redefined-builtin
  6 import tensorflow as tf
  7  
  8 # 原图像的尺度为32*32,但根据常识,信息部分通常位于图像的中央,
  9 # 这里定义了以中心裁剪后图像的尺寸24x24
 10 IMAGE_SIZE = 24
 11 NUM_CLASSES = 10
 12 NUM_EXAMPLES_PER_EPOCH_FOR_TRAIN = 50000
 13 NUM_EXAMPLES_PER_EPOCH_FOR_EVAL = 10000
 14 
 15 #读取数据函数
 16 def read_cifar10(filename_queue):
 17   """Reads and parses examples from CIFAR10 data files.
 18   Recommendation: if you want N-way read parallelism, call this function
 19   N times.  This will give you N independent Readers reading different
 20   files & positions within those files, which will give better mixing of
 21   examples.
 22   Args:
 23     filename_queue: A queue of strings with the filenames to read from.
 24   Returns:
 25     An object representing a single example, with the following fields:
 26       height: number of rows in the result (32)
 27       width: number of columns in the result (32)
 28       depth: number of color channels in the result (3)
 29       key: a scalar string Tensor describing the filename & record number
 30         for this example.
 31       label: an int32 Tensor with the label in the range 0..9.
 32       uint8image: a [height, width, depth] uint8 Tensor with the image data
 33   """
 34  
 35   # 定义一个空的类对象,类似于c语言里面的结构体定义
 36   class CIFAR10Record(object):
 37     pass
 38   result = CIFAR10Record()
 39   label_bytes = 1  # 2 for CIFAR-100
 40   result.height = 32
 41   result.width = 32
 42   result.depth = 3
 43   #一张图像占用空间空间
 44   image_bytes = result.height * result.width * result.depth
 45   #数据集中一条记录占的字节数
 46   record_bytes = label_bytes + image_bytes
 47   # 定义一个Reader,它每次能从文件中读取固定字节数
 48   reader = tf.FixedLengthRecordReader(record_bytes=record_bytes)
 49   # 返回从filename_queue中读取的(key, value)对,key和value都是字符串类型的tensor,并且当队列中的某一个文件读完成时,该文件名会dequeue
 50   result.key, value = reader.read(filename_queue)
 51   # 解码操作可以看作读二进制文件,把字符串中的字节转换为数值向量,每一个数值占用一个字节,在[0, 255]区间内,因此out_type要取uint8类型
 52   record_bytes = tf.decode_raw(value, tf.uint8)#将字符串Tensor转化成uint8类型
 53   # 从一维tensor对象中截取一个slice,类似于从一维向量中筛选子向量,因为record_bytes中包含了label和feature,故要对向量类型tensor进行'parse'(语法分析)操作
 54   #分别表示待截取片段的起点和长度,并且把标签由之前的uint8转变成int32数据类型
 55   result.label = tf.cast(tf.strided_slice(record_bytes, [0], [label_bytes]), tf.int32)
 56   #提取每条记录中的图像数据为result.depth, result.height, result.width
 57   depth_major = tf.reshape(tf.strided_slice(record_bytes, [label_bytes],[label_bytes + image_bytes]),[result.depth, result.height, result.width])
 58   #改变为height, width, depth
 59   result.uint8image = tf.transpose(depth_major, [1, 2, 0])#转置
 60   return result
 61  
 62 # 构建一个排列后的一组图片和分类
 63 def _generate_image_and_label_batch(image, label, min_queue_examples,
 64                                     batch_size, shuffle):
 65   """Construct a queued batch of images and labels.
 66   Args:
 67     image: 3-D Tensor of [height, width, 3] of type.float32.
 68     label: 1-D Tensor of type.int32
 69     min_queue_examples: int32, minimum number of samples to retain
 70       in the queue that provides of batches of examples.
 71     batch_size: Number of images per batch.
 72     shuffle: boolean indicating whether to use a shuffling queue.
 73   Returns:
 74     images: Images. 4D tensor of [batch_size, height, width, 3] size.
 75     labels: Labels. 1D tensor of [batch_size] size.
 76   """
 77   
 78   #线程数
 79   num_preprocess_threads = 16
 80   #布尔指示是否使用一个shuffling队列
 81   if shuffle:    #随即填充张量创建批次
 82     images, label_batch = tf.train.shuffle_batch([image, label],batch_size=batch_size,num_threads=num_preprocess_threads,capacity=min_queue_examples + 3 * batch_size,min_after_dequeue=min_queue_examples)
 83   else:
 84       # tf.train.batch(tensors, batch_size, num_threads=1, capacity=32,enqueue_many=False, shapes=None, dynamic_pad=False,allow_smaller_final_batch=False, shared_name=None, name=None)
 85       #这里是用队列实现,已经默认使用enqueue_runner将enqueue_runner加入到Graph'senqueue_runner集合中
 86       #其默认enqueue_many=False时,输入的tensor为一个样本【x,y,z】,输出为Tensor的一批样本
 87     images, label_batch = tf.train.batch([image, label],batch_size=batch_size,num_threads=num_preprocess_threads,capacity=min_queue_examples + 3 * batch_size)
 88   #将训练图片可视化,可拱直接检查图片正误
 89   tf.summary.image('images', images)
 90   return images, tf.reshape(label_batch, [batch_size])
 91  
 92 # 为CIFAR评价构建输入
 93 # data_dir路径
 94 # batch_size一个组的大小
 95 def distorted_inputs(data_dir, batch_size):
 96   """
 97   Construct distorted input for CIFAR training using the Reader ops.
 98   Args:
 99     data_dir: Path to the CIFAR-10 data directory.
100     batch_size: Number of images per batch.
101   Returns:
102     images: Images. 4D tensor of [batch_size, IMAGE_SIZE, IMAGE_SIZE, 3] size.
103     labels: Labels. 1D tensor of [batch_size] size.
104   """
105   # 那5个数据文件名1-5
106   filenames = [os.path.join(data_dir, 'data_batch_%d.bin' % i) for i in xrange(1, 6)]
107   for f in filenames:
108     if not tf.gfile.Exists(f):
109       raise ValueError('Failed to find file: ' + f)
110  
111   filename_queue = tf.train.string_input_producer(filenames)
112   read_input = read_cifar10(filename_queue)
113   reshaped_image = tf.cast(read_input.uint8image, tf.float32)
114   height = IMAGE_SIZE
115   width = IMAGE_SIZE
116   #对图片随机裁剪成24x24
117   distorted_image = tf.random_crop(reshaped_image, [height, width, 3])
118   # 水平(从左向右)随机翻转图形,0.5的概率
119   distorted_image = tf.image.random_flip_left_right(distorted_image)
120   # 通过随即因子调整图像亮度
121   distorted_image = tf.image.random_brightness(distorted_image,max_delta=63)
122   # 通过随机因子调整图像对比度
123   distorted_image = tf.image.random_contrast(distorted_image,lower=0.2, upper=1.8)
124   float_image = tf.image.per_image_standardization(distorted_image)
125   # 设置张量的shape
126   float_image.set_shape([height, width, 3])
127   read_input.label.set_shape([1])
128   # 确保洗牌的随机性
129   min_fraction_of_examples_in_queue = 0.4
130   min_queue_examples = int(NUM_EXAMPLES_PER_EPOCH_FOR_TRAIN * min_fraction_of_examples_in_queue)
131   print ('Filling queue with %d CIFAR images before starting to train. This will take a few minutes.' % min_queue_examples)
132   # Generate a batch of images and labels by building up a queue of examples.
133   return _generate_image_and_label_batch(float_image, read_input.label,min_queue_examples, batch_size,shuffle=True)
134  
135 # 为CIFAR评价构建输入
136 # eval_data使用训练还是评价数据集
137 # data_dir路径
138 # batch_size一个组的大小
139 def inputs(eval_data, data_dir, batch_size):
140   """
141   Construct input for CIFAR evaluation using the Reader ops.
142   Args:
143     eval_data: bool, indicating if one should use the train or eval data set.
144     data_dir: Path to the CIFAR-10 data directory.
145     batch_size: Number of images per batch.
146   Returns:
147     images: Images. 4D tensor of [batch_size, IMAGE_SIZE, IMAGE_SIZE, 3] size.
148     labels: Labels. 1D tensor of [batch_size] size.
149   """
150   if not eval_data:
151     filenames = [os.path.join(data_dir, 'data_batch_%d.bin' % i) for i in xrange(1, 6)]
152     num_examples_per_epoch = NUM_EXAMPLES_PER_EPOCH_FOR_TRAIN
153   else:
154     filenames = [os.path.join(data_dir, 'test_batch.bin')]
155     num_examples_per_epoch = NUM_EXAMPLES_PER_EPOCH_FOR_EVAL
156  
157   for f in filenames:
158     if not tf.gfile.Exists(f):
159       raise ValueError('Failed to find file: ' + f)
160  
161   # Create a queue that produces the filenames to read.
162   # 文件名队列
163   #def string_input_producer(string_tensor,
164                           # num_epochs=None,
165                           # shuffle=True,
166                           # seed=None,
167                           # capacity=32,
168                           # shared_name=None,
169                           # name=None,
170                           # cancel_op=None):
171   #根据上面的函数可以看出下面的这个默认对输入队列进行shuffle,string_input_producer返回的是字符串队列,
172   #使用enqueue_runner将enqueue_runner加入到Graph'senqueue_runner集合中
173   filename_queue = tf.train.string_input_producer(filenames)
174   # 从文件队列中读取解析出的图片队列
175   #read_cifar10从输入文件名队列中读取一条图像记录
176   read_input = read_cifar10(filename_queue)
177   # 将记录中的图像记录转换为float32
178   reshaped_image = tf.cast(read_input.uint8image, tf.float32)
179   height = IMAGE_SIZE
180   width = IMAGE_SIZE
181   # Crop the central [height, width] of the image. 24x24
182   resized_image = tf.image.resize_image_with_crop_or_pad(reshaped_image,height, width)
183   
184   # Subtract off the mean and divide by the variance of the pixels.
185   # 对图像数据进行归一化
186   float_image = tf.image.per_image_standardization(resized_image)
187  
188   # Set the shapes of tensors.
189   float_image.set_shape([height, width, 3])
190   read_input.label.set_shape([1])
191  
192   # Ensure that the random shuffling has good mixing properties.
193   min_fraction_of_examples_in_queue = 0.4
194   min_queue_examples = int(num_examples_per_epoch * min_fraction_of_examples_in_queue)
195 
196   # Generate a batch of images and labels by building up a queue of examples.
197   #根据当前记录中第一条记录的值,采用多线程的方法,批量读取一个batch中的数据
198   return _generate_image_and_label_batch(float_image, read_input.label, min_queue_examples, batch_size, shuffle=False)
View Code

猜你喜欢

转载自www.cnblogs.com/pacino12134/p/10278627.html