![]() | ![]() | ![]() | ![]() |
Das TFRecord-Format ist ein einfaches Format zum Speichern einer Folge von Binärdatensätzen.
Protokollpuffer sind eine plattformübergreifende, sprachübergreifende Bibliothek zur effizienten Serialisierung strukturierter Daten.
Protokollnachrichten werden durch .proto
Dateien definiert. Dies ist häufig der einfachste Weg, einen Nachrichtentyp zu verstehen.
Die tf.train.Example
Nachricht (oder protobuf) ist ein flexibler Nachrichtentyp, der eine Zuordnung {"string": value}
. Es wurde für die Verwendung mit TensorFlow entwickelt und wird in allen übergeordneten APIs wie TFX verwendet .
In diesem Notizbuch wird gezeigt, wie Sie die tf.train.Example
Nachricht erstellen, analysieren und verwenden und anschließend tf.train.Example
Nachrichten in und aus .tfrecord
Dateien serialisieren, schreiben und lesen.
Installieren
import tensorflow as tf
import numpy as np
import IPython.display as display
tf.train.Example
Datentypen für tf.train.Example
Grundsätzlich ist ein tf.train.Example
ein {"string": tf.train.Feature}
Mapping.
Der Nachrichtentyp tf.train.Feature
kann einen der folgenden drei Typen akzeptieren (Referenz siehe .proto
Datei ). Die meisten anderen generischen Typen können zu einem der folgenden gezwungen werden:
tf.train.BytesList
(die folgenden Typen könnentf.train.BytesList
werden)-
string
-
byte
-
tf.train.FloatList
(die folgenden Typen könnentf.train.FloatList
werden)-
float
(float32
) -
double
(float64
)
-
tf.train.Int64List
(die folgenden Typen könnentf.train.Int64List
werden)-
bool
-
enum
-
int32
-
uint32
-
int64
-
uint64
-
Um einen Standard-TensorFlow-Typ in einen tf.train.Example
kompatiblen tf.train.Feature
zu konvertieren, können Sie die folgenden Verknüpfungsfunktionen verwenden. Man beachte , daß jede Funktion einen skalaren Eingangswert nimmt und gibt eine tf.train.Feature
einer der drei enthaltenden list
Typen oben:
# 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]))
Im Folgenden finden Sie einige Beispiele für die Funktionsweise dieser Funktionen. Beachten Sie die unterschiedlichen Eingabetypen und die standardisierten Ausgabetypen. Wenn der Eingabetyp für eine Funktion nicht mit einem der oben angegebenen Zwangstypen übereinstimmt, löst die Funktion eine Ausnahme aus (z. B. _int64_feature(1.0)
ein Fehler auf, da 1.0
ein Float ist und daher stattdessen mit der Funktion _float_feature
verwendet werden sollte). ::
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 }
Alle .SerializeToString
mithilfe der .SerializeToString
Methode in eine .SerializeToString
werden:
feature = _float_feature(np.exp(1))
feature.SerializeToString()
b'\x12\x06\n\x04T\xf8-@'
Erstellen einer tf.train.Example
Nachricht
Angenommen, Sie möchten eine tf.train.Example
Nachricht aus vorhandenen Daten erstellen. In der Praxis kann der Datensatz von überall kommen, aber das Verfahren zum Erstellen des tf.train.Example
aus einer einzelnen Beobachtung ist dasselbe:
Innerhalb jeder Beobachtung muss jeder Wert unter Verwendung einer der oben genannten Funktionen in einen
tf.train.Feature
konvertiert werden, der einen der 3 kompatiblen Typen enthält.Sie erstellen eine Zuordnung (ein Wörterbuch) aus der Feature-Namenszeichenfolge zu dem in # 1 erstellten codierten Feature-Wert.
Die in Schritt 2 erstellte Karte wird in eine
Features
Nachricht konvertiert.
In diesem Notizbuch erstellen Sie einen Datensatz mit NumPy.
Dieser Datensatz verfügt über 4 Funktionen:
- ein boolesches Merkmal,
False
oderTrue
mit gleicher Wahrscheinlichkeit - ein ganzzahliges Merkmal, das gleichmäßig zufällig aus
[0, 5]
- Ein String-Feature, das aus einer String-Tabelle generiert wird, indem das Integer-Feature als Index verwendet wird
- ein Float-Feature aus einer Standardnormalverteilung
Stellen Sie sich eine Stichprobe vor, die aus 10.000 unabhängig und identisch verteilten Beobachtungen aus jeder der oben genannten Verteilungen besteht:
# 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)
Jedes dieser Features kann zu einem tf.train.Example
kompatiblen Typ gezwungen werden, indem eines von _bytes_feature
, _float_feature
, _int64_feature
. Sie können dann eine tf.train.Example
Nachricht aus diesen codierten Funktionen erstellen:
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()
Angenommen, Sie haben eine einzelne Beobachtung aus dem Datensatz [False, 4, bytes('goat'), 0.9876]
. Sie können die tf.train.Example
Nachricht für diese Beobachtung mit create_message()
erstellen und drucken. Jede einzelne Beobachtung wird wie oben beschrieben als Features
Nachricht geschrieben. Beachten Sie, dass die tf.train.Example
Nachricht nur ein Wrapper um die Features
Nachricht ist:
# 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'
Verwenden tf.train.Example.FromString
zum Dekodieren der Nachricht die Methode 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-Formatdetails
Eine TFRecord-Datei enthält eine Folge von Datensätzen. Die Datei kann nur nacheinander gelesen werden.
Jeder Datensatz enthält eine Byte-Zeichenfolge für die Datennutzlast sowie die Datenlänge und CRC32C-Hashes (32-Bit-CRC unter Verwendung des Castagnoli-Polynoms) zur Integritätsprüfung.
Jeder Datensatz wird in den folgenden Formaten gespeichert:
uint64 length
uint32 masked_crc32_of_length
byte data[length]
uint32 masked_crc32_of_data
Die Datensätze werden miteinander verknüpft, um die Datei zu erstellen. CRCs werden hier beschrieben und die Maske eines CRC lautet:
masked_crc = ((crc >> 15) | (crc << 17)) + 0xa282ead8ul
TFRecord-Dateien mit tf.data
Das Modul tf.data
bietet auch Tools zum Lesen und Schreiben von Daten in TensorFlow.
Schreiben einer TFRecord-Datei
Der einfachste Weg, die Daten in ein Dataset zu übertragen, ist die Verwendung der from_tensor_slices
Methode.
Auf ein Array angewendet wird ein Datensatz mit Skalaren zurückgegeben:
tf.data.Dataset.from_tensor_slices(feature1)
<TensorSliceDataset shapes: (), types: tf.int64>
Auf ein Tupel von Arrays angewendet, gibt es einen Datensatz von Tupeln zurück:
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)
Verwenden Sie die tf.data.Dataset.map
Verfahren , eine Funktion zu jedem Element einer anzuwenden Dataset
.
Die zugeordnete Funktion muss im TensorFlow-Diagrammmodus ausgeführt werden. Sie muss auf tf.Tensors
und diese zurückgeben. Eine Nicht-Tensor-Funktion wie serialize_example
kann mit tf.py_function
, um sie kompatibel zu machen.
Für die Verwendung von tf.py_function
müssen die Form- und tf.py_function
angegeben werden, die ansonsten nicht verfügbar sind:
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'>
Wenden Sie diese Funktion auf jedes Element im Datensatz an:
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>
Und schreiben Sie sie in eine TFRecord-Datei:
filename = 'test.tfrecord'
writer = tf.data.experimental.TFRecordWriter(filename)
writer.write(serialized_features_dataset)
Lesen einer TFRecord-Datei
Sie können die TFRecord-Datei auch mit der Klasse tf.data.TFRecordDataset
lesen.
Weitere Informationen zum Konsumieren von TFRecord-Dateien mit tf.data
finden Sie hier .
Die Verwendung von TFRecordDataset
kann nützlich sein, um Eingabedaten zu standardisieren und die Leistung zu optimieren.
filenames = [filename]
raw_dataset = tf.data.TFRecordDataset(filenames)
raw_dataset
<TFRecordDatasetV2 shapes: (), types: tf.string>
Zu diesem Zeitpunkt enthält der Datensatz serialisierte tf.train.Example
Nachrichten. Bei Iteration werden diese als skalare String-Tensoren zurückgegeben.
Verwenden Sie die .take
Methode, um nur die ersten 10 Datensätze .take
.
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'>
Diese Tensoren können mit der folgenden Funktion analysiert werden. Beachten Sie, dass die feature_description
hier erforderlich ist, da Datasets die Diagrammausführung verwenden und diese Beschreibung benötigen, um ihre Form und feature_description
zu erstellen:
# 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)
Alternativ können tf.parse example
, um den gesamten Stapel auf einmal zu analysieren. Wenden Sie diese Funktion mit der Methode tf.data.Dataset.map
auf jedes Element im Dataset an:
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}>
Verwenden Sie die eifrige Ausführung, um die Beobachtungen im Datensatz anzuzeigen. Es gibt 10.000 Beobachtungen in diesem Datensatz, aber Sie werden nur die ersten 10 anzeigen. Die Daten werden als Wörterbuch der Funktionen angezeigt. Jedes Element ist ein tf.Tensor
, und das numpy
Element dieses Tensors zeigt den Wert des Features an:
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>}
Hier tf.parse_example
Funktion tf.parse_example die Felder tf.train.Example
in Standardtensoren.
TFRecord-Dateien in Python
Das tf.io
Modul enthält außerdem reine Python-Funktionen zum Lesen und Schreiben von TFRecord-Dateien.
Schreiben einer TFRecord-Datei
Schreiben Sie als Nächstes die 10.000 Beobachtungen in die Datei test.tfrecord
. Jede Beobachtung wird in eine tf.train.Example
Nachricht konvertiert und dann in eine Datei geschrieben. Sie können dann überprüfen, ob die Datei test.tfrecord
erstellt wurde:
# 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
Lesen einer TFRecord-Datei
Diese serialisierten Tensoren können einfach mit tf.train.Example.ParseFromString
analysiert werden:
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 } } } }
Exemplarische Vorgehensweise: Lesen und Schreiben von Bilddaten
Dies ist ein durchgängiges Beispiel für das Lesen und Schreiben von Bilddaten mit TFRecords. Wenn Sie ein Bild als Eingabedaten verwenden, schreiben Sie die Daten als TFRecord-Datei, lesen die Datei zurück und zeigen das Bild an.
Dies kann nützlich sein, wenn Sie beispielsweise mehrere Modelle in demselben Eingabedatensatz verwenden möchten. Anstatt die Bilddaten roh zu speichern, können sie im TFRecords-Format vorverarbeitet werden, das für alle weiteren Verarbeitungen und Modellierungen verwendet werden kann.
Lassen Sie uns zuerst dieses Bild einer Katze im Schnee und dieses Foto der im Bau befindlichen Williamsburg Bridge, NYC, herunterladen.
Holen Sie sich die Bilder
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>'))
Schreiben Sie die TFRecord-Datei
Codieren Sie die Features nach wie vor als Typen, die mit tf.train.Example
kompatibel tf.train.Example
. Hier werden die Funktion für Rohbildzeichenfolgen sowie die Funktion für Höhe, Breite, Tiefe und beliebige label
gespeichert. Letzteres wird verwendet, wenn Sie die Datei schreiben, um zwischen dem Katzenbild und dem Brückenbild zu unterscheiden. Verwenden Sie 0
für das Katzenbild und 1
für das Brückenbild:
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 } ...
Beachten Sie, dass alle Funktionen jetzt in der Nachricht tf.train.Example
gespeichert sind. Als nächstes funktionalisieren Sie den obigen Code und schreiben die Beispielnachrichten in eine Datei mit dem Namen 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
Lesen Sie die TFRecord-Datei
Sie haben jetzt die Datei images.tfrecords
und können jetzt die darin images.tfrecords
Datensätze images.tfrecords
, um zurückzulesen, was Sie geschrieben haben. Da Sie in diesem Beispiel nur das Bild reproduzieren, benötigen Sie nur die Rohbildzeichenfolge. Extrahieren Sie es mit den oben beschriebenen Gettern, nämlich example.features.feature['image_raw'].bytes_list.value[0]
. Sie können auch die Beschriftungen verwenden, um zu bestimmen, welcher Datensatz die Katze und welcher die Brücke ist:
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}>
Stellen Sie die Bilder aus der TFRecord-Datei wieder her:
for image_features in parsed_image_dataset:
image_raw = image_features['image_raw'].numpy()
display.display(display.Image(data=image_raw))