天天看點

Pascal VOC資料集轉成tfrecord檔案形式---------------------解讀!!!原因:我自己想對資料集進行一些預處理,看大神的代碼,終于了解是怎麼轉成tensorflow的資料檔案tfrecord!!!!

原因:我自己想對資料集進行一些預處理,看大神的代碼,終于了解是怎麼轉成tensorflow的資料檔案tfrecord!!!!

代碼連結:https://github.com/HiKapok/SSD.TensorFlow

什麼是TFRecord?

       TRecord資料檔案是一種将圖像資料和标簽統一存儲的二進制檔案,能更好的利用記憶體,在TensorFlow中快速的複制,移動,讀取,存儲等。對于我們普通開發者而言,我們并不需要關心這些,Tensorflow 提供了豐富的 API 可以幫助我們輕松讀寫 TFRecord檔案。我們隻關心如何使用Tensorflow生成TFRecord,并且讀取它。

1.将資料儲存為tfrecords

       TFRecords檔案包含了tf.train.Example協定記憶體塊(protocol buffer)(協定記憶體塊包含了字段 Features)。我們可以寫一段代碼擷取你的資料, 将資料填入到Example協定記憶體塊(protocol buffer),将協定記憶體塊序列化為一個字元串, 并且通過tf.python_io.TFRecordWriter寫入到TFRecords檔案。

流程:

1. 将資料填入

example protocol buffer

2. 将

protocol buffer

序列化為一個字元串 

3. 通過

tf.python_io.TFRecordWriter

将字元串寫入

TFRecords

檔案

我們首先看convert_tfrecords.py

1.給的參數:

你的資料集存放的方式:

'''How to organize your dataset folder:
  VOCROOT/
       |->VOC2007/
       |    |->Annotations/
       |    |->ImageSets/
       |    |->...
       |->VOC2012/
       |    |->Annotations/
       |    |->ImageSets/
       |    |->...
       |->VOC2007TEST/
       |    |->Annotations/
       |    |->...
'''      
tf.app.flags.DEFINE_string('dataset_directory', 'D:/Program Files(x86)/PycharmProjects/VOCROOT/',
                           'All datas directory')  #所有檔案的路徑
tf.app.flags.DEFINE_string('train_splits', 'VOC2007, VOC2012',
                           'Comma-separated list of the training data sub-directory') #訓練資料子檔案夾分别的目錄名字
tf.app.flags.DEFINE_string('validation_splits', 'VOC2007TEST',
                           'Comma-separated list of the validation data sub-directory')  #測試資料集子目錄的名字
tf.app.flags.DEFINE_string('output_directory', 'D:/Program Files(x86)/PycharmProjects/convert-tf/dataset/tfrecords/',
                           'Output data directory')     #輸出的tfrecord所在檔案夾位置
tf.app.flags.DEFINE_integer('train_shards', 16,
                            'Number of shards in training TFRecord files.')  #訓練tfrecord檔案夾中的碎片數量16
tf.app.flags.DEFINE_integer('validation_shards', 16,
                            'Number of shards in validation TFRecord files.') #測試tfrecord檔案夾中的碎片數量16
tf.app.flags.DEFINE_integer('num_threads', 8,
                            'Number of threads to preprocess the images.')  #預處理圖像的線程數8
           

 2.将資料集轉化成對應的類型:

def _int64_feature(value):
  """Wrapper for inserting int64 features into Example proto."""
  if not isinstance(value, list):   #資料類型檢查
    value = [value]
  return tf.train.Feature(int64_list=tf.train.Int64List(value=value))


def _float_feature(value):
  """Wrapper for inserting float features into Example proto."""
  if not isinstance(value, list):
    value = [value]
  return tf.train.Feature(float_list=tf.train.FloatList(value=value))

def _bytes_list_feature(value):
    """Wrapper for inserting a list of bytes features into Example proto.
    """
    if not isinstance(value, list):
        value = [value]
    return tf.train.Feature(bytes_list=tf.train.BytesList(value=value))

