原因:我自己想對資料集進行一些預處理,看大神的代碼,終于了解是怎麼轉成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()是通過指定分隔符對字元串進行切片。
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnL0QTOyMzNyEjMwETNwkTMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
現在看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