tfrecord文件生成与读取
生活随笔
收集整理的這篇文章主要介紹了
tfrecord文件生成与读取
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
參考博客——tensorflow-TFRecord 文件詳解
1. 生成tfrecord文件
代碼
2. 讀取tfrecord文件
從文件讀取有 3 大步驟
生成讀取器,不同類型的文件有對應的讀取器
把文件名列表生成隊列
用讀取器的 read 方法讀取隊列中的文件
3 代碼
3.1 dataset_to_tfrecord.py
import os import xml.etree.ElementTree as ET import tensorflow as tf from dataset_config import DIRECTORY_ANNOTATIONS,DIRECTORY_IMAGES,NUM_IMAGES_TFRECORD,labels_to_class from utils.data_process_util import int64_feature,float_feature,bytes_feature def _convert_to_example(img,img_shape,labels,trunacted,difficult,bndbox_size):'''將一張圖片使用example,轉換成protobuffer 格式:param img::param img_shape::param labels::param trunacted::param difficult::param bndbox_size::return:'''# 為了轉換需求,bbox由單個obj的四個位置值,# 轉變成四個位置的單獨列表# 即:[[12,120,330,333],[50,60,100,200]]————>[[12,50],[120,60],[330,100],[333,200]]ymin=[]xmin=[]ymax=[]xmax=[]for b in bndbox_size:ymin.append(b[0])xmin.append(b[1])ymax.append(b[2])xmax.append(b[3])img_format = b'JPEG'print(type(labels))for i,label in enumerate(labels):labels[i]=labels_to_class[label]print('trunacted:',trunacted,type(trunacted),len(trunacted))example = tf.train.Example(features=tf.train.Features(feature={'image/height':int64_feature(img_shape[0]),'image/width':int64_feature(img_shape[1]),'image/channels':int64_feature(img_shape[2]),'image/shape':int64_feature(img_shape),'image/object/bbox/xmin':float_feature(xmin),'image/object/bbox/ymin':float_feature(ymin),'image/object/bbox/xmax':float_feature(xmax),'image/object/bbox/ymax':float_feature(ymax),'image/object/bbox/label_text':int64_feature(labels),# 'image/object/bbox/trunacted':bytes_feature(trunacted),# 'image/object/bbox/difficult':bytes_feature(difficult),'image/object/bbox/format':bytes_feature(img_format),'image/object/bbox/data':bytes_feature(img)# 讀取的圖像值}))print(img_format)return exampledef _process_image(dataset_dir,img_name):'''讀取圖像和xml文件:param dataset_dir::param img_name::return:'''#1.讀取圖像#圖像路徑img_path = os.path.join(dataset_dir,DIRECTORY_IMAGES,img_name+'.jpg')img = tf.gfile.FastGFile(img_path,'rb').read()#tensorflow讀取圖像#2.讀取xml#xml路徑xml_path =os.path.join(dataset_dir,DIRECTORY_ANNOTATIONS,img_name+'.xml')tree = ET.parse(xml_path)root = tree.getroot()#獲取根節點,'annotation'標簽# 2.1獲取圖像尺寸信息size = root.find('size')img_shape=[int(size.find('height').text),int(size.find('width').text),int(size.find('depth').text)]#2.2 獲取bounding box 相關信息# bounding box可能有多個,用多個列表存儲相關信息。labels = []trunacted=[]difficult = []bndbox_sizes=[]bboxes = root.findall('object')for obj in bboxes:label = obj.find('name').textif obj.find('trunacted'):trunacted.append(obj.find('trunacted').text)else:trunacted.append('0')if obj.find(''):difficult.append(obj.find('difficult').text)else:difficult.append(0)bndbox = obj.find('bndbox')bndbox_size=(float(bndbox.find('ymin').text)/img_shape[0],float(bndbox.find('xmin').text)/img_shape[1],float(bndbox.find('ymax').text)/img_shape[0],float(bndbox.find('xmax').text)/img_shape[1])labels.append(label)trunacted.append(trunacted)difficult.append(difficult)bndbox_sizes.append(bndbox_size)return img,img_shape,labels,trunacted,difficult,bndbox_sizesdef _add_to_tfrecord(dataset_dir,img_name,tfrecord_writer):'''讀取圖片和xml文件,保存成一個Example:param dataset_dir:根目錄:param img_name:圖像名稱:param tfrecord_writer::return:'''#1.讀取圖片內容及相應的xml文件img, img_shape, labels, trunacted, difficult, bndbox_size=_process_image(dataset_dir,img_name)# return img,img_shape,labels,trunacted,difficult,bndbox_size#2.讀取的內容封裝成Example,example = _convert_to_example(img, img_shape, labels, trunacted, difficult, bndbox_size)#3.Example序列化結果寫入指定tfrecord文件tfrecord_writer.write(example.SerializeToString())def _get_output_tfrecord_name(output_dir,name,fdx):""":param output_dir::param name::param fdx:第幾個tfrecord文件:return:"""return os.path.join(output_dir,name,'%06d'%fdx+'.tfrecord')def read_tfrecord():slim = tf.contrib.slimdataset = slim.dataset#第一個參數,文件路徑file_pattern = os.path.join('tf_records\data','*.record')#第二個參數reader = tf.TFRecordReader# file_pattern = '%s-* ' # 前面保存的tfrecord文件的文件名類似于“train-00001-of-00004.tfrecord”# file_pattern = os.path.join(dataset_dir, file_pattern % split_name) # dataset_dir即前面保存的tfrecord文件的路徑# 使用slim中的函數tf.FixedLenFeature將tfrecord的example反序列化成存儲之前的格式,# 字符串格式的用''表示,整型格式的用0表示,其他確定的信息還原為原來的形式,如'jpeg','png'keys_to_features = {'image/object/bbox/data': tf.FixedLenFeature((), tf.string, default_value=''),'image/object/bbox/format': tf.FixedLenFeature((), tf.string, default_value='jpeg'),'image/height': tf.FixedLenFeature((), tf.int64, default_value=0),'image/width': tf.FixedLenFeature((), tf.int64, default_value=0),'image/object/bbox/label_text': tf.FixedLenFeature((), tf.int64, default_value=0)}# 將反序列化的數據重組為更適合網絡讀入的格式items_to_handlers = {'image': slim.tfexample_decoder.Image(image_key='image/object/bbox/data',format_key='image/object/bbox/format',channels=3),# 'image_name': tfexample_decoder.Tensor('image/filename'),'height': slim.tfexample_decoder.Tensor('image/height'),'width': slim.tfexample_decoder.Tensor('image/width'),# 'labels_class': tfexample_decoder.Image(# image_key='image/segmentation/class/encoded',# format_key='image/segmentation/class/format',# channels=1)}# 解碼器進行解碼,定義一個解碼器對象,保存到dataset中# 第三個參數decoderdecoder = slim.tfexample_decoder.TFExampleDecoder(keys_to_features, items_to_handlers)# 返回由tfrecord信息所得到的數據集dataset,dataset對象定義了數據集的文件位置,解碼方式等元信息dataset = dataset.Dataset(data_sources=file_pattern, # tfrecord路徑reader=tf.TFRecordReader, # 讀取tfrecord文件的方式decoder=decoder, # 解碼tfrecord文件的方式num_samples=1464, # PASCAL-VOC2012數據集訓練樣本數items_to_descriptions={ # 樣本集圖像和標簽描述'image': 'A color image of varying height and width.','labels_class': ('A semantic segmentation label whose size matches image.''Its values range from 0 (background) to num_classes.')},num_classes = 3, # 數據集包含類別數(20個前景類別和1個背景類別)multi_label = True) # 多標簽(具體我也不太清楚)dataset_data_provider = slim.dataset_data_providerprefetch_queue = slim.prefetch_queue# 創建一個DatasetDataProvider類的對象data_provider,根據dataset和其他的一些已知信息讀取數據。data_provider = dataset_data_provider.DatasetDataProvider(dataset,num_readers=1,num_epochs=None,shuffle=True)# 通過調用data_provider對象的get實例函數能夠根據data_provider中給出的信息解讀tfrecord文件,生成圖像和標簽和圖像文件名image, height, width = data_provider.get(['image', 'height', 'width'])# image_name, = data_provider.get(['image_name'])# label = data_provider.get(['label'])# 圖像預處理過程,這里具體的處理過程與本文主題無關,因此省略具體的處理過程return image, height, widthdef run(dataset_dir,output_dir,name='data'):"""運行轉換代碼邏輯。存入多個tfrecord文件,每個文件固定N個樣本:param dataset_dir:數據集目錄,包含annotations,jpeg文件夾:param output_dir:tfrecords存儲目錄:param name:數據集名字,指定名字以及train or test:return:"""# 1. 判斷數據集目錄是否存在,創建一個目錄if tf.gfile.Exists(dataset_dir):tf.gfile.MakeDirs(dataset_dir)# 輸出路徑需要已存在# if tf.gfile.Exists(output_dir):# tf.gfile.MakeDirs(output_dir)# 2. 讀取某個文件夾下的所有文件名字列表dir_path = os.path.join(dataset_dir,DIRECTORY_ANNOTATIONS)files_path = sorted(os.listdir(dir_path))print(files_path)# 3. 循環名字列表,# 每200(NUM_IMAGES_TFRECORD)個圖片及xml文件存儲到一個tfrecord文件中num = len(files_path)i = 0fdx = 0while i < num:tf_record_name = _get_output_tfrecord_name(output_dir,name,fdx)with tf.python_io.TFRecordWriter(tf_record_name) as tf_record_writer:j = 0while i<num and j < NUM_IMAGES_TFRECORD:xml_path = files_path[i]img_name = xml_path.split('.')[0]#每個圖像構建一個Example,保存到tf_record_name中_add_to_tfrecord(dataset_dir,img_name,tf_record_writer)j += 1i += 1fdx += 1print('fdx',fdx)print('數據集%s轉換成功'%(dataset_dir))3.2 tfrecord文件讀取
def read_tfrecord():slim = tf.contrib.slimdataset = slim.dataset#第一個參數,文件路徑file_pattern = os.path.join('tf_records\data','*.tfrecord')#第二個參數reader = tf.TFRecordReader# file_pattern = '%s-* ' # 前面保存的tfrecord文件的文件名類似于“train-00001-of-00004.tfrecord”# file_pattern = os.path.join(dataset_dir, file_pattern % split_name) # dataset_dir即前面保存的tfrecord文件的路徑# 使用slim中的函數tf.FixedLenFeature將tfrecord的example反序列化成存儲之前的格式,# 字符串格式的用''表示,整型格式的用0表示,其他確定的信息還原為原來的形式,如'jpeg','png'keys_to_features = {'image/object/bbox/data': tf.FixedLenFeature((), tf.string, default_value=''),'image/object/bbox/format': tf.FixedLenFeature((), tf.string, default_value='jpeg'),'image/height': tf.FixedLenFeature((), tf.int64, default_value=0),'image/width': tf.FixedLenFeature((), tf.int64, default_value=0),'image/object/bbox/label_text': tf.FixedLenFeature((), tf.int64, default_value=0)}# 將反序列化的數據重組為更適合網絡讀入的格式items_to_handlers = {'image': slim.tfexample_decoder.Image(image_key='image/object/bbox/data',format_key='image/object/bbox/format',channels=3),# 'image_name': tfexample_decoder.Tensor('image/filename'),'height': slim.tfexample_decoder.Tensor('image/height'),'width': slim.tfexample_decoder.Tensor('image/width'),# 'labels_class': tfexample_decoder.Image(# image_key='image/segmentation/class/encoded',# format_key='image/segmentation/class/format',# channels=1)}# 解碼器進行解碼,定義一個解碼器對象,保存到dataset中# 第三個參數decoderdecoder = slim.tfexample_decoder.TFExampleDecoder(keys_to_features, items_to_handlers)# 返回由tfrecord信息所得到的數據集dataset,dataset對象定義了數據集的文件位置,解碼方式等元信息dataset = dataset.Dataset(data_sources=file_pattern, # tfrecord路徑reader=tf.TFRecordReader, # 讀取tfrecord文件的方式decoder=decoder, # 解碼tfrecord文件的方式num_samples=1464, # PASCAL-VOC2012數據集訓練樣本數items_to_descriptions={ # 樣本集圖像和標簽描述'image': 'A color image of varying height and width.','labels_class': ('A semantic segmentation label whose size matches image.''Its values range from 0 (background) to num_classes.')},num_classes = 3, # 數據集包含類別數(20個前景類別和1個背景類別)multi_label = True) # 多標簽(具體我也不太清楚)dataset_data_provider = slim.dataset_data_providerprefetch_queue = slim.prefetch_queue# 創建一個DatasetDataProvider類的對象data_provider,根據dataset和其他的一些已知信息讀取數據。data_provider = dataset_data_provider.DatasetDataProvider(dataset,num_readers=1,num_epochs=None,shuffle=True)# 通過調用data_provider對象的get實例函數能夠根據data_provider中給出的信息解讀tfrecord文件,生成圖像和標簽和圖像文件名image, height, width = data_provider.get(['image', 'height', 'width'])# image_name, = data_provider.get(['image_name'])# label = data_provider.get(['label'])# 圖像預處理過程,這里具體的處理過程與本文主題無關,因此省略具體的處理過程return image, height, width總結
以上是生活随笔為你收集整理的tfrecord文件生成与读取的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 基于tensorflow框架的神经网络结
- 下一篇: 120. 三角形最小路径和