Halaman ini diterjemahkan oleh Cloud Translation API.
Switch to English

TFRecord dan tf. Contoh

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

Untuk membaca data secara efisien akan sangat membantu untuk membuat serialisasi data Anda dan menyimpannya dalam satu set file (masing-masing 100-200MB) yang masing-masing dapat dibaca secara linear. Ini terutama benar jika data sedang dialirkan melalui jaringan. Ini juga bisa berguna untuk melakukan caching setiap preprocessing data.

Format TFRecord adalah format sederhana untuk menyimpan urutan catatan biner.

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

Pesan protokol didefinisikan oleh file .proto , ini sering merupakan cara termudah untuk memahami jenis pesan.

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

Buku catatan ini akan menunjukkan cara membuat, mem-parsing, dan menggunakan pesan tf.Example , lalu membuat serial, menulis, dan membaca tf.Example pesan ke dan dari file .tfrecord .

Mempersiapkan

 import tensorflow as tf

import numpy as np
import IPython.display as display
 

tf.Example

Jenis data untuk tf.Example

Pada dasarnya, tf.Example adalah tf.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 tipe generik lain dapat dipaksa menjadi salah satu dari 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 mengkonversi tipe TensorFlow standar ke tf.Example -compatible tf.train.Feature . tf.train.Feature , Anda dapat menggunakan fungsi pintasan di bawah ini. Perhatikan bahwa setiap fungsi mengambil nilai input 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.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 bagaimana fungsi-fungsi ini bekerja. Perhatikan berbagai tipe input dan tipe output standar. Jika tipe input untuk suatu fungsi tidak cocok dengan salah satu tipe koersibel yang disebutkan di atas, fungsi tersebut akan memunculkan eksepsi (mis. _int64_feature(1.0) akan error out, karena 1.0 adalah float, jadi sebaiknya digunakan dengan fungsi _float_feature sebagai gantinya) :

 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 diserialisasi ke string biner menggunakan metode .SerializeToString :

 feature = _float_feature(np.exp(1))

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

Membuat pesan tf.Example

Misalkan Anda ingin membuat pesan tf.Example dari data yang ada. Dalam praktiknya, dataset mungkin berasal dari mana saja, tetapi prosedur pembuatan tf.Example pesan dari satu pengamatan akan sama:

  1. Dalam setiap pengamatan, setiap nilai perlu dikonversi ke 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 disandikan yang diproduksi di # 1.

  3. Peta yang dihasilkan pada langkah 2 dikonversi ke pesan Features .

Di buku catatan ini, Anda akan membuat dataset menggunakan NumPy.

Dataset ini akan memiliki 4 fitur:

  • fitur boolean, False or True dengan probabilitas yang sama
  • fitur integer 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 pengamatan independen dan terdistribusi secara 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)
 

Masing-masing fitur ini dapat dipaksa menjadi tf.Example Contoh tf.Example kompatibel menggunakan salah satu dari _bytes_feature , _float_feature , _int64_feature . Anda kemudian dapat membuat pesan tf.Example dari fitur yang disandikan ini:

 def serialize_example(feature0, feature1, feature2, feature3):
  """
  Creates a tf.Example message ready to be written to a file.
  """
  # Create a dictionary mapping the feature name to the tf.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, anggap Anda memiliki pengamatan tunggal dari dataset, [False, 4, bytes('goat'), 0.9876] . Anda dapat membuat dan mencetak pesan tf.Example untuk pengamatan ini menggunakan create_message() . Setiap pengamatan tunggal akan ditulis sebagai pesan Features seperti di atas. Perhatikan bahwa pesan tf.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\x11\n\x08feature1\x12\x05\x1a\x03\n\x01\x04\n\x14\n\x08feature2\x12\x08\n\x06\n\x04goat\n\x14\n\x08feature3\x12\x08\x12\x06\n\x04[\xd3|?'

Untuk mendekode 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 catatan. File hanya dapat dibaca secara berurutan.

Setiap catatan berisi byte-string, untuk data-payload, ditambah panjang data, dan CRC32C (32-bit CRC menggunakan polinomial Castagnoli) hash 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 disatukan untuk menghasilkan file. CRC dijelaskan di sini , dan topeng CRC adalah:

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

File tf.data menggunakan tf.data

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

Menulis file TFRecord

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

Diterapkan ke sebuah array, ia mengembalikan dataset skalar:

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

Diterapkan ke tupel array, ia mengembalikan set 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(True, shape=(), dtype=bool)
tf.Tensor(1, shape=(), dtype=int64)
tf.Tensor(b'dog', shape=(), dtype=string)
tf.Tensor(-0.7334449193276843, shape=(), dtype=float64)

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

