ปรับแต่งในสตรีเป็นครั้งแรกในการประชุมทางวิชาการ ML อังคารนี้ 19 ตุลาคมเวลา 09:00 PST ลงทะเบียนตอนนี้

TFRecord และ tf.train.Example

ดูบน TensorFlow.org ทำงานใน Google Colab ดูแหล่งที่มาบน GitHub ดาวน์โหลดโน๊ตบุ๊ค

รูปแบบ TFRecord เป็นรูปแบบที่เรียบง่ายสำหรับการจัดเก็บลำดับของเรคคอร์ดไบนารี

บัฟเฟอร์โปรโตคอล เป็นข้ามแพลตฟอร์มห้องสมุดข้ามภาษาสำหรับอนุกรมที่มีประสิทธิภาพของข้อมูลที่มีโครงสร้าง

ข้อความโพรโทคอจะถูกกำหนดโดย .proto ไฟล์เหล่านี้มักจะเป็นวิธีที่ง่ายที่สุดในการทำความเข้าใจประเภทข้อความ

tf.train.Example ข้อความ (หรือ protobuf) เป็นชนิดที่มีความยืดหยุ่นข้อความที่แสดงถึง {"string": value} การทำแผนที่ มันถูกออกแบบมาสำหรับการใช้งานกับ TensorFlow และมีการใช้ทั่ว APIs ระดับสูงเช่น TFX

โน๊ตบุ๊คนี้แสดงให้เห็นถึงวิธีการสร้างการแยกวิเคราะห์และใช้ tf.train.Example ข้อความแล้วอันดับ, การเขียนและอ่าน tf.train.Example ข้อความไปและกลับจาก .tfrecord ไฟล์

ติดตั้ง

import tensorflow as tf

import numpy as np
import IPython.display as display

tf.train.Example

ประเภทข้อมูลสำหรับ tf.train.Example

พื้นฐานเป็น tf.train.Example เป็น {"string": tf.train.Feature} การทำแผนที่

tf.train.Feature ประเภทข้อความสามารถยอมรับหนึ่งต่อไปนี้สามประเภท (ดู .proto ไฟล์ สำหรับการอ้างอิง) ยาสามัญอื่นๆ ส่วนใหญ่สามารถบังคับได้ดังนี้

  1. tf.train.BytesList (ประเภทต่อไปนี้สามารถบังคับ)

    • string
    • byte
  2. tf.train.FloatList (ประเภทต่อไปนี้สามารถบังคับ)

    • float ( float32 )
    • double ( float64 )
  3. tf.train.Int64List (ประเภทต่อไปนี้สามารถบังคับ)

    • bool
    • enum
    • int32
    • uint32
    • int64
    • uint64

เพื่อแปลงเป็นชนิด TensorFlow มาตรฐานกับ tf.train.Example ใช้ได้กับระบบปฏิบัติการ tf.train.Feature คุณสามารถใช้ฟังก์ชั่นทางลัดด้านล่าง โปรดทราบว่าแต่ละฟังก์ชั่นใช้เวลาคุ้มค่าการป้อนข้อมูลสเกลาร์และผลตอบแทน tf.train.Feature ที่มีหนึ่งในสามของ list ประเภทดังกล่าวข้างต้น:

# The following functions can be used to convert a value to a type compatible
# with tf.train.Example.

def _bytes_feature(value):
  """Returns a bytes_list from a string / byte."""
  if isinstance(value, type(tf.constant(0))):
    value = value.numpy() # BytesList won't unpack a string from an EagerTensor.
  return tf.train.Feature(bytes_list=tf.train.BytesList(value=[value]))

def _float_feature(value):
  """Returns a float_list from a float / double."""
  return tf.train.Feature(float_list=tf.train.FloatList(value=[value]))

def _int64_feature(value):
  """Returns an int64_list from a bool / enum / int / uint."""
  return tf.train.Feature(int64_list=tf.train.Int64List(value=[value]))

ด้านล่างนี้คือตัวอย่างการทำงานของฟังก์ชันเหล่านี้ สังเกตประเภทอินพุตที่แตกต่างกันและประเภทเอาต์พุตมาตรฐาน ถ้าชนิดป้อนข้อมูลสำหรับการทำงานไม่ตรงกับหนึ่งในประเภท coercible ระบุไว้ข้างต้นฟังก์ชันจะเพิ่มการยกเว้น (เช่น _int64_feature(1.0) จะเกิดข้อผิดพลาดออกมาเพราะ 1.0 เป็นลอยจึงควรใช้กับ _float_feature ฟังก์ชั่นแทน ):

