![]() | ![]() | ![]() | ![]() |
פורמט 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
להפניה). ניתן לכפות את רוב הסוגים הגנריים האחרים לאחד מאלה:
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, לכן יש להשתמש בפונקציה _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
הודעת דוגמה מתצפית יחידה תהיה זהה:
בתוך כל תצפית, צריך להמיר כל ערך ל-
tf.train.Feature
המכילה אחד משלושת הסוגים התואמים, תוך שימוש באחת מהפונקציות לעיל.אתה יוצר מפה (מילון) ממחרוזת שם התכונה לערך התכונה המקודד המיוצר במספר 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
דוגמה 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>'))
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
את התכונות 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))