Fungsi yang dipetakan harus beroperasi dalam mode grafik TensorFlow — ia harus beroperasi dan mengembalikan tf.Tensors . Fungsi non-tensor, seperti serialize_example , dapat dibungkus dengan tf.py_function untuk membuatnya kompatibel.

Menggunakan tf.py_function harus menentukan bentuk dan jenis informasi yang 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\x11\n\x08feature0\x12\x05\x1a\x03\n\x01\x01\n\x11\n\x08feature1\x12\x05\x1a\x03\n\x01\x01\n\x13\n\x08feature2\x12\x07\n\x05\n\x03dog\n\x14\n\x08feature3\x12\x08\x12\x06\n\x04\x0c\xc3;\xbf'>

Terapkan fungsi ini ke setiap elemen dalam dataset:

 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 menulisnya 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 penggunaan file tf.data menggunakan tf.data dapat ditemukan di sini .

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

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

Pada titik ini dataset berisi pesan tf.train.Example berseri. tf.train.Example . Ketika iterated di atasnya mengembalikan ini sebagai tensor string skalar.

Gunakan metode .take untuk hanya menampilkan 10 catatan 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\x03dog\n\x14\n\x08feature3\x12\x08\x12\x06\n\x04\x0c\xc3;\xbf\n\x11\n\x08feature0\x12\x05\x1a\x03\n\x01\x01\n\x11\n\x08feature1\x12\x05\x1a\x03\n\x01\x01'>
<tf.Tensor: shape=(), dtype=string, numpy=b'\nR\n\x11\n\x08feature0\x12\x05\x1a\x03\n\x01\x01\n\x11\n\x08feature1\x12\x05\x1a\x03\n\x01\x04\n\x14\n\x08feature2\x12\x08\n\x06\n\x04goat\n\x14\n\x08feature3\x12\x08\x12\x06\n\x04Da=?'>
<tf.Tensor: shape=(), dtype=string, numpy=b'\nR\n\x11\n\x08feature0\x12\x05\x1a\x03\n\x01\x01\n\x11\n\x08feature1\x12\x05\x1a\x03\n\x01\x04\n\x14\n\x08feature2\x12\x08\n\x06\n\x04goat\n\x14\n\x08feature3\x12\x08\x12\x06\n\x04\xaaV\xa6>'>
<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\x04>\x95\r\xbc\n\x11\n\x08feature0\x12\x05\x1a\x03\n\x01\x01\n\x11\n\x08feature1\x12\x05\x1a\x03\n\x01\x00'>
<tf.Tensor: shape=(), dtype=string, numpy=b'\nQ\n\x11\n\x08feature0\x12\x05\x1a\x03\n\x01\x00\n\x11\n\x08feature1\x12\x05\x1a\x03\n\x01\x01\n\x13\n\x08feature2\x12\x07\n\x05\n\x03dog\n\x14\n\x08feature3\x12\x08\x12\x06\n\x042\xb0\xbe\xbf'>
<tf.Tensor: shape=(), dtype=string, numpy=b'\nU\n\x11\n\x08feature0\x12\x05\x1a\x03\n\x01\x01\n\x11\n\x08feature1\x12\x05\x1a\x03\n\x01\x02\n\x17\n\x08feature2\x12\x0b\n\t\n\x07chicken\n\x14\n\x08feature3\x12\x08\x12\x06\n\x04\x8a\x0c\x9e;'>
<tf.Tensor: shape=(), dtype=string, numpy=b'\nS\n\x11\n\x08feature0\x12\x05\x1a\x03\n\x01\x01\n\x11\n\x08feature1\x12\x05\x1a\x03\n\x01\x03\n\x15\n\x08feature2\x12\t\n\x07\n\x05horse\n\x14\n\x08feature3\x12\x08\x12\x06\n\x04\x8c9S?'>
<tf.Tensor: shape=(), dtype=string, numpy=b'\nU\n\x11\n\x08feature0\x12\x05\x1a\x03\n\x01\x01\n\x11\n\x08feature1\x12\x05\x1a\x03\n\x01\x02\n\x17\n\x08feature2\x12\x0b\n\t\n\x07chicken\n\x14\n\x08feature3\x12\x08\x12\x06\n\x04\xbdk_\xbc'>
<tf.Tensor: shape=(), dtype=string, numpy=b'\nQ\n\x11\n\x08feature0\x12\x05\x1a\x03\n\x01\x01\n\x11\n\x08feature1\x12\x05\x1a\x03\n\x01\x01\n\x13\n\x08feature2\x12\x07\n\x05\n\x03dog\n\x14\n\x08feature3\x12\x08\x12\x06\n\x04H~\xd8?'>
<tf.Tensor: shape=(), dtype=string, numpy=b'\nR\n\x11\n\x08feature0\x12\x05\x1a\x03\n\x01\x01\n\x11\n\x08feature1\x12\x05\x1a\x03\n\x01\x04\n\x14\n\x08feature2\x12\x08\n\x06\n\x04goat\n\x14\n\x08feature3\x12\x08\x12\x06\n\x04z\x08\x1c?'>