def _bytes_feature(value):
  """Wrapper for inserting bytes features into Example proto."""
  if isinstance(value, six.string_types):
    value = six.binary_type(value, encoding='utf-8')
  return tf.train.Feature(bytes_list=tf.train.BytesList(value=[value]))
           

 3.我們從主函數看起:一步一步調用到另一個函數。

def main(unused_argv):
    #斷言,%取餘
  assert not FLAGS.train_shards % FLAGS.num_threads, (
      'Please make the FLAGS.num_threads commensurate with FLAGS.train_shards')
  assert not FLAGS.validation_shards % FLAGS.num_threads, (
      'Please make the FLAGS.num_threads commensurate with '
      'FLAGS.validation_shards')
  print('Saving results to %s' % FLAGS.output_directory)

  # Run it!
  _process_dataset('val', FLAGS.dataset_directory, parse_comma_list(FLAGS.validation_splits), FLAGS.validation_shards)
  _process_dataset('train', FLAGS.dataset_directory, parse_comma_list(FLAGS.train_splits), FLAGS.train_shards)
           

 這裡首先要保證train_shards/num_threads是整數,

train_shards:将訓練資料集分成幾塊,這裡我們上面給的參數是16,就是分成16塊,就是最後的訓練資料就是16個tfrecord格式的檔案。

num_threads:是線程的數量,這裡給的參數是8,采用8個線程産生資料。注意:線程數必須要被能整出train_shards和validation_shards,來保證每個線程處理的資料塊數是相同的。

也就是16/8=2,每個線程處理2個tfrecord.。首先輸出圖檔儲存的路徑,然後調用第一個函數_process_dataset(),我們以train舉例

3.1

_process_dataset('train', FLAGS.dataset_directory, parse_comma_list(FLAGS.train_splits), FLAGS.train_shards)
      

parse_comma_list()是作者自己寫的函數:比如前面給的參數train_splits是‘VOC2007, VOC2012’就是将字元串取出來一個個VOC2007,VOC2012這個取出來,為了後面的路徑。

strip()是去除空格的,split()是通過指定分隔符對字元串進行切片。

Pascal VOC資料集轉成tfrecord檔案形式---------------------解讀!!!原因:我自己想對資料集進行一些預處理,看大神的代碼,終于了解是怎麼轉成tensorflow的資料檔案tfrecord!!!!

現在看process_dataset 

#處理一個完整的資料集将其儲存成tfrecord
def _process_dataset(name, directory, all_splits, num_shards):
  """Process a complete data set and save it as a TFRecord.

  Args:
    name: string, unique identifier specifying the data set.字元串資料集的唯一辨別符
    directory: string, root path to the data set.目錄:字元串,資料集的根路徑
    all_splits: list of strings, sub-path to the data set.字元串清單,資料集的子路徑
    num_shards: integer number of shards for this data set.此資料集的碎片數
  """
  all_records = []
  for split in all_splits:
    jpeg_file_path = os.path.join(directory, split, 'JPEGImages')  #拼接路徑
    images = tf.gfile.ListDirectory(jpeg_file_path) #羅列path下所有的檔案并以清單傳回,參數必須是目錄名
    jpegs = [im_name for im_name in images if im_name.strip()[-3:]=='jpg']  #strip()移除字元串頭尾指定的字元
    #等價于
    #jpegs =[]
    #for im_name in images:
    #   if im_name.strip()[-3:]=='jpg':
    #      jpegs.append(im_name))

    all_records.extend(list(zip([split] * len(jpegs), jpegs)))  #清單添加元素
    #當zip()函數有兩個參數時,zip(a,b)函數分别從a和b中取一個元素組成元組,
    # 再次将組成的元組組合成一個新的疊代器。a與b的維數相同時,
    # 正常組合對應位置的元素。當a與b行或列數不同時,取兩者中的最小的行列數。
  #不懂
  #打亂指數
  shuffled_index = list(range(len(all_records)))
  random.seed(RANDOM_SEED)  #使得随機資料可預測,隻要給的seed值一樣,後續生成的随機數都是一樣的
  random.shuffle(shuffled_index)  #打亂清單順序,在序列的本身打亂,多元數組隻對行之間進行洗牌,行内内容不變
  all_records = [all_records[i] for i in shuffled_index]
  _process_image_files(name, directory, all_records, num_shards)
  #all_records=22136,這裡的内容是(voc2007,圖檔的名字)
           

 将一個完成的資料集儲存成TFRecord,參數:name是資料集的名稱,directory:是資料集的根目錄,all_splits是一個字元串的清單,資料集的子路徑;num_shards:是此資料分成幾塊,我就稱為碎片數吧。解釋:我的代碼注釋很清楚。

