tensorflowxun训练自己的数据集之从tfrecords读取数据

  当训练数据量较小时,采用直接读取文件的方式,当训练数据量非常大时,直接读取文件的方式太耗内存,这时应采用高效的读取方法,读取tfrecords文件,这其实是一种二进制文件。tensorflow为其内置了各种存储和读取的函数,方便调用。

  不知道为啥,从tfrecords中读取数据用于训练时,收敛得更快,更平稳。上面两个图是使用tfrecords的准确率和loss值变化,下面是直接读取文件的准确率和loss值变化。

 

 

1 生成记录样本的记录文件

 1 root_dir = os.getcwd()
 2 
 3 def getTrianList():
 4     with open("train.txt","w") as f:
 5         for file in os.listdir(root_dir+'\\dataSet'):
 6             for picFile in os.listdir(root_dir+"\\dataSet\\"+file):
 7                 f.write("dataSet/"+file+"/"+picFile+" "+file+"\n")
 8                 print(picFile)
 9 if __name__=="__main__":
10     getTrianList()

  将样本文件路径和标签统一记录到一个txt中,后面生成tfrecords文件就是通过读取这些信息。

  

  注意文件路径和标签之间采用空格,不要使用制表符。

2 读取txt存于数组中

 

1 def load_file(example_list_file):
2     lines = np.genfromtxt(example_list_file,delimiter=" ",dtype=[('col1', 'S120'), ('col2', 'i8')])
3     examples = []
4     labels = []
5     for example,label in lines:
6         examples.append(example)
7         labels.append(label)
8     #convert to numpy array
9     return np.asarray(examples),np.asarray(labels),len(lines)

  这段代码主要用来读取第1步生成的txt,将文件路径和标签存于数组中

3 读取图片

1 def extract_image(filename,height,width):
2     print(filename)
3     image = cv2.imread(filename)
4     image = cv2.resize(image,(height,width))
5     b,g,r = cv2.split(image)
6     rgb_image = cv2.merge([r,g,b])
7     return rgb_image

  使用cv2读取图片文件

4 转化为tfrecords文件

 1 def trans2tfRecord(trainFile,name,output_dir,height,width):
 2     if not os.path.exists(output_dir) or os.path.isfile(output_dir):
 3         os.makedirs(output_dir)
 4     _examples,_labels,examples_num = load_file(train_file)
 5     filename = name + '.tfrecords'
 6     writer = tf.python_io.TFRecordWriter(filename)
 7     for i,[example,label] in enumerate(zip(_examples,_labels)):
 8         print("NO{}".format(i))
 9         #need to convert the example(bytes) to utf-8
10         example = example.decode("UTF-8")
11         image = extract_image(example,height,width)
12         image_raw = image.tostring()
13         example = tf.train.Example(features=tf.train.Features(feature={
14                 'image_raw':_bytes_feature(image_raw),
15                 'height':_int64_feature(image.shape[0]),
16                  'width': _int64_feature(32),  
17                 'depth': _int64_feature(32),  
18                  'label': _int64_feature(label)                        
19                 }))
20         writer.write(example.SerializeToString())
21     writer.close()
1 def _int64_feature(value):  
2     return tf.train.Feature(int64_list=tf.train.Int64List(value=[value]))  
3   
4 def _bytes_feature(value):  
5     return tf.train.Feature(bytes_list=tf.train.BytesList(value=[value]))  

5 从tfrecords中读取训练数据

 1 def read_tfRecord(file_tfRecord):
 2     queue = tf.train.string_input_producer([file_tfRecord])
 3     reader = tf.TFRecordReader()
 4     _,serialized_example = reader.read(queue)
 5     features = tf.parse_single_example(
 6             serialized_example,
 7             features={
 8           'image_raw': tf.FixedLenFeature([], tf.string),  
 9           'height': tf.FixedLenFeature([], tf.int64), 
10           'width':tf.FixedLenFeature([], tf.int64),
11           'depth': tf.FixedLenFeature([], tf.int64),  
12           'label': tf.FixedLenFeature([], tf.int64)  
13                     }
14             )
15     image = tf.decode_raw(features['image_raw'],tf.uint8)
16     #height = tf.cast(features['height'], tf.int64)
17     #width = tf.cast(features['width'], tf.int64)
18     image = tf.reshape(image,[32,32,3])
19     image = tf.cast(image, tf.float32)
20     image = tf.image.per_image_standardization(image)
21     label = tf.cast(features['label'], tf.int64)
22     print(image,label)
23     return image,label

  从tfrecords文件中读取image和label,训练的时候,直接使用tf.train.batch函数生成用于训练的batch即可。

1 image_batches,label_batches = tf.train.batch([image, label], batch_size=16, capacity=20)

  其余的部分跟之前的训练步骤一样。

posted @ 2017-07-29 21:14  康小武  阅读(14645)  评论(9编辑  收藏  举报