print(_bytes_feature(b'test_string'))
print(_bytes_feature(u'test_bytes'.encode('utf-8')))

print(_float_feature(np.exp(1)))

print(_int64_feature(True))
print(_int64_feature(1))
bytes_list {
  value: "test_string"
}

bytes_list {
  value: "test_bytes"
}

float_list {
  value: 2.7182817459106445
}

int64_list {
  value: 1
}

int64_list {
  value: 1
}

ข้อความโปรทั้งหมดสามารถต่อเนื่องไปยังไบนารีสตริงใช้ .SerializeToString วิธีการ:

feature = _float_feature(np.exp(1))

feature.SerializeToString()
b'\x12\x06\n\x04T\xf8-@'

สร้าง tf.train.Example ข้อความ

สมมติว่าคุณต้องการที่จะสร้าง tf.train.Example ข้อความจากข้อมูลที่มีอยู่ ในทางปฏิบัติชุดข้อมูลที่อาจจะมาจากที่ใดก็ได้ แต่ขั้นตอนของการสร้างที่ tf.train.Example ข้อความจากการสังเกตเดียวจะไม่เหมือนเดิม:

  1. ภายในแต่ละสังเกตแต่ละความต้องการความคุ้มค่าให้ถูกแปลงเป็น tf.train.Feature ที่มีหนึ่งใน 3 ประเภทที่เข้ากันได้โดยใช้หนึ่งในฟังก์ชั่นดังกล่าวข้างต้น

  2. คุณสร้างแผนที่ (พจนานุกรม) จากสตริงชื่อสถานที่ไปจนถึงค่าคุณลักษณะที่เข้ารหัสซึ่งสร้างขึ้นใน #1

  3. แผนที่ที่ผลิตในขั้นตอนที่ 2 จะถูกแปลงเป็น Features ข้อความ

ในสมุดบันทึกนี้ คุณจะสร้างชุดข้อมูลโดยใช้ NumPy

ชุดข้อมูลนี้จะมีคุณสมบัติ 4 ประการ:

  • คุณลักษณะบูลีน False หรือ True มีโอกาสที่เท่าเทียมกัน
  • คุณลักษณะจำนวนเต็มสม่ำเสมอสุ่มเลือกจาก [0, 5]
  • คุณลักษณะสตริงที่สร้างจากตารางสตริงโดยใช้คุณลักษณะจำนวนเต็มเป็นดัชนี
  • คุณสมบัติลอยจากการแจกแจงแบบปกติมาตรฐาน

พิจารณาตัวอย่างที่ประกอบด้วยการสังเกตที่แยกจากกันอย่างอิสระและเหมือนกัน 10,000 ครั้งจากการแจกแจงข้างต้นแต่ละครั้ง:

# The number of observations in the dataset.
n_observations = int(1e4)

# Boolean feature, encoded as False or True.
feature0 = np.random.choice([False, True], n_observations)

# Integer feature, random from 0 to 4.
feature1 = np.random.randint(0, 5, n_observations)

# String feature.
strings = np.array([b'cat', b'dog', b'chicken', b'horse', b'goat'])
feature2 = strings[feature1]

# Float feature, from a standard normal distribution.
feature3 = np.random.randn(n_observations)

แต่ละคุณลักษณะเหล่านี้จะสามารถบังคับให้เป็น tf.train.Example ชนิดเข้ากันโดยใช้หนึ่งใน _bytes_feature , _float_feature , _int64_feature จากนั้นคุณสามารถสร้าง tf.train.Example ข้อความจากคุณสมบัติที่เข้ารหัสเหล่านี้:

def serialize_example(feature0, feature1, feature2, feature3):
  """
  Creates a tf.train.Example message ready to be written to a file.
  """
  # Create a dictionary mapping the feature name to the tf.train.Example-compatible
  # data type.
  feature = {
      'feature0': _int64_feature(feature0),
      'feature1': _int64_feature(feature1),
      'feature2': _bytes_feature(feature2),
      'feature3': _float_feature(feature3),
  }

  # Create a Features message using tf.train.Example.

  example_proto = tf.train.Example(features=tf.train.Features(feature=feature))
  return example_proto.SerializeToString()

ตัวอย่างเช่นสมมติว่าคุณมีการสังเกตเดียวจากชุดที่ [False, 4, bytes('goat'), 0.9876] คุณสามารถสร้างและพิมพ์ tf.train.Example ข้อความสำหรับการสังเกตนี้โดยใช้ create_message() การสังเกตแต่ละเดียวจะได้รับการเขียนเป็น Features ข้อความตามข้างต้น หมายเหตุว่า tf.train.Example ข้อความ เป็นเพียงเสื้อคลุมรอบ Features ข้อความ:

# This is an example observation from the dataset.

example_observation = []

serialized_example = serialize_example(False, 4, b'goat', 0.9876)
serialized_example
b'\nR\n\x14\n\x08feature2\x12\x08\n\x06\n\x04goat\n\x14\n\x08feature3\x12\x08\x12\x06\n\x04[\xd3|?\n\x11\n\x08feature1\x12\x05\x1a\x03\n\x01\x04\n\x11\n\x08feature0\x12\x05\x1a\x03\n\x01\x00'

ใช้ในการถอดรหัสข้อความ tf.train.Example.FromString วิธี

example_proto = tf.train.Example.FromString(serialized_example)
example_proto
features {
  feature {
    key: "feature0"
    value {
      int64_list {
        value: 0
      }
    }
  }
  feature {
    key: "feature1"
    value {
      int64_list {
        value: 4
      }
    }
  }
  feature {
    key: "feature2"
    value {
      bytes_list {
        value: "goat"
      }
    }
  }
  feature {
    key: "feature3"
    value {
      float_list {
        value: 0.9876000285148621
      }
    }
  }
}

รายละเอียดรูปแบบ TFRecords

ไฟล์ TFRecord มีลำดับของเรคคอร์ด ไฟล์สามารถอ่านได้ตามลำดับเท่านั้น

แต่ละระเบียนมีไบต์สตริงสำหรับข้อมูลน้ำหนักบรรทุกรวมทั้งข้อมูลที่มีความยาวและ CRC-32C ( 32 บิต CRC ใช้ พหุนาม Castagnoli ) hashes สำหรับการตรวจสอบความสมบูรณ์

แต่ละระเบียนจะถูกจัดเก็บในรูปแบบต่อไปนี้:

uint64 length
uint32 masked_crc32_of_length
byte   data[length]
uint32 masked_crc32_of_data

เร็กคอร์ดถูกต่อเข้าด้วยกันเพื่อสร้างไฟล์ CRCs มีการ อธิบายไว้ที่นี่ และหน้ากากของซีอาร์ซีคือ:

masked_crc = ((crc >> 15) | (crc << 17)) + 0xa282ead8ul

ไฟล์ TFRecord ใช้ tf.data

tf.data โมดูลยังมีเครื่องมือสำหรับการอ่านและเขียนข้อมูลใน TensorFlow

การเขียนไฟล์ TFRecord

วิธีที่ง่ายที่สุดที่จะได้รับข้อมูลลงในชุดข้อมูลคือการใช้ from_tensor_slices วิธี

นำไปใช้กับอาร์เรย์ จะส่งคืนชุดข้อมูลของสเกลาร์:

tf.data.Dataset.from_tensor_slices(feature1)
<TensorSliceDataset shapes: (), types: tf.int64>

นำไปใช้กับ tuple ของอาร์เรย์ จะส่งคืนชุดข้อมูลของ tuples:

features_dataset = tf.data.Dataset.from_tensor_slices((feature0, feature1, feature2, feature3))
features_dataset
<TensorSliceDataset shapes: ((), (), (), ()), types: (tf.bool, tf.int64, tf.string, tf.float64)>
# Use `take(1)` to only pull one example from the dataset.
for f0,f1,f2,f3 in features_dataset.take(1):
  print(f0)
  print(f1)
  print(f2)
  print(f3)
tf.Tensor(True, shape=(), dtype=bool)
tf.Tensor(1, shape=(), dtype=int64)
tf.Tensor(b'dog', shape=(), dtype=string)
tf.Tensor(-0.9885608219225024, shape=(), dtype=float64)

ใช้ tf.data.Dataset.map วิธีการใช้ฟังก์ชั่นให้องค์ประกอบของแต่ละ Dataset

ฟังก์ชั่นแมปจะต้องดำเนินการในกราฟ TensorFlow โหมดก็จะต้องดำเนินการในและกลับ tf.Tensors ฟังก์ชั่นที่ไม่ใช่เมตริกซ์เช่น serialize_example สามารถห่อด้วย tf.py_function ที่จะทำให้มันเข้ากันได้

ใช้ tf.py_function ต้องระบุรูปร่างและชนิดของข้อมูลที่ไม่สามารถใช้งานอย่างอื่น

def tf_serialize_example(f0,f1,f2,f3):
  tf_string = tf.py_function(
    serialize_example,
    (f0, f1, f2, f3),  # Pass these args to the above function.
    tf.string)      # The return type is `tf.string`.
  return tf.reshape(tf_string, ()) # The result is a scalar.