3.2 

_process_image_files(name, directory, all_records, num_shards)      

調用這個函數,處理并且儲存圖像清單作為示例協定的TFRecord,參數:name是一個資料集的唯一标定比如VOC2007,

directory:資料的路徑,all_records:是一個字元串元組,組成的清單,第一個元組是子目錄,第二個元組是圖像檔案名,

num_shards:這個資料集的分塊數

def _process_image_files(name, directory, all_records, num_shards):
  """Process and save list of images as TFRecord of Example protos.處理并儲存圖像清單作為示例協定的TFRecord。

  Args:
    name: string, unique identifier specifying the data set
    directory: string; the path of all datas
    all_records: list of string tuples; the first of each tuple is the sub-directory of the record, the second is the image filename.
    #all_records:字元串元組清單;每個元組的第一個是記錄的子目錄,第二個是圖像檔案名。
    num_shards: integer number of shards for this data set.
  """
  #使用[range [i][0], range [i][1]]将所有圖像分成批次。
  # Break all images into batches with a [ranges[i][0], ranges[i][1]].
  spacing = np.linspace(0, len(all_records), FLAGS.num_threads + 1).astype(np.int)
  #linspace()函數建立一個等差數列,前兩個參數是數列的開始和結尾,第三個參數是指定數列的元素個數
  ranges = []   #就是把資料集分成8分,每一份的索引區間,22136/9=x ranges=[[0,x],[x,2x],...[8x,22136]]
  threads = []
  for i in range(len(spacing) - 1):
    ranges.append([spacing[i], spacing[i + 1]])

  # Launch a thread for each batch.為每個批次啟動一個線程。
  print('Launching %d threads for spacings: %s' % (FLAGS.num_threads, ranges))
  sys.stdout.flush()

  # Create a mechanism for monitoring when all threads are finished.建立一個監視所有線程何時完成的機制。
  coord = tf.train.Coordinator()

  # Create a generic TensorFlow-based utility for converting all image codings.建立一個基于TensorFlow的通用實用程式,用于轉換所有圖像編碼。
  coder = ImageCoder()

  threads = []
  for thread_index in range(len(ranges)):
    args = (coder, thread_index, ranges, name, directory, all_records, num_shards)  #元組
    t = threading.Thread(target=_process_image_files_batch, args=args)
    t.start()
    threads.append(t)

  # Wait for all the threads to terminate.
  coord.join(threads)
  print('%s: Finished writing all %d images in data set.' %
        (datetime.now(), len(all_records)))
  sys.stdout.flush()
           

這裡調用了三個函數: 

_find_image_bounding_boxes(directory, cur_record)      
_process_image(filename, coder)      
_convert_to_example(filename, cur_record[1], image_buffer, bboxes, labels, labels_text,
                              difficult, truncated, height, width)      

3.3_find_image_bounding_boxes(directory, cur_record),找到目前路徑的bounding_boxes,解析

