השב / י לאירוע TensorFlow Everywhere המקומי שלך היום!
דף זה תורגם על ידי Cloud Translation API.
Switch to English

TFRecord ו- tf.train. דוגמה

צפה ב- TensorFlow.org הפעל בגוגל קולאב צפה במקור ב- GitHub הורד מחברת

פורמט TFRecord הוא פורמט פשוט לאחסון רצף רשומות בינאריות.

מאגרי פרוטוקולים הם ספרייה חוצה פלטפורמות, בין שפות, לסידור יעיל של נתונים מובנים.

הודעות פרוטוקול מוגדרות על ידי קבצי .proto , לרוב זו הדרך הקלה ביותר להבין סוג הודעה.

הודעת tf.train.Example (או protobuf) היא סוג הודעה גמיש המייצג מיפוי {"string": value} . הוא מיועד לשימוש עם TensorFlow ומשמש בכל ממשקי ה- API ברמה הגבוהה יותר כגון TFX .

מחברת זו תדגים כיצד ליצור, לנתח ולהשתמש בהודעה tf.train.Example , ולאחר מכן 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]))

להלן מספר דוגמאות לאופן שבו פונקציות אלה פועלות. שימו לב לסוגי הקלט המשתנים ולסוגי הפלט הסטנדרטיים. אם סוג הקלט של פונקציה אינו תואם את אחד מסוגי הכפייה שצוינו לעיל, הפונקציה תעלה חריג (למשל, _int64_feature(1.0) תגרום לשגיאה, מכיוון ש 1.0 הוא float, לכן יש להשתמש בפונקציה _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 בשיטת .SerializeToString :

feature = _float_feature(np.exp(1))

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

יצירת הודעה tf.train.Example

נניח שתרצה ליצור tf.train.Example הודעה tf.train.Example מהנתונים הקיימים. בפועל, מערך הנתונים עשוי להגיע מכל מקום, אך ההליך ליצירת tf.train.Example הודעת דוגמה מתצפית יחידה תהיה זהה:

  1. בתוך כל תצפית, צריך להמיר כל ערך ל- tf.train.Feature המכילה אחד משלושת הסוגים התואמים, תוך שימוש באחת מהפונקציות לעיל.

  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 דוגמה 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\x11\n\x08feature0\x12\x05\x1a\x03\n\x01\x00\n\x14\n\x08feature3\x12\x08\x12\x06\n\x04[\xd3|?\n\x11\n\x08feature1\x12\x05\x1a\x03\n\x01\x04\n\x14\n\x08feature2\x12\x08\n\x06\n\x04goat'

כדי לפענח את ההודעה השתמש בשיטת 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 מכיל רצף רשומות. ניתן לקרוא את הקובץ ברצף בלבד.

כל רשומה מכילה מחרוזת בתים, עבור מטען הנתונים, בתוספת אורך הנתונים, ו- CRC32C (CRC של 32 סיביות באמצעות פולינום Castagnoli) לבדיקת תקינות.

כל רשומה מאוחסנת בפורמטים הבאים:

uint64 length
uint32 masked_crc32_of_length
byte   data[length]
uint32 masked_crc32_of_data

הרשומות משורשרות יחד כדי להפיק את הקובץ. CRCs מתוארים כאן , והמסיכה של CRC היא:

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

קבצי tf.data באמצעות 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(False, shape=(), dtype=bool)
tf.Tensor(0, shape=(), dtype=int64)
tf.Tensor(b'cat', shape=(), dtype=string)
tf.Tensor(-0.07564599618591197, 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\x13\n\x08feature2\x12\x07\n\x05\n\x03cat\n\x14\n\x08feature3\x12\x08\x12\x06\n\x04J\xec\x9a\xbd\n\x11\n\x08feature1\x12\x05\x1a\x03\n\x01\x00\n\x11\n\x08feature0\x12\x05\x1a\x03\n\x01\x00'>

החל פונקציה זו על כל רכיב במערך הנתונים:

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)

קריאת קובץ TFRecord

אתה יכול גם לקרוא את הקובץ TFRecord באמצעות המחלקה tf.data.TFRecordDataset .

מידע נוסף על צריכת קבצי tf.data באמצעות tf.data נמצא כאן .

השימוש ב- TFRecordDataset s יכול להיות שימושי לתקינה של נתוני קלט ואופטימיזציה של ביצועים.

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

בשלב זה מערך הנתונים מכיל tf.train.Example . הודעות 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\x13\n\x08feature2\x12\x07\n\x05\n\x03cat\n\x14\n\x08feature3\x12\x08\x12\x06\n\x04J\xec\x9a\xbd\n\x11\n\x08feature0\x12\x05\x1a\x03\n\x01\x00\n\x11\n\x08feature1\x12\x05\x1a\x03\n\x01\x00'>
<tf.Tensor: shape=(), dtype=string, numpy=b'\nS\n\x15\n\x08feature2\x12\t\n\x07\n\x05horse\n\x14\n\x08feature3\x12\x08\x12\x06\n\x04\x1f\xe0\xcb?\n\x11\n\x08feature0\x12\x05\x1a\x03\n\x01\x00\n\x11\n\x08feature1\x12\x05\x1a\x03\n\x01\x03'>
<tf.Tensor: shape=(), dtype=string, numpy=b'\nU\n\x11\n\x08feature0\x12\x05\x1a\x03\n\x01\x01\n\x14\n\x08feature3\x12\x08\x12\x06\n\x04q\xa9\xb8>\n\x17\n\x08feature2\x12\x0b\n\t\n\x07chicken\n\x11\n\x08feature1\x12\x05\x1a\x03\n\x01\x02'>
<tf.Tensor: shape=(), dtype=string, numpy=b'\nU\n\x11\n\x08feature0\x12\x05\x1a\x03\n\x01\x00\n\x14\n\x08feature3\x12\x08\x12\x06\n\x04\x93|+?\n\x17\n\x08feature2\x12\x0b\n\t\n\x07chicken\n\x11\n\x08feature1\x12\x05\x1a\x03\n\x01\x02'>
<tf.Tensor: shape=(), dtype=string, numpy=b'\nR\n\x11\n\x08feature0\x12\x05\x1a\x03\n\x01\x00\n\x14\n\x08feature3\x12\x08\x12\x06\n\x04\xa0X}?\n\x14\n\x08feature2\x12\x08\n\x06\n\x04goat\n\x11\n\x08feature1\x12\x05\x1a\x03\n\x01\x04'>
<tf.Tensor: shape=(), dtype=string, numpy=b'\nU\n\x14\n\x08feature3\x12\x08\x12\x06\n\x04[\x19\x11\xc0\n\x11\n\x08feature1\x12\x05\x1a\x03\n\x01\x02\n\x17\n\x08feature2\x12\x0b\n\t\n\x07chicken\n\x11\n\x08feature0\x12\x05\x1a\x03\n\x01\x01'>
<tf.Tensor: shape=(), dtype=string, numpy=b'\nS\n\x15\n\x08feature2\x12\t\n\x07\n\x05horse\n\x14\n\x08feature3\x12\x08\x12\x06\n\x0473\x12>\n\x11\n\x08feature1\x12\x05\x1a\x03\n\x01\x03\n\x11\n\x08feature0\x12\x05\x1a\x03\n\x01\x00'>
<tf.Tensor: shape=(), dtype=string, numpy=b'\nQ\n\x13\n\x08feature2\x12\x07\n\x05\n\x03dog\n\x11\n\x08feature0\x12\x05\x1a\x03\n\x01\x00\n\x11\n\x08feature1\x12\x05\x1a\x03\n\x01\x01\n\x14\n\x08feature3\x12\x08\x12\x06\n\x04\xa2\xf7\xf9>'>
<tf.Tensor: shape=(), dtype=string, numpy=b'\nR\n\x11\n\x08feature0\x12\x05\x1a\x03\n\x01\x00\n\x14\n\x08feature2\x12\x08\n\x06\n\x04goat\n\x11\n\x08feature1\x12\x05\x1a\x03\n\x01\x04\n\x14\n\x08feature3\x12\x08\x12\x06\n\x04\xba\xf8\xb1?'>
<tf.Tensor: shape=(), dtype=string, numpy=b'\nQ\n\x11\n\x08feature1\x12\x05\x1a\x03\n\x01\x00\n\x11\n\x08feature0\x12\x05\x1a\x03\n\x01\x01\n\x14\n\x08feature3\x12\x08\x12\x06\n\x04\xb71\xe5>\n\x13\n\x08feature2\x12\x07\n\x05\n\x03cat'>

ניתן לנתח טנזורים אלה באמצעות הפונקציה למטה. שים לב כי feature_description נחוצה כאן מכיוון feature_description נתונים משתמשים בביצוע גרפים, וזקוקים לתיאור זה כדי לבנות את צורתם וחתימת הסוג שלהם:

# 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=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.075646>}
{'feature0': <tf.Tensor: shape=(), dtype=int64, numpy=0>, 'feature1': <tf.Tensor: shape=(), dtype=int64, numpy=3>, 'feature2': <tf.Tensor: shape=(), dtype=string, numpy=b'horse'>, 'feature3': <tf.Tensor: shape=(), dtype=float32, numpy=1.5927771>}
{'feature0': <tf.Tensor: shape=(), dtype=int64, numpy=1>, '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.36066774>}
{'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.6698696>}
{'feature0': <tf.Tensor: shape=(), dtype=int64, numpy=0>, 'feature1': <tf.Tensor: shape=(), dtype=int64, numpy=4>, 'feature2': <tf.Tensor: shape=(), dtype=string, numpy=b'goat'>, 'feature3': <tf.Tensor: shape=(), dtype=float32, numpy=0.98963356>}
{'feature0': <tf.Tensor: shape=(), dtype=int64, numpy=1>, 'feature1': <tf.Tensor: shape=(), dtype=int64, numpy=2>, 'feature2': <tf.Tensor: shape=(), dtype=string, numpy=b'chicken'>, 'feature3': <tf.Tensor: shape=(), dtype=float32, numpy=-2.2671726>}
{'feature0': <tf.Tensor: shape=(), dtype=int64, numpy=0>, '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.1427735>}
{'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.4882174>}
{'feature0': <tf.Tensor: shape=(), dtype=int64, numpy=0>, '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.390403>}
{'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.44764492>}

כאן, הפונקציה tf.parse_example פורקת את tf.train.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: 0
      }
    }
  }
  feature {
    key: "feature1"
    value {
      int64_list {
        value: 0
      }
    }
  }
  feature {
    key: "feature2"
    value {
      bytes_list {
        value: "cat"
      }
    }
  }
  feature {
    key: "feature3"
    value {
      float_list {
        value: -0.07564599812030792
      }
    }
  }
}


הדרכה: קריאה וכתיבה של נתוני תמונה

זוהי דוגמה מקצה לקצה כיצד לקרוא ולכתוב נתוני תמונה באמצעות 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
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

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 את התכונות tf.train.Example התואמים ל- 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.image.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 . לאחר מכן, פונקציונלי את הקוד לעיל וכתוב את הודעות הדוגמה לקובץ בשם 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