tf_serialize_example(f0, f1, f2, f3)
<tf.Tensor: shape=(), dtype=string, numpy=b'\nQ\n\x14\n\x08feature3\x12\x08\x12\x06\n\x04R\x12}\xbf\n\x11\n\x08feature1\x12\x05\x1a\x03\n\x01\x01\n\x13\n\x08feature2\x12\x07\n\x05\n\x03dog\n\x11\n\x08feature0\x12\x05\x1a\x03\n\x01\x01'>

ใช้ฟังก์ชันนี้กับแต่ละองค์ประกอบในชุดข้อมูล:

serialized_features_dataset = features_dataset.map(tf_serialize_example)
serialized_features_dataset
<MapDataset shapes: (), types: tf.string>
def generator():
  for features in features_dataset:
    yield serialize_example(*features)
serialized_features_dataset = tf.data.Dataset.from_generator(
    generator, output_types=tf.string, output_shapes=())
serialized_features_dataset
<FlatMapDataset shapes: (), types: tf.string>

และเขียนลงในไฟล์ TFRecord:

filename = 'test.tfrecord'
writer = tf.data.experimental.TFRecordWriter(filename)
writer.write(serialized_features_dataset)
WARNING:tensorflow:From /tmp/ipykernel_16482/3575438268.py:2: TFRecordWriter.__init__ (from tensorflow.python.data.experimental.ops.writers) is deprecated and will be removed in a future version.
Instructions for updating:
To write TFRecords to disk, use `tf.io.TFRecordWriter`. To save and load the contents of a dataset, use `tf.data.experimental.save` and `tf.data.experimental.load`

การอ่านไฟล์ TFRecord

นอกจากนี้คุณยังสามารถอ่านไฟล์ TFRecord ใช้ tf.data.TFRecordDataset ระดับ

ข้อมูลเพิ่มเติมเกี่ยวกับการบริโภคไฟล์ TFRecord ใช้ tf.data สามารถพบได้ใน tf.data: รูปร่าง TensorFlow ท่อป้อนข้อมูล คู่มือ

ใช้ TFRecordDataset s จะมีประโยชน์สำหรับมาตรฐานการป้อนข้อมูลและการเพิ่มประสิทธิภาพการทำงาน

filenames = [filename]
raw_dataset = tf.data.TFRecordDataset(filenames)
raw_dataset
<TFRecordDatasetV2 shapes: (), types: tf.string>

ณ จุดนี้ชุดข้อมูลที่มีต่อเนื่อง tf.train.Example ข้อความ เมื่อวนซ้ำจะส่งกลับสิ่งเหล่านี้เป็นเทนเซอร์สตริงสเกลาร์

ใช้ .take วิธีการที่จะแสดงเพียงครั้งแรก 10 ระเบียน

for raw_record in raw_dataset.take(10):
  print(repr(raw_record))