Annotations檔案裡面的xml檔案資料。      
def _find_image_bounding_boxes(directory, cur_record):
  """Find the bounding boxes for a given image file.

  Args:
    directory: string; the path of all datas.
    cur_record: list of strings; the first of which is the sub-directory of cur_record, the second is the image filename.
  Returns:
    bboxes: List of bounding boxes for each image.
    labels: List of labels for bounding box.
    labels_text: List of labels' name for bounding box.
    difficult: List of ints indicate the difficulty of that bounding box.
    truncated: List of ints indicate the truncation of that bounding box.
  """
  anna_file = os.path.join(directory, cur_record[0], 'Annotations', cur_record[1].replace('jpg', 'xml'))

  tree = xml_tree.parse(anna_file)  #打開xml檔案
  root = tree.getroot()   #擷取根節點

  # Image shape.
  size = root.find('size')
  shape = [int(size.find('height').text),
           int(size.find('width').text),
           int(size.find('depth').text)]
  # Find annotations.
  bboxes = []
  labels = []
  labels_text = []
  difficult = []
  truncated = []
  #查找子節點
  for obj in root.findall('object'):
      label = obj.find('name').text.strip()  #strip()沒有傳入參數就是去除空格
      labels.append(int(dataset_common.VOC_LABELS[label][0]))
      labels_text.append(label.encode('ascii'))  #變為ascii格式

      isdifficult = obj.find('difficult')
      if isdifficult is not None:
          difficult.append(int(isdifficult.text))
      else:
          difficult.append(0)

      istruncated = obj.find('truncated')
      if istruncated is not None:
          truncated.append(int(istruncated.text))
      else:
          truncated.append(0)

      bbox = obj.find('bndbox')
      #(pascal_voc标注是1-based,是以需要-1轉化成0-based,如果我們的資料标注是0-based,再-1就可能溢出,是以要去掉)
      # 。如果隻是0-based的問題(而沒有标注為負數或超出圖像邊界的坐标),這裡就應該解決問題了。
      #就是指左上角的坐标(x1,y1)
      bboxes.append((float(bbox.find('ymin').text) - 1.,
                     float(bbox.find('xmin').text) - 1.,
                     float(bbox.find('ymax').text) - 1.,
                     float(bbox.find('xmax').text) - 1.
                     ))
  return bboxes, labels, labels_text, difficult, truncated
           

 3.4

#圖檔處理
def _process_image(filename, coder):
  """Process a single image file.

  Args:
    filename: string, path to an image file e.g., '/path/to/example.JPG'.
    coder: instance of ImageCoder to provide TensorFlow image coding utils.#執行個體ImageCoder來提供TensorFlow圖像編碼utils。
  Returns:
    image_buffer: string, JPEG encoding of RGB image.RGB圖像的JPEG編碼
    height: integer, image height in pixels.
    width: integer, image width in pixels.
  """
  # Read the image file.,下面函數實作對圖檔的讀取
  with tf.gfile.FastGFile(filename, 'rb') as f:
    image_data = f.read()

  # Decode the RGB JPEG.
  image = coder.decode_jpeg(image_data)

  # Check that image converted to RGB
  assert len(image.shape) == 3
  height = image.shape[0]
  width = image.shape[1]
  assert image.shape[2] == 3

  return image_data, height, width
           

3.5 

_convert_to_example      
def _convert_to_example(filename, image_name, image_buffer, bboxes, labels, labels_text,
                        difficult, truncated, height, width):
  """Build an Example proto for an example.建構一個示例proto作為示例。

  Args:#參數
    filename: string, path to an image file, e.g., '/path/to/example.JPG'圖像檔案的路徑
    image_buffer: string, JPEG encoding of RGB image字元串,RGB圖像的JPEG編碼
    bboxes: List of bounding boxes for each image 每個圖像的包圍框清單
    labels: List of labels for bounding box       包圍框标簽清單
    labels_text: List of labels' name for bounding box   用于包圍框的标簽名稱清單
    difficult: List of ints indicate the difficulty of that bounding box int清單表示該邊框的難度
    truncated: List of ints indicate the truncation of that bounding box int清單表示該邊框的截斷
    height: integer, image height in pixels  整數,圖像高度(以像素為機關)
    width: integer, image width in pixels     :整數,圖像寬度(以像素為機關)
  Returns:
    Example proto
  """
  ymin = []
  xmin = []
  ymax = []
  xmax = []
  for b in bboxes:
    assert len(b) == 4   #斷言函數,如果不滿足這個條件,程式退出
    # pylint: disable=expression-not-assigned
    #zip()打包成元組,傳回由這些元組組成的清單
    [l.append(point) for l, point in zip([ymin, xmin, ymax, xmax], b)]
    #把b裡面4個元素放進[ymin,xmin,ymax,xmax]第一個放ymin...
    # pylint: enable=expression-not-assigned
  channels = 3
  image_format = 'JPEG'

  example = tf.train.Example(features=tf.train.Features(feature={
            'image/height': _int64_feature(height),
            'image/width': _int64_feature(width),
            'image/channels': _int64_feature(channels),
            'image/shape': _int64_feature([height, width, channels]),
            'image/object/bbox/xmin': _float_feature(xmin),
            'image/object/bbox/xmax': _float_feature(xmax),
            'image/object/bbox/ymin': _float_feature(ymin),
            'image/object/bbox/ymax': _float_feature(ymax),
            'image/object/bbox/label': _int64_feature(labels),
            'image/object/bbox/label_text': _bytes_list_feature(labels_text),
            'image/object/bbox/difficult': _int64_feature(difficult),
            'image/object/bbox/truncated': _int64_feature(truncated),
            'image/format': _bytes_feature(image_format),  #圖像編碼格式
            'image/filename': _bytes_feature(image_name.encode('utf8')),
            'image/encoded': _bytes_feature(image_buffer)}))  #圖像資料
  return example