Tensor ini dapat diuraikan menggunakan fungsi di bawah ini. Perhatikan bahwa feature_description diperlukan di sini karena dataset menggunakan eksekusi grafik, dan memerlukan deskripsi ini untuk membangun bentuk dan tipe tanda tangan mereka:

 # 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.Example` proto using the dictionary above.
  return tf.io.parse_single_example(example_proto, feature_description)
 

Atau, gunakan tf.parse example untuk mem-parsing seluruh batch 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 eksekusi yang cepat untuk menampilkan pengamatan dalam dataset. Ada 10.000 pengamatan dalam dataset ini, tetapi Anda hanya akan menampilkan 10. data pertama ditampilkan sebagai kamus fitur. Setiap item adalah tf.Tensor , dan elemen numpy dari tensor ini menampilkan nilai fitur:

 for parsed_record in parsed_dataset.take(10):
  print(repr(parsed_record))
 
{'feature0': <tf.Tensor: shape=(), dtype=int64, numpy=1>, 'feature1': <tf.Tensor: shape=(), dtype=int64, numpy=1>, 'feature2': <tf.Tensor: shape=(), dtype=string, numpy=b'dog'>, 'feature3': <tf.Tensor: shape=(), dtype=float32, numpy=-0.7334449>}
{'feature0': <tf.Tensor: shape=(), dtype=int64, numpy=1>, 'feature1': <tf.Tensor: shape=(), dtype=int64, numpy=4>, 'feature2': <tf.Tensor: shape=(), dtype=string, numpy=b'goat'>, 'feature3': <tf.Tensor: shape=(), dtype=float32, numpy=0.7397654>}
{'feature0': <tf.Tensor: shape=(), dtype=int64, numpy=1>, 'feature1': <tf.Tensor: shape=(), dtype=int64, numpy=4>, 'feature2': <tf.Tensor: shape=(), dtype=string, numpy=b'goat'>, 'feature3': <tf.Tensor: shape=(), dtype=float32, numpy=0.32487994>}
{'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.008641539>}
{'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=-1.489752>}
{'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.004823272>}
{'feature0': <tf.Tensor: shape=(), dtype=int64, numpy=1>, '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.82509685>}
{'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.013636527>}
{'feature0': <tf.Tensor: shape=(), dtype=int64, numpy=1>, 'feature1': <tf.Tensor: shape=(), dtype=int64, numpy=1>, 'feature2': <tf.Tensor: shape=(), dtype=string, numpy=b'dog'>, 'feature3': <tf.Tensor: shape=(), dtype=float32, numpy=1.6913538>}
{'feature0': <tf.Tensor: shape=(), dtype=int64, numpy=1>, 'feature1': <tf.Tensor: shape=(), dtype=int64, numpy=4>, 'feature2': <tf.Tensor: shape=(), dtype=string, numpy=b'goat'>, 'feature3': <tf.Tensor: shape=(), dtype=float32, numpy=0.60950434>}

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

File TFRecord dengan Python

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

Menulis file TFRecord

Selanjutnya, tulis 10.000 pengamatan ke file test.tfrecord . Setiap pengamatan dikonversi menjadi pesan tf.Example , kemudian ditulis ke file. Anda kemudian dapat memverifikasi bahwa file test.tfrecord telah dibuat:

 # Write the `tf.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 diuraikan 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: 1
      }
    }
  }
  feature {
    key: "feature1"
    value {
      int64_list {
        value: 1
      }
    }
  }
  feature {
    key: "feature2"
    value {
      bytes_list {
        value: "dog"
      }
    }
  }
  feature {
    key: "feature3"
    value {
      float_list {
        value: -0.7334449291229248
      }
    }
  }
}


Panduan: Membaca dan menulis data gambar

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

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

Pertama, mari unduh gambar kucing di salju ini dan foto Jembatan Williamsburg, NYC yang 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, menyandikan fitur sebagai tipe yang kompatibel dengan tf.Example . Ini menyimpan fitur string gambar mentah, serta fitur label tinggi, lebar, kedalaman, dan arbitrer. Yang terakhir digunakan ketika 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 dalam pesan tf.Example . Selanjutnya, memfungsikan kode di atas dan menulis contoh pesan ke file bernama images.tfrecords :

 # Write the raw image files to `images.tfrecords`.
# First, process the two images into `tf.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 - images.tfrecords - dan sekarang dapat mengulangi catatan di dalamnya untuk membaca kembali apa yang Anda tulis. Karena dalam contoh ini Anda hanya akan mereproduksi gambar, satu-satunya fitur yang Anda perlukan adalah string gambar mentah. Ekstrak dengan 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 kucing dan yang mana adalah jembatan:

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