<tf.Tensor: shape=(), dtype=string, numpy=b'\nQ\n\x14\n\x08feature3\x12\x08\x12\x06\n\x04R\x12}\xbf\n\x11\n\x08feature0\x12\x05\x1a\x03\n\x01\x01\n\x13\n\x08feature2\x12\x07\n\x05\n\x03dog\n\x11\n\x08feature1\x12\x05\x1a\x03\n\x01\x01'>
<tf.Tensor: shape=(), dtype=string, numpy=b'\nQ\n\x14\n\x08feature3\x12\x08\x12\x06\n\x04\xb5\x91\xdc\xbb\n\x11\n\x08feature1\x12\x05\x1a\x03\n\x01\x00\n\x11\n\x08feature0\x12\x05\x1a\x03\n\x01\x01\n\x13\n\x08feature2\x12\x07\n\x05\n\x03cat'>
<tf.Tensor: shape=(), dtype=string, numpy=b'\nU\n\x11\n\x08feature0\x12\x05\x1a\x03\n\x01\x00\n\x17\n\x08feature2\x12\x0b\n\t\n\x07chicken\n\x14\n\x08feature3\x12\x08\x12\x06\n\x04\xbd\x91g=\n\x11\n\x08feature1\x12\x05\x1a\x03\n\x01\x02'>
<tf.Tensor: shape=(), dtype=string, numpy=b'\nQ\n\x11\n\x08feature0\x12\x05\x1a\x03\n\x01\x00\n\x13\n\x08feature2\x12\x07\n\x05\n\x03dog\n\x11\n\x08feature1\x12\x05\x1a\x03\n\x01\x01\n\x14\n\x08feature3\x12\x08\x12\x06\n\x04e\xc5\x98>'>
<tf.Tensor: shape=(), dtype=string, numpy=b'\nS\n\x15\n\x08feature2\x12\t\n\x07\n\x05horse\n\x11\n\x08feature1\x12\x05\x1a\x03\n\x01\x03\n\x14\n\x08feature3\x12\x08\x12\x06\n\x04e\xa4|>\n\x11\n\x08feature0\x12\x05\x1a\x03\n\x01\x01'>
<tf.Tensor: shape=(), dtype=string, numpy=b'\nQ\n\x11\n\x08feature0\x12\x05\x1a\x03\n\x01\x00\n\x13\n\x08feature2\x12\x07\n\x05\n\x03cat\n\x14\n\x08feature3\x12\x08\x12\x06\n\x04\x0b\xb3\x02@\n\x11\n\x08feature1\x12\x05\x1a\x03\n\x01\x00'>
<tf.Tensor: shape=(), dtype=string, numpy=b'\nQ\n\x14\n\x08feature3\x12\x08\x12\x06\n\x04G\xa4\xda\xbf\n\x13\n\x08feature2\x12\x07\n\x05\n\x03dog\n\x11\n\x08feature0\x12\x05\x1a\x03\n\x01\x01\n\x11\n\x08feature1\x12\x05\x1a\x03\n\x01\x01'>
<tf.Tensor: shape=(), dtype=string, numpy=b'\nQ\n\x11\n\x08feature1\x12\x05\x1a\x03\n\x01\x01\n\x11\n\x08feature0\x12\x05\x1a\x03\n\x01\x00\n\x13\n\x08feature2\x12\x07\n\x05\n\x03dog\n\x14\n\x08feature3\x12\x08\x12\x06\n\x04\xd2/\xcf\xbf'>
<tf.Tensor: shape=(), dtype=string, numpy=b'\nQ\n\x11\n\x08feature0\x12\x05\x1a\x03\n\x01\x00\n\x14\n\x08feature3\x12\x08\x12\x06\n\x04<\xedO?\n\x11\n\x08feature1\x12\x05\x1a\x03\n\x01\x00\n\x13\n\x08feature2\x12\x07\n\x05\n\x03cat'>
<tf.Tensor: shape=(), dtype=string, numpy=b'\nR\n\x11\n\x08feature0\x12\x05\x1a\x03\n\x01\x01\n\x11\n\x08feature1\x12\x05\x1a\x03\n\x01\x04\n\x14\n\x08feature3\x12\x08\x12\x06\n\x041I\xe1?\n\x14\n\x08feature2\x12\x08\n\x06\n\x04goat'>

สามารถแยกวิเคราะห์เมตริกซ์เหล่านี้ได้โดยใช้ฟังก์ชันด้านล่าง หมายเหตุว่า feature_description เป็นสิ่งจำเป็นที่นี่เพราะ tf.data.Dataset s ใช้กราฟดำเนินการและต้องการคำอธิบายนี้ในการสร้างรูปทรงและลายเซ็นของประเภทของพวกเขา

# Create a description of the features.
feature_description = {
    'feature0': tf.io.FixedLenFeature([], tf.int64, default_value=0),
    'feature1': tf.io.FixedLenFeature([], tf.int64, default_value=0),
    'feature2': tf.io.FixedLenFeature([], tf.string, default_value=''),
    'feature3': tf.io.FixedLenFeature([], tf.float32, default_value=0.0),
}

def _parse_function(example_proto):
  # Parse the input `tf.train.Example` proto using the dictionary above.
  return tf.io.parse_single_example(example_proto, feature_description)

หรือใช้ tf.parse example ที่จะแยกชุดทั้งหมดในครั้งเดียว สมัครฟังก์ชันนี้เพื่อแต่ละรายการในชุดข้อมูลโดยใช้ tf.data.Dataset.map วิธีการ:

parsed_dataset = raw_dataset.map(_parse_function)
parsed_dataset
<MapDataset shapes: {feature0: (), feature1: (), feature2: (), feature3: ()}, types: {feature0: tf.int64, feature1: tf.int64, feature2: tf.string, feature3: tf.float32}>

ใช้การดำเนินการอย่างกระตือรือร้นเพื่อแสดงการสังเกตในชุดข้อมูล มีการสังเกต 10,000 รายการในชุดข้อมูลนี้ แต่คุณจะแสดงเฉพาะ 10 รายการแรกเท่านั้น ข้อมูลจะแสดงเป็นพจนานุกรมของคุณสมบัติ แต่ละรายการเป็น tf.Tensor และ numpy องค์ประกอบของเมตริกซ์นี้แสดงค่าของคุณลักษณะ:

for parsed_record in parsed_dataset.take(10):
  print(repr(parsed_record))
{'feature0': <tf.Tensor: shape=(), dtype=int64, numpy=1>, 'feature1': <tf.Tensor: shape=(), dtype=int64, numpy=1>, 'feature2': <tf.Tensor: shape=(), dtype=string, numpy=b'dog'>, 'feature3': <tf.Tensor: shape=(), dtype=float32, numpy=-0.9885608>}
{'feature0': <tf.Tensor: shape=(), dtype=int64, numpy=1>, 'feature1': <tf.Tensor: shape=(), dtype=int64, numpy=0>, 'feature2': <tf.Tensor: shape=(), dtype=string, numpy=b'cat'>, 'feature3': <tf.Tensor: shape=(), dtype=float32, numpy=-0.006731237>}
{'feature0': <tf.Tensor: shape=(), dtype=int64, numpy=0>, 'feature1': <tf.Tensor: shape=(), dtype=int64, numpy=2>, 'feature2': <tf.Tensor: shape=(), dtype=string, numpy=b'chicken'>, 'feature3': <tf.Tensor: shape=(), dtype=float32, numpy=0.05653547>}
{'feature0': <tf.Tensor: shape=(), dtype=int64, numpy=0>, 'feature1': <tf.Tensor: shape=(), dtype=int64, numpy=1>, 'feature2': <tf.Tensor: shape=(), dtype=string, numpy=b'dog'>, 'feature3': <tf.Tensor: shape=(), dtype=float32, numpy=0.298381>}
{'feature0': <tf.Tensor: shape=(), dtype=int64, numpy=1>, 'feature1': <tf.Tensor: shape=(), dtype=int64, numpy=3>, 'feature2': <tf.Tensor: shape=(), dtype=string, numpy=b'horse'>, 'feature3': <tf.Tensor: shape=(), dtype=float32, numpy=0.24672087>}
{'feature0': <tf.Tensor: shape=(), dtype=int64, numpy=0>, 'feature1': <tf.Tensor: shape=(), dtype=int64, numpy=0>, 'feature2': <tf.Tensor: shape=(), dtype=string, numpy=b'cat'>, 'feature3': <tf.Tensor: shape=(), dtype=float32, numpy=2.042178>}
{'feature0': <tf.Tensor: shape=(), dtype=int64, numpy=1>, 'feature1': <tf.Tensor: shape=(), dtype=int64, numpy=1>, 'feature2': <tf.Tensor: shape=(), dtype=string, numpy=b'dog'>, 'feature3': <tf.Tensor: shape=(), dtype=float32, numpy=-1.7081383>}
{'feature0': <tf.Tensor: shape=(), dtype=int64, numpy=0>, 'feature1': <tf.Tensor: shape=(), dtype=int64, numpy=1>, 'feature2': <tf.Tensor: shape=(), dtype=string, numpy=b'dog'>, 'feature3': <tf.Tensor: shape=(), dtype=float32, numpy=-1.6186469>}
{'feature0': <tf.Tensor: shape=(), dtype=int64, numpy=0>, 'feature1': <tf.Tensor: shape=(), dtype=int64, numpy=0>, 'feature2': <tf.Tensor: shape=(), dtype=string, numpy=b'cat'>, 'feature3': <tf.Tensor: shape=(), dtype=float32, numpy=0.81221366>}
{'feature0': <tf.Tensor: shape=(), dtype=int64, numpy=1>, 'feature1': <tf.Tensor: shape=(), dtype=int64, numpy=4>, 'feature2': <tf.Tensor: shape=(), dtype=string, numpy=b'goat'>, 'feature3': <tf.Tensor: shape=(), dtype=float32, numpy=1.7600461>}

นี่ tf.parse_example ฟังก์ชั่น unpacks tf.train.Example สาขาเข้าไปในเทนเซอร์มาตรฐาน

ไฟล์ TFRecord ใน Python

tf.io โมดูลนอกจากนี้ยังมีฟังก์ชั่นหลามบริสุทธิ์สำหรับการอ่านและการเขียนไฟล์ TFRecord

การเขียนไฟล์ TFRecord

ถัดไปเขียน 10,000 สังเกตไปยังแฟ้ม test.tfrecord แต่ละสังเกตจะถูกแปลงเป็น tf.train.Example ข้อความเขียนไปยังแฟ้มแล้ว จากนั้นคุณสามารถตรวจสอบว่าไฟล์ test.tfrecord ได้รับการสร้าง:

# Write the `tf.train.Example` observations to the file.
with tf.io.TFRecordWriter(filename) as writer:
  for i in range(n_observations):
    example = serialize_example(feature0[i], feature1[i], feature2[i], feature3[i])
    writer.write(example)
du -sh {filename}
984K    test.tfrecord

การอ่านไฟล์ TFRecord

เทนเซอร์เนื่องเหล่านี้สามารถแยกวิเคราะห์อย่างง่ายดายโดยใช้ tf.train.Example.ParseFromString :

filenames = [filename]
raw_dataset = tf.data.TFRecordDataset(filenames)
raw_dataset
<TFRecordDatasetV2 shapes: (), types: tf.string>
for raw_record in raw_dataset.take(1):
  example = tf.train.Example()
  example.ParseFromString(raw_record.numpy())
  print(example)
features {
  feature {
    key: "feature0"
    value {
      int64_list {
        value: 1
      }
    }
  }
  feature {
    key: "feature1"
    value {
      int64_list {
        value: 1
      }
    }
  }
  feature {
    key: "feature2"
    value {
      bytes_list {
        value: "dog"
      }
    }
  }
  feature {
    key: "feature3"
    value {
      float_list {
        value: -0.9885607957839966
      }
    }
  }
}

ที่ส่งกลับ tf.train.Example โปรโตซึ่งเป็น dificult กับการใช้งานที่เป็นอยู่ แต่มันก็เป็นพื้นฐานที่เป็นตัวแทนของ:

Dict[str,
     Union[List[float],
           List[int],
           List[str]]]

รหัสต่อไปนี้ด้วยตนเองแปลง Example ในพจนานุกรมของอาร์เรย์ NumPy โดยไม่ต้องใช้ TensorFlow Ops อ้างถึง ไฟล์โปรโต สำหรับ detials

result = {}
# example.features.feature is the dictionary
for key, feature in example.features.feature.items():
  # The values are the Feature objects which contain a `kind` which contains:
  # one of three fields: bytes_list, float_list, int64_list

  kind = feature.WhichOneof('kind')
  result[key] = np.array(getattr(feature, kind).value)

result
{'feature1': array([1]),
 'feature0': array([1]),
 'feature2': array([b'dog'], dtype='|S3'),
 'feature3': array([-0.9885608])}

กวดวิชา: การอ่านและการเขียนข้อมูลภาพ

นี่เป็นตัวอย่างแบบ end-to-end ของวิธีการอ่านและเขียนข้อมูลภาพโดยใช้ TFRecords การใช้รูปภาพเป็นข้อมูลเข้า คุณจะเขียนข้อมูลเป็นไฟล์ TFRecord จากนั้นอ่านไฟล์กลับและแสดงรูปภาพ

ซึ่งจะเป็นประโยชน์ ตัวอย่างเช่น หากคุณต้องการใช้แบบจำลองหลายแบบในชุดข้อมูลอินพุตเดียวกัน แทนที่จะจัดเก็บข้อมูลภาพดิบ มันสามารถประมวลผลล่วงหน้าในรูปแบบ TFRecords และสามารถใช้ในการประมวลผลและการสร้างแบบจำลองเพิ่มเติมทั้งหมด

อันดับแรกให้ดาวน์โหลด ภาพนี้ ของแมวในหิมะและ รูปนี้ ของสะพานวิลเลียมส์, นิวยอร์คภายใต้การก่อสร้าง

ดึงภาพ

cat_in_snow  = tf.keras.utils.get_file(
    '320px-Felis_catus-cat_on_snow.jpg',
    'https://storage.googleapis.com/download.tensorflow.org/example_images/320px-Felis_catus-cat_on_snow.jpg')

williamsburg_bridge = tf.keras.utils.get_file(
    '194px-New_East_River_Bridge_from_Brooklyn_det.4a09796u.jpg',
    'https://storage.googleapis.com/download.tensorflow.org/example_images/194px-New_East_River_Bridge_from_Brooklyn_det.4a09796u.jpg')
Downloading data from https://storage.googleapis.com/download.tensorflow.org/example_images/320px-Felis_catus-cat_on_snow.jpg
24576/17858 [=========================================] - 0s 0us/step
32768/17858 [=======================================================] - 0s 0us/step
Downloading data from https://storage.googleapis.com/download.tensorflow.org/example_images/194px-New_East_River_Bridge_from_Brooklyn_det.4a09796u.jpg
16384/15477 [===============================] - 0s 0us/step
24576/15477 [===============================================] - 0s 0us/step
display.display(display.Image(filename=cat_in_snow))
display.display(display.HTML('Image cc-by: <a "href=https://commons.wikimedia.org/wiki/File:Felis_catus-cat_on_snow.jpg">Von.grzanka</a>'))