#以上函數就是每次讀取一張圖檔檔案及其對應的标注檔案并處理
           

這個寫入example的過程有點複雜。 

Example,初始化為tf.train.Example() 

包含字段features=tf.train.Features() 

字段features包含一個或多個: feature={"key": tf.train.Feature()} 

feature是基于key-value對的存儲,key是字元串,其映射到的是value 包含3種資料類型: 

1. BytesList: 字元串清單: tf.train.BytesList(value=[value]) 

2. FloatList: 浮點數清單tf.train.FloatList() 

3. Int64List: 64位整數清單tf.train.Int64List() 

對于圖檔的numpy數組,可以.tostring之後存到BytesList,可以tf.gfile.FastGFile讀入成bytes存到BytesList,可以.flatten後存到FloatList

Example中有幾個一緻性規則需要注意: 

1. 如果一個example的feature K的資料類型是T,那麼所有其他的所有feature K都應該是這個資料類型 

2. feature K 的value list的item個數可能在不同的example中是不一樣多的,這個取決于你的需求 

3. 如果在一個example中沒有feature k,那麼如果在解析的時候指定一個預設值的話,那麼将會傳回一個預設值 

4. 如果一個feature k 不包含任何的value值,那麼将會傳回一個空的tensor而不是預設值

 結果:

D:\Program Files\Anaconda3\python.exe" "D:/Program Files(x86)/PycharmProjects/convert-tf/dataset/convert_tfrecords.py"

Saving results to D:/Program Files(x86)/PycharmProjects/convert-tf/dataset/tfrecords/

Launching 8 threads for spacings: [[0, 619], [619, 1238], [1238, 1857], [1857, 2476], [2476, 3095], [3095, 3714], [3714, 4333], [4333, 4952]]

2019-05-10 20:19:23.022920: I T:\src\github\tensorflow\tensorflow\core\platform\cpu_feature_guard.cc:141] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2

2019-05-10 20:19:23.537115: I T:\src\github\tensorflow\tensorflow\core\common_runtime\gpu\gpu_device.cc:1392] Found device 0 with properties: 

name: Quadro P620 major: 6 minor: 1 memoryClockRate(GHz): 1.354

pciBusID: 0000:01:00.0

totalMemory: 2.00GiB freeMemory: 1.61GiB

2019-05-10 20:19:23.537576: I T:\src\github\tensorflow\tensorflow\core\common_runtime\gpu\gpu_device.cc:1471] Adding visible gpu devices: 0

2019-05-10 20:19:30.646848: I T:\src\github\tensorflow\tensorflow\core\common_runtime\gpu\gpu_device.cc:952] Device interconnect StreamExecutor with strength 1 edge matrix:

2019-05-10 20:19:30.647366: I T:\src\github\tensorflow\tensorflow\core\common_runtime\gpu\gpu_device.cc:958]      0 

2019-05-10 20:19:30.647704: I T:\src\github\tensorflow\tensorflow\core\common_runtime\gpu\gpu_device.cc:971] 0:   N 

