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 sering kali 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 tingkat yang lebih tinggi seperti TFX .
Buku catatan ini menunjukkan cara membuat, mengurai, dan menggunakan pesan tf.train.Example
, lalu membuat cerita bersambung, 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 pemetaan {"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 lainnya dapat dipaksa menjadi salah satu dari ini:
tf.train.BytesList
(tipe berikut dapat dipaksakan)-
string
-
byte
-
tf.train.FloatList
(tipe berikut dapat dipaksakan)-
float
(float32
) -
double
(float64
)
-
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 input skalar dan mengembalikan tf.train.Feature
yang berisi salah satu dari tiga jenis list
di 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 bagaimana fungsi-fungsi ini bekerja. Perhatikan berbagai jenis input dan jenis output standar. Jika tipe input untuk suatu fungsi tidak cocok dengan salah satu tipe paksaan yang disebutkan di atas, fungsi tersebut akan memunculkan pengecualian (mis _int64_feature(1.0)
akan error karena 1.0
adalah float—oleh karena itu, fungsi tersebut harus 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 tf.train.Example
pesan
Misalkan Anda ingin membuat pesan tf.train.Example
dari data yang ada. Dalam praktiknya, dataset dapat berasal dari mana saja, tetapi prosedur pembuatan tf.train.Example
pesan dari satu observasi akan sama:
Dalam setiap pengamatan, setiap nilai perlu dikonversi ke
tf.train.Feature
yang berisi salah satu dari 3 tipe yang kompatibel, menggunakan salah satu fungsi di atas.Anda membuat peta (kamus) dari string nama fitur ke nilai fitur yang disandikan yang dihasilkan di #1.
Peta yang dihasilkan pada langkah 2 diubah menjadi pesan
Features
.
Di buku catatan ini, Anda akan membuat kumpulan data menggunakan NumPy.
Dataset ini akan memiliki 4 fitur:
- fitur boolean,
False
atauTrue
dengan probabilitas yang sama - fitur integer yang dipilih secara acak secara seragam 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 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)
Masing-masing fitur ini dapat dipaksa menjadi tipe yang kompatibel dengan tf.train.Example
menggunakan salah satu dari _bytes_feature
, _float_feature
, _int64_feature
. Anda kemudian dapat membuat pesan tf.train.Example
dari fitur yang disandikan 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 pengamatan dari kumpulan data, [False, 4, bytes('goat'), 0.9876]
. Anda dapat membuat dan mencetak pesan tf.train.Example
untuk pengamatan ini menggunakan create_message()
. Setiap pengamatan tunggal akan ditulis sebagai pesan Features
sesuai 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\x14\n\x08feature2\x12\x08\n\x06\n\x04goat\n\x11\n\x08feature1\x12\x05\x1a\x03\n\x01\x04\n\x11\n\x08feature0\x12\x05\x1a\x03\n\x01\x00\n\x14\n\x08feature3\x12\x08\x12\x06\n\x04[\xd3|?'
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 catatan. File hanya dapat dibaca secara berurutan.
Setiap catatan berisi string-byte, untuk muatan data, ditambah panjang data, dan hash CRC-32C ( CRC 32-bit menggunakan polinomial Castagnoli ) untuk pemeriksaan integritas.
Setiap record disimpan dalam format berikut:
uint64 length
uint32 masked_crc32_of_length
byte data[length]
uint32 masked_crc32_of_data
Catatan digabungkan bersama untuk menghasilkan file. CRC dijelaskan di sini , dan topeng CRC adalah:
masked_crc = ((crc >> 15) | (crc << 17)) + 0xa282ead8ul
File TFRecord 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 kumpulan data adalah dengan menggunakan metode from_tensor_slices
.
Diterapkan ke array, ia mengembalikan set data skalar:
tf.data.Dataset.from_tensor_slices(feature1)
<TensorSliceDataset element_spec=TensorSpec(shape=(), dtype=tf.int64, name=None)>
Diterapkan ke tupel array, ia mengembalikan kumpulan data tupel:
features_dataset = tf.data.Dataset.from_tensor_slices((feature0, feature1, feature2, feature3))
features_dataset
<TensorSliceDataset element_spec=(TensorSpec(shape=(), dtype=tf.bool, name=None), TensorSpec(shape=(), dtype=tf.int64, name=None), TensorSpec(shape=(), dtype=tf.string, name=None), TensorSpec(shape=(), dtype=tf.float64, name=None))>
# 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(4, shape=(), dtype=int64) tf.Tensor(b'goat', shape=(), dtype=string) tf.Tensor(0.5251196235602504, 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—fungsi ini harus beroperasi dan mengembalikan tf.Tensors
. Fungsi non-tensor, seperti serialize_example
, dapat dibungkus dengan tf.py_function
agar kompatibel.
Menggunakan tf.py_function
perlu menentukan informasi bentuk dan tipe 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'\nR\n\x14\n\x08feature3\x12\x08\x12\x06\n\x04=n\x06?\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'>
Terapkan fungsi ini ke setiap elemen dalam kumpulan data:
serialized_features_dataset = features_dataset.map(tf_serialize_example)
serialized_features_dataset
<MapDataset element_spec=TensorSpec(shape=(), dtype=tf.string, name=None)>
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 element_spec=TensorSpec(shape=(), dtype=tf.string, name=None)>
Dan tuliskan ke file TFRecord:
filename = 'test.tfrecord'
writer = tf.data.experimental.TFRecordWriter(filename)
writer.write(serialized_features_dataset)
WARNING:tensorflow:From /tmp/ipykernel_25215/3575438268.py:2: TFRecordWriter.__init__ (from tensorflow.python.data.experimental.ops.writers) is deprecated and will be removed in a future version. Instructions for updating: To write TFRecords to disk, use `tf.io.TFRecordWriter`. To save and load the contents of a dataset, use `tf.data.experimental.save` and `tf.data.experimental.load`
Membaca file TFRecord
Anda juga dapat membaca file TFRecord menggunakan kelas tf.data.TFRecordDataset
.
Informasi lebih lanjut tentang penggunaan file TFRecord menggunakan tf.data
dapat ditemukan di tf.data: Panduan pipeline input build TensorFlow .
Menggunakan TFRecordDataset
s dapat berguna untuk menstandardisasi data input dan mengoptimalkan kinerja.
filenames = [filename]
raw_dataset = tf.data.TFRecordDataset(filenames)
raw_dataset
<TFRecordDatasetV2 element_spec=TensorSpec(shape=(), dtype=tf.string, name=None)>
Pada titik ini kumpulan data berisi pesan tf.train.Example
serial. Ketika diulang, ia 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'\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=n\x06?'> <tf.Tensor: shape=(), dtype=string, numpy=b'\nR\n\x11\n\x08feature1\x12\x05\x1a\x03\n\x01\x04\n\x11\n\x08feature0\x12\x05\x1a\x03\n\x01\x01\n\x14\n\x08feature3\x12\x08\x12\x06\n\x04\x9d\xfa\x98\xbe\n\x14\n\x08feature2\x12\x08\n\x06\n\x04goat'> <tf.Tensor: shape=(), dtype=string, numpy=b'\nQ\n\x13\n\x08feature2\x12\x07\n\x05\n\x03dog\n\x11\n\x08feature1\x12\x05\x1a\x03\n\x01\x01\n\x14\n\x08feature3\x12\x08\x12\x06\n\x04a\xc0r?\n\x11\n\x08feature0\x12\x05\x1a\x03\n\x01\x01'> <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\x00\n\x13\n\x08feature2\x12\x07\n\x05\n\x03cat\n\x14\n\x08feature3\x12\x08\x12\x06\n\x04\x92Q(?'> <tf.Tensor: shape=(), dtype=string, numpy=b'\nR\n\x14\n\x08feature2\x12\x08\n\x06\n\x04goat\n\x14\n\x08feature3\x12\x08\x12\x06\n\x04>\xc0\xe5>\n\x11\n\x08feature0\x12\x05\x1a\x03\n\x01\x01\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\x04I!\xde\xbe\n\x11\n\x08feature1\x12\x05\x1a\x03\n\x01\x02\n\x11\n\x08feature0\x12\x05\x1a\x03\n\x01\x00\n\x17\n\x08feature2\x12\x0b\n\t\n\x07chicken'> <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\xe0\x1a\xab\xbf\n\x13\n\x08feature2\x12\x07\n\x05\n\x03cat'> <tf.Tensor: shape=(), dtype=string, numpy=b'\nQ\n\x13\n\x08feature2\x12\x07\n\x05\n\x03cat\n\x11\n\x08feature0\x12\x05\x1a\x03\n\x01\x01\n\x14\n\x08feature3\x12\x08\x12\x06\n\x04\x87\xb2\xd7?\n\x11\n\x08feature1\x12\x05\x1a\x03\n\x01\x00'> <tf.Tensor: shape=(), dtype=string, numpy=b'\nR\n\x11\n\x08feature1\x12\x05\x1a\x03\n\x01\x04\n\x11\n\x08feature0\x12\x05\x1a\x03\n\x01\x01\n\x14\n\x08feature3\x12\x08\x12\x06\n\x04n\xe19>\n\x14\n\x08feature2\x12\x08\n\x06\n\x04goat'> <tf.Tensor: shape=(), dtype=string, numpy=b'\nR\n\x14\n\x08feature3\x12\x08\x12\x06\n\x04\x1as\xd9\xbf\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'>
Tensor ini dapat diuraikan menggunakan fungsi di bawah ini. Perhatikan bahwa feature_description
diperlukan di sini karena tf.data.Dataset
s menggunakan eksekusi grafik, dan memerlukan deskripsi ini untuk membuat bentuk dan jenis tanda tangannya:
# 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 batch sekaligus. Terapkan fungsi ini ke setiap item dalam kumpulan data menggunakan metode tf.data.Dataset.map
:
parsed_dataset = raw_dataset.map(_parse_function)
parsed_dataset
<MapDataset element_spec={'feature0': TensorSpec(shape=(), dtype=tf.int64, name=None), 'feature1': TensorSpec(shape=(), dtype=tf.int64, name=None), 'feature2': TensorSpec(shape=(), dtype=tf.string, name=None), 'feature3': TensorSpec(shape=(), dtype=tf.float32, name=None)}>
Gunakan eksekusi bersemangat untuk menampilkan pengamatan dalam dataset. Ada 10.000 pengamatan dalam kumpulan data ini, tetapi Anda hanya akan menampilkan 10 pengamatan pertama. Data 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=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.5251196>} {'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.29878703>} {'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.94824797>} {'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.65749466>} {'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.44873232>} {'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.4338477>} {'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=-1.3367577>} {'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=1.6851357>} {'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.18152401>} {'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=-1.6988251>}
Di sini, fungsi tf.parse_example
membongkar bidang tf.train.Example
ke dalam tensor standar.
File TFRecord 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
, kemudian 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 serial ini dapat dengan mudah diurai menggunakan tf.train.Example.ParseFromString
:
filenames = [filename]
raw_dataset = tf.data.TFRecordDataset(filenames)
raw_dataset
<TFRecordDatasetV2 element_spec=TensorSpec(shape=(), dtype=tf.string, name=None)>
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: 4 } } } feature { key: "feature2" value { bytes_list { value: "goat" } } } feature { key: "feature3" value { float_list { value: 0.5251196026802063 } } } }
Itu mengembalikan proto tf.train.Example
yang sulit digunakan apa adanya, tetapi pada dasarnya merupakan representasi dari:
Dict[str,
Union[List[float],
List[int],
List[str]]]
Kode berikut secara manual mengonversi Example
ke kamus array NumPy, tanpa menggunakan TensorFlow Ops. Lihat file PROTO untuk detailnya.
result = {}
# example.features.feature is the dictionary
for key, feature in example.features.feature.items():
# The values are the Feature objects which contain a `kind` which contains:
# one of three fields: bytes_list, float_list, int64_list
kind = feature.WhichOneof('kind')
result[key] = np.array(getattr(feature, kind).value)
result
{'feature3': array([0.5251196]), 'feature1': array([4]), 'feature0': array([0]), 'feature2': array([b'goat'], dtype='|S4')}
Panduan: Membaca dan menulis data gambar
Ini adalah contoh ujung ke ujung tentang cara membaca dan menulis data gambar menggunakan TFRecords. Menggunakan gambar sebagai data input, Anda akan menulis data sebagai file TFRecord, kemudian membaca file kembali dan menampilkan gambar.
Ini dapat berguna jika, misalnya, Anda ingin menggunakan beberapa model pada kumpulan data input yang sama. Alih-alih menyimpan data gambar mentah, itu dapat diproses sebelumnya 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 gambar
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 32768/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 24576/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>'))
Tulis file TFRecord
Seperti sebelumnya, enkodekan fitur sebagai tipe yang kompatibel dengan tf.train.Example
. Ini menyimpan fitur string gambar mentah, serta fitur label
tinggi, lebar, kedalaman, dan 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.io.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.train.Example
. Selanjutnya, fungsikan 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 mengulangi catatan di dalamnya untuk membaca kembali apa yang Anda tulis. Mengingat bahwa 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 catatan mana yang kucing dan mana yang 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.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 element_spec={'depth': TensorSpec(shape=(), dtype=tf.int64, name=None), 'height': TensorSpec(shape=(), dtype=tf.int64, name=None), 'image_raw': TensorSpec(shape=(), dtype=tf.string, name=None), 'label': TensorSpec(shape=(), dtype=tf.int64, name=None), 'width': TensorSpec(shape=(), dtype=tf.int64, name=None)}>
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))