RSVP für Ihr lokales TensorFlow Everywhere-Event noch heute!
Diese Seite wurde von der Cloud Translation API übersetzt.
Switch to English

TFRecord und tf.train.Example

Ansicht auf TensorFlow.org In Google Colab ausführen Quelle auf GitHub anzeigen Notizbuch herunterladen

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:

  1. tf.train.BytesList (die folgenden Typen können tf.train.BytesList werden)

    • string
    • byte
  2. tf.train.FloatList (die folgenden Typen können tf.train.FloatList werden)

    • float ( float32 )
    • double ( float64 )
  3. tf.train.Int64List (die folgenden Typen können tf.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:

  1. 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.

  2. Sie erstellen eine Zuordnung (ein Wörterbuch) aus der Feature-Namenszeichenfolge zu dem in # 1 erstellten codierten Feature-Wert.

  3. 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 oder True 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>'))

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

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

JPEG

JPEG