2019-05-10 20:19:30.672063: I T:\src\github\tensorflow\tensorflow\core\common_runtime\gpu\gpu_device.cc:1084] Created TensorFlow device (/job:localhost/replica:0/task:0/device:GPU:0 with 1375 MB memory) -> physical GPU (device: 0, name: Quadro P620, pci bus id: 0000:01:00.0, compute capability: 6.1)

2019-05-10 20:19:47.105772 [thread 2]: Wrote 309 images to D:/Program Files(x86)/PycharmProjects/convert-tf/dataset/tfrecords/val-00004-of-00016

2019-05-10 20:19:47.469564 [thread 3]: Wrote 309 images to D:/Program Files(x86)/PycharmProjects/convert-tf/dataset/tfrecords/val-00006-of-00016

2019-05-10 20:19:47.858334 [thread 5]: Wrote 309 images to D:/Program Files(x86)/PycharmProjects/convert-tf/dataset/tfrecords/val-00010-of-00016

2019-05-10 20:19:48.088204 [thread 0]: Wrote 309 images to D:/Program Files(x86)/PycharmProjects/convert-tf/dataset/tfrecords/val-00000-of-00016

2019-05-10 20:19:48.431021 [thread 6]: Wrote 309 images to D:/Program Files(x86)/PycharmProjects/convert-tf/dataset/tfrecords/val-00012-of-00016

2019-05-10 20:19:48.637893 [thread 7]: Wrote 309 images to D:/Program Files(x86)/PycharmProjects/convert-tf/dataset/tfrecords/val-00014-of-00016

2019-05-10 20:19:48.853768 [thread 1]: Wrote 309 images to D:/Program Files(x86)/PycharmProjects/convert-tf/dataset/tfrecords/val-00002-of-00016

2019-05-10 20:19:49.213563 [thread 4]: Wrote 309 images to D:/Program Files(x86)/PycharmProjects/convert-tf/dataset/tfrecords/val-00008-of-00016

2019-05-10 20:20:01.406130 [thread 2]: Wrote 310 images to D:/Program Files(x86)/PycharmProjects/convert-tf/dataset/tfrecords/val-00005-of-00016

2019-05-10 20:20:01.406130 [thread 2]: Wrote 619 images to 619 shards.

2019-05-10 20:20:01.669947 [thread 6]: Wrote 310 images to D:/Program Files(x86)/PycharmProjects/convert-tf/dataset/tfrecords/val-00013-of-00016

2019-05-10 20:20:01.669947 [thread 6]: Wrote 619 images to 619 shards.

2019-05-10 20:20:02.097705 [thread 0]: Wrote 310 images to D:/Program Files(x86)/PycharmProjects/convert-tf/dataset/tfrecords/val-00001-of-00016

2019-05-10 20:20:02.098707 [thread 0]: Wrote 619 images to 619 shards.

2019-05-10 20:20:02.790308 [thread 5]: Wrote 310 images to D:/Program Files(x86)/PycharmProjects/convert-tf/dataset/tfrecords/val-00011-of-00016

2019-05-10 20:20:02.791309 [thread 5]: Wrote 619 images to 619 shards.

2019-05-10 20:20:03.366988 [thread 3]: Wrote 310 images to D:/Program Files(x86)/PycharmProjects/convert-tf/dataset/tfrecords/val-00007-of-00016

2019-05-10 20:20:03.366988 [thread 3]: Wrote 619 images to 619 shards.

2019-05-10 20:20:03.589887 [thread 4]: Wrote 310 images to D:/Program Files(x86)/PycharmProjects/convert-tf/dataset/tfrecords/val-00009-of-00016

2019-05-10 20:20:03.589887 [thread 4]: Wrote 619 images to 619 shards.

2019-05-10 20:20:03.802736 [thread 7]: Wrote 310 images to D:/Program Files(x86)/PycharmProjects/convert-tf/dataset/tfrecords/val-00015-of-00016

2019-05-10 20:20:03.802736 [thread 7]: Wrote 619 images to 619 shards.

