Catat tanggalnya! Google I / O mengembalikan 18-20 Mei Daftar sekarang
Halaman ini diterjemahkan oleh Cloud Translation API.
Switch to English

TFRecord dan tf.train.Example

Lihat di TensorFlow.org Jalankan di Google Colab Lihat sumber di GitHub Unduh buku catatan

Format TFRecord adalah format sederhana untuk menyimpan urutan catatan biner.

Buffer protokol adalah pustaka lintas platform dan lintas bahasa untuk serialisasi data terstruktur yang efisien.

Pesan protokol ditentukan oleh file .proto , ini seringkali merupakan cara termudah untuk memahami jenis pesan.

Pesan tf.train.Example (atau protobuf) adalah jenis pesan fleksibel yang mewakili pemetaan {"string": value} . Ini dirancang untuk digunakan dengan TensorFlow dan digunakan di seluruh API level yang lebih tinggi seperti TFX .

Notebook ini akan mendemonstrasikan cara membuat, mengurai, dan menggunakan pesan tf.train.Example , lalu membuat serial, menulis, dan membaca pesan tf.train.Example ke dan dari file .tfrecord .

Mempersiapkan

import tensorflow as tf

import numpy as np
import IPython.display as display

tf.train.Example

Tipe data untuk tf.train.Example

Pada dasarnya, tf.train.Example adalah tf.train.Example {"string": tf.train.Feature} .

Jenis pesan tf.train.Feature dapat menerima salah satu dari tiga jenis berikut (Lihat file .proto untuk referensi). Sebagian besar jenis generik lainnya dapat dipaksakan menjadi salah satu dari berikut ini:

  1. tf.train.BytesList (tipe berikut dapat dipaksakan)

    • string
    • byte
  2. tf.train.FloatList (tipe berikut dapat dipaksakan)

    • float ( float32 )
    • double ( float64 )
  3. tf.train.Int64List (tipe berikut dapat dipaksakan)

    • bool
    • enum
    • int32
    • uint32
    • int64
    • uint64

Untuk mengonversi jenis TensorFlow standar menjadi tf.train.Example -compatible tf.train.Feature , Anda dapat menggunakan fungsi pintasan di bawah ini. Perhatikan bahwa setiap fungsi mengambil nilai masukan skalar dan mengembalikan tf.train.Feature berisi salah satu dari tiga jenis list atas:

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

Di bawah ini adalah beberapa contoh cara kerja fungsi-fungsi ini. Perhatikan berbagai jenis masukan dan jenis keluaran standar. Jika jenis masukan untuk suatu fungsi tidak cocok dengan salah satu jenis pemaksaan yang disebutkan di atas, fungsi tersebut akan memunculkan pengecualian (misalnya _int64_feature(1.0) akan mengalami error, karena 1.0 adalah float, jadi sebaiknya digunakan dengan fungsi _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
}

Semua pesan proto dapat diserialkan ke string biner menggunakan metode .SerializeToString :

feature = _float_feature(np.exp(1))

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

Membuat pesan tf.train.Example

Misalkan Anda ingin membuat pesan tf.train.Example dari data yang ada. Dalam praktiknya, kumpulan data dapat berasal dari mana saja, tetapi prosedur pembuatan tf.train.Example pesan dari satu observasi akan sama:

  1. Dalam setiap observasi, setiap nilai perlu diubah menjadi tf.train.Feature berisi salah satu dari 3 jenis yang kompatibel, menggunakan salah satu fungsi di atas.

  2. Anda membuat peta (kamus) dari string nama fitur ke nilai fitur yang dikodekan yang dihasilkan di # 1.

  3. Peta yang dihasilkan pada langkah 2 diubah menjadi pesan Features .

Di notebook ini, Anda akan membuat dataset menggunakan NumPy.

Dataset ini akan memiliki 4 fitur:

  • fitur boolean, False atau True dengan probabilitas yang sama
  • fitur bilangan bulat yang dipilih secara acak dari [0, 5]
  • fitur string yang dihasilkan dari tabel string dengan menggunakan fitur integer sebagai indeks
  • fitur float dari distribusi normal standar

Pertimbangkan sampel yang terdiri dari 10.000 observasi yang terdistribusi secara independen dan identik dari masing-masing distribusi di atas:

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

Setiap fitur ini dapat dipaksa menjadi tf.train.Example -compatible type menggunakan salah satu dari _bytes_feature , _float_feature , _int64_feature . Anda kemudian dapat membuat pesan tf.train.Example dari fitur yang dikodekan ini:

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

Misalnya, Anda memiliki satu observasi dari kumpulan data, [False, 4, bytes('goat'), 0.9876] . Anda bisa membuat dan mencetak pesan tf.train.Example untuk observasi ini menggunakan create_message() . Setiap pengamatan tunggal akan ditulis sebagai pesan Features seperti di atas. Perhatikan bahwa pesan tf.train.Example hanyalah pembungkus di sekitar pesan 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'

Untuk memecahkan kode pesan, gunakan metode 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
      }
    }
  }
}

Detail format TFRecords

File TFRecord berisi urutan record. File hanya dapat dibaca secara berurutan.

Setiap record berisi byte-string, untuk data-payload, ditambah data-length, dan hash CRC32C (32-bit CRC menggunakan Castagnoli polynomial) untuk pemeriksaan integritas.

Setiap catatan disimpan dalam format berikut:

uint64 length
uint32 masked_crc32_of_length
byte   data[length]
uint32 masked_crc32_of_data

Catatan tersebut digabungkan untuk menghasilkan file. CRC dijelaskan di sini , dan mask dari CRC adalah:

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

TFRecord file menggunakan tf.data