jpeg

display.display(display.Image(filename=williamsburg_bridge))
display.display(display.HTML('<a "href=https://commons.wikimedia.org/wiki/File:New_East_River_Bridge_from_Brooklyn_det.4a09796u.jpg">From Wikimedia</a>'))

jpeg

เขียนไฟล์ TFRecord

เมื่อก่อนเข้ารหัสคุณสมบัติเป็นชนิดเข้ากันได้กับ tf.train.Example ร้านค้านี้คุณลักษณะดิบสตริงภาพเช่นเดียวกับความสูงความกว้างความลึกและพล label คุณลักษณะ หลังใช้เมื่อคุณเขียนไฟล์เพื่อแยกความแตกต่างระหว่างอิมเมจ cat และอิมเมจบริดจ์ ใช้ 0 ภาพแมวและ 1 ภาพสะพาน:

image_labels = {
    cat_in_snow : 0,
    williamsburg_bridge : 1,
}
# This is an example, just using the cat image.
image_string = open(cat_in_snow, 'rb').read()

label = image_labels[cat_in_snow]

# Create a dictionary with features that may be relevant.
def image_example(image_string, label):
  image_shape = tf.io.decode_jpeg(image_string).shape

  feature = {
      'height': _int64_feature(image_shape[0]),
      'width': _int64_feature(image_shape[1]),
      'depth': _int64_feature(image_shape[2]),
      'label': _int64_feature(label),
      'image_raw': _bytes_feature(image_string),
  }

  return tf.train.Example(features=tf.train.Features(feature=feature))

for line in str(image_example(image_string, label)).split('\n')[:15]:
  print(line)
print('...')
features {
  feature {
    key: "depth"
    value {
      int64_list {
        value: 3
      }
    }
  }
  feature {
    key: "height"
    value {
      int64_list {
        value: 213
      }
...

ขอให้สังเกตว่าคุณสมบัติทั้งหมดจะถูกเก็บไว้ในขณะนี้ใน tf.train.Example ข้อความ ถัดไป functionalize โค้ดข้างต้นและเขียนข้อความตัวอย่างไปยังแฟ้มชื่อ images.tfrecords :

# Write the raw image files to `images.tfrecords`.
# First, process the two images into `tf.train.Example` messages.
# Then, write to a `.tfrecords` file.
record_file = 'images.tfrecords'
with tf.io.TFRecordWriter(record_file) as writer:
  for filename, label in image_labels.items():
    image_string = open(filename, 'rb').read()
    tf_example = image_example(image_string, label)
    writer.write(tf_example.SerializeToString())
du -sh {record_file}
36K images.tfrecords

อ่านไฟล์ TFRecord

ตอนนี้คุณมี File- images.tfrecords และอื่นสามารถตอนนี้ย้ำไปบันทึกในนั้นที่จะอ่านกลับสิ่งที่คุณเขียน เนื่องจากในตัวอย่างนี้ คุณจะสร้างภาพขึ้นมาใหม่เท่านั้น คุณลักษณะเดียวที่คุณต้องการคือสตริงภาพดิบ สารสกัดโดยใช้ getters ที่อธิบายข้างต้นคือ example.features.feature['image_raw'].bytes_list.value[0] คุณยังสามารถใช้ป้ายกำกับเพื่อกำหนดว่าเร็กคอร์ดใดเป็นแมวและอันใดคือบริดจ์:

raw_image_dataset = tf.data.TFRecordDataset('images.tfrecords')

# Create a dictionary describing the features.
image_feature_description = {
    'height': tf.io.FixedLenFeature([], tf.int64),
    'width': tf.io.FixedLenFeature([], tf.int64),
    'depth': tf.io.FixedLenFeature([], tf.int64),
    'label': tf.io.FixedLenFeature([], tf.int64),
    'image_raw': tf.io.FixedLenFeature([], tf.string),
}

def _parse_image_function(example_proto):
  # Parse the input tf.train.Example proto using the dictionary above.
  return tf.io.parse_single_example(example_proto, image_feature_description)

parsed_image_dataset = raw_image_dataset.map(_parse_image_function)
parsed_image_dataset
<MapDataset shapes: {depth: (), height: (), image_raw: (), label: (), width: ()}, types: {depth: tf.int64, height: tf.int64, image_raw: tf.string, label: tf.int64, width: tf.int64}>

กู้คืนรูปภาพจากไฟล์ TFRecord:

for image_features in parsed_image_dataset:
  image_raw = image_features['image_raw'].numpy()
  display.display(display.Image(data=image_raw))

jpeg

jpeg