2019-05-10 20:20:04.106557 [thread 1]: Wrote 310 images to D:/Program Files(x86)/PycharmProjects/convert-tf/dataset/tfrecords/val-00003-of-00016

2019-05-10 20:20:04.106557 [thread 1]: Wrote 619 images to 619 shards.

2019-05-10 20:20:04.405420: Finished writing all 4952 images in data set.

Launching 8 threads for spacings: [[0, 2767], [2767, 5534], [5534, 8301], [8301, 11068], [11068, 13835], [13835, 16602], [16602, 19369], [19369, 22136]]

2019-05-10 20:20:04.596152: I T:\src\github\tensorflow\tensorflow\core\common_runtime\gpu\gpu_device.cc:1471] Adding visible gpu devices: 0

2019-05-10 20:20:04.596538: I T:\src\github\tensorflow\tensorflow\core\common_runtime\gpu\gpu_device.cc:952] Device interconnect StreamExecutor with strength 1 edge matrix:

2019-05-10 20:20:04.596801: I T:\src\github\tensorflow\tensorflow\core\common_runtime\gpu\gpu_device.cc:958]      0 

2019-05-10 20:20:04.596975: I T:\src\github\tensorflow\tensorflow\core\common_runtime\gpu\gpu_device.cc:971] 0:   N 

2019-05-10 20:20:04.597205: I T:\src\github\tensorflow\tensorflow\core\common_runtime\gpu\gpu_device.cc:1084] Created TensorFlow device (/job:localhost/replica:0/task:0/device:GPU:0 with 1375 MB memory) -> physical GPU (device: 0, name: Quadro P620, pci bus id: 0000:01:00.0, compute capability: 6.1)

2019-05-10 20:22:19.931104 [thread 2]: Processed 1000 of 2767 images in thread batch.

2019-05-10 20:22:20.628721 [thread 5]: Processed 1000 of 2767 images in thread batch.

2019-05-10 20:22:20.747640 [thread 0]: Processed 1000 of 2767 images in thread batch.

2019-05-10 20:22:22.375711 [thread 7]: Processed 1000 of 2767 images in thread batch.

2019-05-10 20:22:22.559604 [thread 1]: Processed 1000 of 2767 images in thread batch.

2019-05-10 20:22:24.088742 [thread 6]: Processed 1000 of 2767 images in thread batch.

2019-05-10 20:22:24.108723 [thread 4]: Processed 1000 of 2767 images in thread batch.

2019-05-10 20:22:24.798327 [thread 3]: Processed 1000 of 2767 images in thread batch.

2019-05-10 20:23:01.115620 [thread 2]: Wrote 1383 images to D:/Program Files(x86)/PycharmProjects/convert-tf/dataset/tfrecords/train-00004-of-00016

2019-05-10 20:23:02.034104 [thread 5]: Wrote 1383 images to D:/Program Files(x86)/PycharmProjects/convert-tf/dataset/tfrecords/train-00010-of-00016

2019-05-10 20:23:02.348917 [thread 0]: Wrote 1383 images to D:/Program Files(x86)/PycharmProjects/convert-tf/dataset/tfrecords/train-00000-of-00016

2019-05-10 20:23:03.891037 [thread 7]: Wrote 1383 images to D:/Program Files(x86)/PycharmProjects/convert-tf/dataset/tfrecords/train-00014-of-00016

2019-05-10 20:23:04.100928 [thread 3]: Wrote 1383 images to D:/Program Files(x86)/PycharmProjects/convert-tf/dataset/tfrecords/train-00006-of-00016

2019-05-10 20:23:04.232874 [thread 1]: Wrote 1383 images to D:/Program Files(x86)/PycharmProjects/convert-tf/dataset/tfrecords/train-00002-of-00016

2019-05-10 20:23:04.508716 [thread 4]: Wrote 1383 images to D:/Program Files(x86)/PycharmProjects/convert-tf/dataset/tfrecords/train-00008-of-00016

2019-05-10 20:23:05.688044 [thread 6]: Wrote 1383 images to D:/Program Files(x86)/PycharmProjects/convert-tf/dataset/tfrecords/train-00012-of-00016

