يوم مجتمع ML هو 9 نوفمبر! الانضمام إلينا للحصول على التحديثات من TensorFlow، JAX، وأكثر معرفة المزيد

TFRecord و tf.train مثال

عرض على TensorFlow.org تشغيل في Google Colab عرض المصدر على جيثب تحميل دفتر

تنسيق 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]
  • ميزة سلسلة يتم إنشاؤها من جدول سلسلة باستخدام ميزة العدد الصحيح كفهرس
  • ميزة عائمة من التوزيع العادي القياسي

ضع في اعتبارك عينة تتكون من 10000 ملاحظة موزعة بشكل مستقل ومتماثل من كل من التوزيعات المذكورة أعلاه:

# 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 التجزئة لفحص سلامة).

يتم تخزين كل سجل بالتنسيقات التالية:

uint64 length
uint32 masked_crc32_of_length
byte   data[length]
uint32 masked_crc32_of_data

يتم تجميع السجلات معًا لإنتاج الملف. ومراكز التأهيل المجتمعي وصفها هنا ، وقناع من CRC هو:

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>

عند تطبيقها على مجموعة من المصفوفات ، فإنها تُرجع مجموعة بيانات تتكون من مجموعات:

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 الصورة يمكن أن تكون مفيدة لتوحيد إدخال البيانات وتحسين الأداء.

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 الصورة استخدام الرسم البياني، التنفيذ، وتحتاج هذا الوصف لبناء شكل ونوع التوقيع:

# 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}>

استخدم التنفيذ الحثيث لعرض الملاحظات في مجموعة البيانات. توجد 10000 ملاحظة في مجموعة البيانات هذه ، ولكنك ستعرض أول 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 وظيفة بفك tf.train.Example الحقول إلى التنسورات القياسية.

ملفات TFRecord في بايثون

و 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 على القاموس صفائف نمباي، من دون استخدام العمليات TensorFlow. الرجوع إلى ملف بروتو لديتيالس.

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])}

تجول: قراءة وكتابة بيانات الصورة

هذا مثال شامل على كيفية قراءة بيانات الصورة وكتابتها باستخدام سجلات TFRecords. باستخدام صورة كبيانات إدخال ، ستكتب البيانات كملف TFRecord ، ثم تقرأ الملف مرة أخرى وتعرض الصورة.

يمكن أن يكون هذا مفيدًا ، على سبيل المثال ، إذا كنت تريد استخدام عدة نماذج على نفس مجموعة بيانات الإدخال. بدلاً من تخزين بيانات الصورة الخام ، يمكن معالجتها مسبقًا في تنسيق TFRecords ، ويمكن استخدامها في جميع عمليات المعالجة والنمذجة الإضافية.

أولا، دعونا تحميل هذه الصورة لقطة في الثلج و هذه الصورة من جسر وليامز، NYC قيد الإنشاء.

إحضار الصور

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 الميزة. يتم استخدام الأخير عند كتابة الملف للتمييز بين صورة القط وصورة الجسر. استخدام 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

لديك الآن ملف- images.tfrecords -ويمكن الآن أعاد أكثر من السجلات في ذلك لقراءة الظهر ما كتبته. بالنظر إلى أنك في هذا المثال ستعيد إنتاج الصورة فقط ، فإن الميزة الوحيدة التي ستحتاج إليها هي سلسلة الصورة الأولية. استخراجه باستخدام حاصل المذكورة أعلاه، وهي 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