Modul tf.data juga menyediakan fitur untuk membaca dan menulis data di TensorFlow.

Menulis file TFRecord

Cara termudah untuk memasukkan data ke dalam kumpulan data adalah dengan menggunakan metode from_tensor_slices .

Diterapkan ke array, ini mengembalikan kumpulan data skalar:

tf.data.Dataset.from_tensor_slices(feature1)
<TensorSliceDataset shapes: (), types: tf.int64>

Diterapkan ke tuple array, ini mengembalikan kumpulan data tupel:

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)

Gunakan metode tf.data.Dataset.map untuk menerapkan fungsi ke setiap elemen Dataset .

Fungsi yang dipetakan harus beroperasi dalam mode grafik TensorFlow — harus beroperasi pada dan menampilkan tf.Tensors . Fungsi non-tensor, seperti serialize_example , dapat dibungkus dengan tf.py_function agar kompatibel.

Menggunakan tf.py_function membutuhkan untuk menentukan bentuk dan jenis informasi yang jika tidak tersedia tidak tersedia:

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

Terapkan fungsi ini ke setiap elemen dalam kumpulan data:

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>

Dan tulis ke file TFRecord:

filename = 'test.tfrecord'
writer = tf.data.experimental.TFRecordWriter(filename)
writer.write(serialized_features_dataset)

Membaca file TFRecord

Anda juga dapat membaca file TFRecord menggunakan kelas tf.data.TFRecordDataset .

Informasi lebih lanjut tentang menggunakan file tf.data menggunakan tf.data dapat ditemukan di sini .

Menggunakan TFRecordDataset dapat berguna untuk menstandarisasi data masukan dan mengoptimalkan kinerja.

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

Pada titik ini, kumpulan data berisi pesan tf.train.Example berseri. Ketika diiterasi, ia mengembalikan ini sebagai tensor string skalar.

Gunakan metode .take untuk hanya menampilkan 10 record pertama.

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

Tensor ini dapat diurai menggunakan fungsi di bawah ini. Perhatikan bahwa feature_description sini diperlukan karena feature_description data menggunakan eksekusi grafik, dan memerlukan deskripsi ini untuk membuat tanda tangan bentuk dan jenisnya:

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

Atau, gunakan tf.parse example untuk mengurai seluruh kelompok sekaligus. Terapkan fungsi ini ke setiap item dalam dataset menggunakan metode 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}>

Gunakan eager execution untuk menampilkan observasi dalam dataset. Ada 10.000 observasi dalam dataset ini, tetapi Anda hanya akan menampilkan 10. Data pertama ditampilkan sebagai kamus fitur. Setiap item adalah tf.Tensor , dan elemen numpy tensor ini menampilkan nilai fitur:

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

Di sini, tf.parse_example fungsi membongkar tf.train.Example bidang dalam tensor standar.

TFRecord file dengan Python

Modul tf.io juga berisi fungsi-fungsi Python murni untuk membaca dan menulis file TFRecord.

Menulis file TFRecord

Selanjutnya, tulis 10.000 observasi ke file test.tfrecord . Setiap observasi diubah menjadi pesan tf.train.Example , lalu ditulis ke file. Anda kemudian dapat memverifikasi bahwa file test.tfrecord telah dibuat:

# 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

Membaca file TFRecord

Tensor berseri ini dapat dengan mudah diurai menggunakan 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
      }
    }
  }
}

Panduan: Membaca dan menulis data gambar

Ini adalah contoh ujung ke ujung tentang cara membaca dan menulis data gambar menggunakan TFRecords. Dengan menggunakan gambar sebagai data masukan, Anda akan menulis data sebagai file TFRecord, kemudian membaca kembali file tersebut dan menampilkan gambar tersebut.

Ini dapat berguna jika, misalnya, Anda ingin menggunakan beberapa model pada set data masukan yang sama. Alih-alih menyimpan data gambar mentah, itu dapat diproses ke dalam format TFRecords, dan itu dapat digunakan dalam semua pemrosesan dan pemodelan lebih lanjut.

Pertama, mari unduh gambar kucing di salju dan foto Jembatan Williamsburg, NYC ini sedang dibangun.

Ambil gambarnya

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

Tulis file TFRecord

Seperti sebelumnya, enkode fitur sebagai tipe yang kompatibel dengan tf.train.Example . Ini menyimpan fitur string gambar mentah, serta tinggi, lebar, kedalaman, dan fitur label arbitrer. Yang terakhir digunakan saat Anda menulis file untuk membedakan antara gambar kucing dan gambar jembatan. Gunakan 0 untuk gambar kucing, dan 1 untuk gambar jembatan:

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

Perhatikan bahwa semua fitur sekarang disimpan di pesan tf.train.Example . Selanjutnya, fungsionalkan kode di atas dan tulis pesan contoh ke file bernama 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

Baca file TFRecord

Anda sekarang memiliki file— images.tfrecords — dan sekarang dapat melakukan iterasi terhadap record di dalamnya untuk membaca kembali apa yang Anda tulis. Mengingat dalam contoh ini Anda hanya akan mereproduksi gambar, satu-satunya fitur yang Anda perlukan adalah string gambar mentah. Ekstrak menggunakan getter yang dijelaskan di atas, yaitu example.features.feature['image_raw'].bytes_list.value[0] . Anda juga dapat menggunakan label untuk menentukan rekaman mana yang merupakan cat dan mana yang menjembatani:

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

Pulihkan gambar dari file TFRecord:

for image_features in parsed_image_dataset:
  image_raw = image_features['image_raw'].numpy()
  display.display(display.Image(data=image_raw))

jpeg

jpeg