2019-05-10 20:23:58.257034 [thread 0]: Processed 2000 of 2767 images in thread batch.

2019-05-10 20:23:58.361986 [thread 3]: Processed 2000 of 2767 images in thread batch.

2019-05-10 20:23:59.171511 [thread 5]: Processed 2000 of 2767 images in thread batch.

2019-05-10 20:23:59.753180 [thread 2]: Processed 2000 of 2767 images in thread batch.

2019-05-10 20:24:00.065002 [thread 6]: Processed 2000 of 2767 images in thread batch.

2019-05-10 20:24:00.320873 [thread 4]: Processed 2000 of 2767 images in thread batch.

2019-05-10 20:24:00.415822 [thread 1]: Processed 2000 of 2767 images in thread batch.

2019-05-10 20:24:01.776026 [thread 7]: Processed 2000 of 2767 images in thread batch.

2019-05-10 20:25:02.162595 [thread 0]: Wrote 1384 images to D:/Program Files(x86)/PycharmProjects/convert-tf/dataset/tfrecords/train-00001-of-00016

2019-05-10 20:25:02.163592 [thread 0]: Wrote 2767 images to 2767 shards.

2019-05-10 20:25:02.695321 [thread 3]: Wrote 1384 images to D:/Program Files(x86)/PycharmProjects/convert-tf/dataset/tfrecords/train-00007-of-00016

2019-05-10 20:25:02.695321 [thread 3]: Wrote 2767 images to 2767 shards.

2019-05-10 20:25:03.116049 [thread 2]: Wrote 1384 images to D:/Program Files(x86)/PycharmProjects/convert-tf/dataset/tfrecords/train-00005-of-00016

2019-05-10 20:25:03.116049 [thread 2]: Wrote 2767 images to 2767 shards.

2019-05-10 20:25:03.697749 [thread 5]: Wrote 1384 images to D:/Program Files(x86)/PycharmProjects/convert-tf/dataset/tfrecords/train-00011-of-00016

2019-05-10 20:25:03.699716 [thread 5]: Wrote 2767 images to 2767 shards.

2019-05-10 20:25:04.521280 [thread 6]: Wrote 1384 images to D:/Program Files(x86)/PycharmProjects/convert-tf/dataset/tfrecords/train-00013-of-00016

2019-05-10 20:25:04.521280 [thread 6]: Wrote 2767 images to 2767 shards.

2019-05-10 20:25:05.261857 [thread 4]: Wrote 1384 images to D:/Program Files(x86)/PycharmProjects/convert-tf/dataset/tfrecords/train-00009-of-00016

2019-05-10 20:25:05.264824 [thread 4]: Wrote 2767 images to 2767 shards.

2019-05-10 20:25:06.172305 [thread 1]: Wrote 1384 images to D:/Program Files(x86)/PycharmProjects/convert-tf/dataset/tfrecords/train-00003-of-00016

2019-05-10 20:25:06.172305 [thread 1]: Wrote 2767 images to 2767 shards.

2019-05-10 20:25:07.585508 [thread 7]: Wrote 1384 images to D:/Program Files(x86)/PycharmProjects/convert-tf/dataset/tfrecords/train-00015-of-00016

2019-05-10 20:25:07.585508 [thread 7]: Wrote 2767 images to 2767 shards.

2019-05-10 20:25:08.263114: Finished writing all 22136 images in data set.

Process finished with exit code 0

參考連結:

https://blog.csdn.net/weiweixiao3/article/details/82352062

tensorflow TFRecords檔案的生成和讀取方法https://zhuanlan.zhihu.com/p/31992460

tensorflow分類--------實作訓練自己的訓練集并在網頁中顯示https://blog.csdn.net/m0_37407756/article/details/80670377

TensorFlow 自定義生成 .record 檔案 https://www.jianshu.com/p/ad5c7cdfeff2

Tensorflow - tfrecords 檔案的建立 https://cloud.tencent.com/developer/article/1401155

TensorFlow學習筆記(五)圖像資料處理 https://www.cnblogs.com/zuoshoushizi/p/9232095.html

繼續閱讀