הצג באתר TensorFlow.org | הפעל בגוגל קולאב | צפה במקור ב-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
לעיון). ניתן לכפות את רוב הסוגים הגנריים האחרים לאחד מאלה:
tf.train.BytesList
(ניתן לכפות על הסוגים הבאים)-
string
-
byte
-
tf.train.FloatList
(ניתן לכפות על הסוגים הבאים)-
float
(float32
) -
double
(float64
)
-
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_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
.דוגמה מתצפית בודדת יהיה זהה:
בתוך כל תצפית, יש להמיר כל ערך ל-
tf.train.Feature
המכיל אחד מ-3 הסוגים התואמים, באמצעות אחת מהפונקציות שלמעלה.אתה יוצר מפה (מילון) ממחרוזת שם התכונה לערך התכונה המקודד שנוצר ב-#1.
המפה שהופקה בשלב 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\x11\n\x08feature1\x12\x05\x1a\x03\n\x01\x04\n\x11\n\x08feature0\x12\x05\x1a\x03\n\x01\x00\n\x14\n\x08feature3\x12\x08\x12\x06\n\x04[\xd3|?'
כדי לפענח את ההודעה השתמש בשיטת 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 מתוארים כאן , והמסכה של 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 element_spec=TensorSpec(shape=(), dtype=tf.int64, name=None)>
מיושם על טאפל של מערכים, הוא מחזיר מערך נתונים של tuples:
features_dataset = tf.data.Dataset.from_tensor_slices((feature0, feature1, feature2, feature3))
features_dataset
<TensorSliceDataset element_spec=(TensorSpec(shape=(), dtype=tf.bool, name=None), TensorSpec(shape=(), dtype=tf.int64, name=None), TensorSpec(shape=(), dtype=tf.string, name=None), TensorSpec(shape=(), dtype=tf.float64, name=None))>
# 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(4, shape=(), dtype=int64) tf.Tensor(b'goat', shape=(), dtype=string) tf.Tensor(0.5251196235602504, 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'\nR\n\x14\n\x08feature3\x12\x08\x12\x06\n\x04=n\x06?\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'>
החל את הפונקציה הזו על כל רכיב במערך הנתונים:
serialized_features_dataset = features_dataset.map(tf_serialize_example)
serialized_features_dataset
<MapDataset element_spec=TensorSpec(shape=(), dtype=tf.string, name=None)>
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 element_spec=TensorSpec(shape=(), dtype=tf.string, name=None)>
וכתוב אותם לקובץ TFRecord:
filename = 'test.tfrecord'
writer = tf.data.experimental.TFRecordWriter(filename)
writer.write(serialized_features_dataset)
WARNING:tensorflow:From /tmp/ipykernel_25215/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: Build TensorFlow input pipelines .
שימוש ב- TFRecordDataset
s יכול להיות שימושי לסטנדרטיזציה של נתוני קלט ואופטימיזציה של ביצועים.
filenames = [filename]
raw_dataset = tf.data.TFRecordDataset(filenames)
raw_dataset
<TFRecordDatasetV2 element_spec=TensorSpec(shape=(), dtype=tf.string, name=None)>
בשלב זה מערך הנתונים מכיל הודעות tf.train.Example
. כאשר הוא חוזר על זה מחזיר את אלה כחותני מיתרים סקלרים.
השתמש בשיטת .take
כדי להציג רק את 10 הרשומות הראשונות.
for raw_record in raw_dataset.take(10):
print(repr(raw_record))
<tf.Tensor: shape=(), dtype=string, numpy=b'\nR\n\x11\n\x08feature0\x12\x05\x1a\x03\n\x01\x00\n\x11\n\x08feature1\x12\x05\x1a\x03\n\x01\x04\n\x14\n\x08feature2\x12\x08\n\x06\n\x04goat\n\x14\n\x08feature3\x12\x08\x12\x06\n\x04=n\x06?'> <tf.Tensor: shape=(), dtype=string, numpy=b'\nR\n\x11\n\x08feature1\x12\x05\x1a\x03\n\x01\x04\n\x11\n\x08feature0\x12\x05\x1a\x03\n\x01\x01\n\x14\n\x08feature3\x12\x08\x12\x06\n\x04\x9d\xfa\x98\xbe\n\x14\n\x08feature2\x12\x08\n\x06\n\x04goat'> <tf.Tensor: shape=(), dtype=string, numpy=b'\nQ\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\x04a\xc0r?\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\x01\n\x11\n\x08feature1\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\x92Q(?'> <tf.Tensor: shape=(), dtype=string, numpy=b'\nR\n\x14\n\x08feature2\x12\x08\n\x06\n\x04goat\n\x14\n\x08feature3\x12\x08\x12\x06\n\x04>\xc0\xe5>\n\x11\n\x08feature0\x12\x05\x1a\x03\n\x01\x01\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\x04I!\xde\xbe\n\x11\n\x08feature1\x12\x05\x1a\x03\n\x01\x02\n\x11\n\x08feature0\x12\x05\x1a\x03\n\x01\x00\n\x17\n\x08feature2\x12\x0b\n\t\n\x07chicken'> <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\xe0\x1a\xab\xbf\n\x13\n\x08feature2\x12\x07\n\x05\n\x03cat'> <tf.Tensor: shape=(), dtype=string, numpy=b'\nQ\n\x13\n\x08feature2\x12\x07\n\x05\n\x03cat\n\x11\n\x08feature0\x12\x05\x1a\x03\n\x01\x01\n\x14\n\x08feature3\x12\x08\x12\x06\n\x04\x87\xb2\xd7?\n\x11\n\x08feature1\x12\x05\x1a\x03\n\x01\x00'> <tf.Tensor: shape=(), dtype=string, numpy=b'\nR\n\x11\n\x08feature1\x12\x05\x1a\x03\n\x01\x04\n\x11\n\x08feature0\x12\x05\x1a\x03\n\x01\x01\n\x14\n\x08feature3\x12\x08\x12\x06\n\x04n\xe19>\n\x14\n\x08feature2\x12\x08\n\x06\n\x04goat'> <tf.Tensor: shape=(), dtype=string, numpy=b'\nR\n\x14\n\x08feature3\x12\x08\x12\x06\n\x04\x1as\xd9\xbf\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\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 element_spec={'feature0': TensorSpec(shape=(), dtype=tf.int64, name=None), 'feature1': TensorSpec(shape=(), dtype=tf.int64, name=None), 'feature2': TensorSpec(shape=(), dtype=tf.string, name=None), 'feature3': TensorSpec(shape=(), dtype=tf.float32, name=None)}>
השתמש בביצוע נלהב כדי להציג את התצפיות במערך הנתונים. יש 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=4>, 'feature2': <tf.Tensor: shape=(), dtype=string, numpy=b'goat'>, 'feature3': <tf.Tensor: shape=(), dtype=float32, numpy=0.5251196>} {'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=-0.29878703>} {'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.94824797>} {'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.65749466>} {'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=0.44873232>} {'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.4338477>} {'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=-1.3367577>} {'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=1.6851357>} {'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=0.18152401>} {'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.6988251>}
כאן, הפונקציה tf.parse_example
מפרקת את השדות tf.train.Example
סטנדרטיים.
קבצי TFRecord ב- Python
מודול tf.io
מכיל גם פונקציות Pure-Python לקריאה וכתיבה של קבצי 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 element_spec=TensorSpec(shape=(), dtype=tf.string, name=None)>
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: 4 } } } feature { key: "feature2" value { bytes_list { value: "goat" } } } feature { key: "feature3" value { float_list { value: 0.5251196026802063 } } } }
זה מחזיר פרוטו tf.train.Example
להשתמש בו כפי שהוא, אבל זה בעצם ייצוג של:
Dict[str,
Union[List[float],
List[int],
List[str]]]
הקוד הבא ממיר באופן ידני את Example
למילון של מערכי NumPy, מבלי להשתמש ב- TensorFlow Ops. עיין בקובץ PROTO לפרטים.
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
{'feature3': array([0.5251196]), 'feature1': array([4]), 'feature0': array([0]), 'feature2': array([b'goat'], dtype='|S4')}
הדרכה: קריאה וכתיבה של נתוני תמונה
זוהי דוגמה מקצה לקצה כיצד לקרוא ולכתוב נתוני תמונה באמצעות 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>'))
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>'))
כתוב את קובץ 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
. לאחר מכן, הפעל את הקוד למעלה וכתוב את ההודעות לדוגמה לקובץ בשם 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 element_spec={'depth': TensorSpec(shape=(), dtype=tf.int64, name=None), 'height': TensorSpec(shape=(), dtype=tf.int64, name=None), 'image_raw': TensorSpec(shape=(), dtype=tf.string, name=None), 'label': TensorSpec(shape=(), dtype=tf.int64, name=None), 'width': TensorSpec(shape=(), dtype=tf.int64, name=None)}>
שחזר את התמונות מקובץ TFRecord:
for image_features in parsed_image_dataset:
image_raw = image_features['image_raw'].numpy()
display.display(display.Image(data=image_raw))