امروز برای رویداد محلی TensorFlow خود در همه جا پاسخ دهید!
این صفحه به‌وسیله ‏Cloud Translation API‏ ترجمه شده است.
Switch to English

TFRecord و tf.train. مثال

مشاهده در TensorFlow.org در Google Colab اجرا کنید مشاهده منبع در GitHub دانلود دفترچه یادداشت

قالب TFRecord یک قالب ساده برای ذخیره سازی دنباله ای از سوابق باینری است.

بافرهای پروتکل یک کتابخانه چندزبانی و چندزبانه برای سریال سازی کارآمد داده های ساخت یافته است.

پیام های پروتکل توسط .proto های .proto تعریف می شوند ، اینها اغلب ساده ترین راه برای درک نوع پیام هستند.

پیام tf.train.Example (یا tf.train.Example ) نوعی پیام انعطاف پذیر است که نقشه برداری {"string": value} نشان می دهد. این برنامه برای استفاده با TensorFlow طراحی شده است و در سراسر API های سطح بالاتر مانند TFX استفاده می شود .

این نوت بوک نشان می دهد که چگونه برای ایجاد، تجزیه، و استفاده از tf.train.Example پیام، و سپس مرتب، نوشتن، و خواندن tf.train.Example پیام به و از .tfrecord فایل های.

برپایی

import tensorflow as tf

import numpy as np
import IPython.display as display

tf.train.Example

انواع داده ها برای tf.train.Example عنوان tf.train.Example

اساسا، یک tf.train.Example است {"string": tf.train.Feature} نقشه برداری.

نوع پیام tf.train.Feature می تواند یکی از سه نوع زیر را .proto (برای مراجعه به پرونده .proto مراجعه کنید). اکثر انواع عمومی دیگر را می توان به یکی از اینها وادار کرد:

  1. tf.train.BytesList (انواع زیر را می توان اجبار کرد)

    • string
    • byte
  2. tf.train.FloatList (انواع زیر را می توان اجبار کرد)

    • float ( float32 )
    • double ( float64 )
  3. tf.train.Int64List (انواع زیر را می توان اجباری کرد)

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

به منظور تبدیل یک نوع استاندارد tf.train.Example - سازگار tf.train.Feature ، می توانید از توابع میانبر زیر استفاده کنید. توجه داشته باشید که هر تابع مقدار ورودی اسکالر را می گیرد و یک tf.train.Feature برمی گرداند. tf.train.Feature حاوی یکی از سه نوع list بالا:

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

در زیر چند نمونه از نحوه عملکرد این توابع آورده شده است. به انواع مختلف ورودی و انواع خروجی استاندارد توجه کنید. اگر نوع ورودی برای یک تابع با یکی از انواع اجباری ذکر شده در بالا مطابقت نداشته باشد ، این تابع یک استثنا را ایجاد می کند (به عنوان مثال _int64_feature(1.0) خطا می رود ، زیرا 1.0 شناور است ، بنابراین باید به جای آن با تابع _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
}


همه پیام های اولیه را می توان با استفاده از روش .SerializeToString به یک رشته باینری مرتب کرد:

feature = _float_feature(np.exp(1))

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

ایجاد یک پیام tf.train.Example

فرض کنید می خواهید یک پیام tf.train.Example از داده های موجود ایجاد کنید. در عمل ، مجموعه داده ممکن است از هر کجا باشد ، اما روش ایجاد tf.train.Example پیام مثال از یک مشاهده یکسان خواهد بود:

  1. در هر مشاهده ، هر مقدار باید به tf.train.Feature تبدیل شود. tf.train.Feature حاوی یکی از 3 نوع سازگار ، با استفاده از یکی از توابع بالا.

  2. شما از رشته نام ویژگی تا مقدار ویژگی رمزگذاری شده تولید شده در شماره 1 (فرهنگ لغت) ایجاد می کنید.

  3. نقشه تولید شده در مرحله 2 به پیام Features تبدیل می شود.

در این نوت بوک ، شما یک مجموعه داده را با استفاده از NumPy ایجاد خواهید کرد.

این مجموعه داده دارای 4 ویژگی است:

  • یک ویژگی بولی ، False یا True با احتمال برابر
  • یک ویژگی صحیح به طور یکنواخت از [0, 5]
  • یک ویژگی رشته ای که از جدول رشته با استفاده از ویژگی عدد صحیح به عنوان فهرست ایجاد می شود
  • یک ویژگی شناور از یک توزیع استاندارد استاندارد

یک نمونه متشکل از 10000 مشاهده مستقل و توزیع شده یکسان از هر یک از توزیع های فوق را در نظر بگیرید:

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

هر یک از این ویژگی ها را می توان به یک tf.train.Example به عنوان tf.train.Example نوع سازگار با استفاده از یکی از _bytes_feature های _bytes_feature ، _float_feature ، _int64_feature . سپس می توانید از این ویژگی های رمزگذاری شده یک پیام tf.train.Example ایجاد کنید.

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

به عنوان مثال ، فرض کنید شما یک مشاهده واحد از مجموعه داده دارید ، [False, 4, bytes('goat'), 0.9876] . می توانید tf.train.Example پیام tf.train.Example ایجاد کنید و آن را چاپ کنید با استفاده از create_message() . هر مشاهده منفرد بصورت پیام Features مطابق موارد فوق نوشته خواهد شد. توجه داشته باشید که پیام tf.train.Example فقط یک پیام در اطراف 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'

برای رمزگشایی پیام از روش 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

یک پرونده TFRecord شامل توالی سوابق است. پرونده فقط به صورت متوالی قابل خواندن است.

هر رکورد شامل یک بایت رشته برای بار داده ، به علاوه طول داده و CRC32C (CRC 32 بیتی با استفاده از چند جمله ای Castagnoli) برای بررسی یکپارچگی است.

هر رکورد در قالب های زیر ذخیره می شود:

uint64 length
uint32 masked_crc32_of_length
byte   data[length]
uint32 masked_crc32_of_data

سوابق برای تولید پرونده بهم پیوسته اند. CRC در اینجا توضیح داده شده است و ماسک CRC به شرح زیر است:

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

پرونده های tf.data با استفاده از tf.data

ماژول tf.data همچنین ابزارهایی برای خواندن و نوشتن داده ها در tf.data فراهم می کند.

نوشتن یک فایل TFRecord

ساده ترین راه برای ورود داده ها به یک مجموعه داده استفاده از روش from_tensor_slices است.

با استفاده از یک آرایه ، مجموعه ای از مقیاس پذیرها را برمی گرداند:

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

با استفاده از چند آرایه ، مجموعه ای از tuples را برمی گرداند:

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)

از روش tf.data.Dataset.map برای اعمال یک تابع به هر عنصر از Dataset .

تابع ترسیم شده باید در حالت نمودار tf.Tensors عمل کند - باید tf.Tensors اجرا کند و بازگرداند. یک عملکرد غیر تنسور ، مانند serialize_example ، می تواند با tf.py_function بسته بندی شود تا سازگار شود.

استفاده از tf.py_function نیاز به تعیین شکل و نوع اطلاعاتی دارد که در غیر این صورت در دسترس نیست:

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

این تابع را روی هر عنصر در مجموعه داده اعمال کنید:

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>

و آنها را در یک پرونده TFRecord بنویسید:

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

خواندن یک فایل TFRecord

همچنین می توانید فایل TFRecord را با استفاده از کلاس tf.data.TFRecordDataset .

اطلاعات بیشتر در مورد مصرف پرونده های tf.data با استفاده از tf.data می توانید در اینجا پیدا کنید .

استفاده از TFRecordDataset می تواند برای استاندارد سازی داده های ورودی و بهینه سازی عملکرد مفید باشد.

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

در این مرحله مجموعه داده حاوی پیام های tf.train.Example سریال است. وقتی روی آن تکرار شد ، اینها را به عنوان سنسورهای رشته مقیاس بازمی گرداند.

از روش .take استفاده کنید تا فقط 10 رکورد اول را نشان دهید.

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

با استفاده از عملکرد زیر می توان این سنسورها را تجزیه کرد. توجه داشته باشید که feature_description در اینجا لازم است زیرا مجموعه های داده از نمودار استفاده می شوند و برای ساختن شکل و نوع امضای خود به این توضیحات نیاز دارند:

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

روش دیگر ، استفاده از tf.parse example برای تجزیه یک باره کل دسته. این تابع را با استفاده از روش tf.data.Dataset.map برای هر مورد در مجموعه داده 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}>

برای نمایش مشاهدات در مجموعه داده ، از اعدام مشتاقانه استفاده کنید. 10000 مشاهده در این مجموعه داده وجود دارد ، اما شما فقط 10 مورد اول را نمایش می دهید. داده ها به عنوان فرهنگ نامه ویژگی ها نمایش داده می شوند. هر مورد tf.Tensor و عنصر numpy این تنسور مقدار ویژگی را نمایش می دهد:

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

در اینجا، tf.parse_example تابع حالت زیپ خارج tf.train.Example زمینه به تانسورها استاندارد.

پرونده های TFRecord در پایتون

ماژول tf.io همچنین شامل توابع Python خالص برای خواندن و نوشتن فایلهای TFRecord است.

نوشتن یک فایل TFRecord

بعد ، 10 هزار مشاهده را در پرونده test.tfrecord . هر مشاهده به یک پیام tf.train.Example تبدیل می شود. به عنوان tf.train.Example ، برای نوشتن ارسال می شود. سپس می توانید بررسی کنید که فایل test.tfrecord ایجاد شده است:

# 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

خواندن یک فایل TFRecord

این tf.train.Example.ParseFromString با استفاده از tf.train.Example.ParseFromString به راحتی تجزیه می 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
      }
    }
  }
}


Walkthrough: خواندن و نوشتن داده های تصویر

این یک مثال از انتها به انتهای نحوه خواندن و نوشتن داده های تصویر با استفاده از TFRecords است. با استفاده از یک تصویر به عنوان داده ورودی ، شما داده ها را به عنوان یک فایل TFRecord می نویسید ، سپس پرونده را دوباره می خوانید و تصویر را نمایش می دهید.

این می تواند مفید باشد اگر مثلاً بخواهید از چندین مدل در مجموعه داده ورودی یکسان استفاده کنید. به جای ذخیره داده های تصویر به صورت خام ، می توان آنها را از قبل در قالب TFRecords پردازش کرد و می توان از آن در تمام پردازش ها و مدل سازی های بعدی استفاده کرد.

ابتدا ، اجازه دهید این تصویر از یک گربه در برف و این عکس از پل ویلیامزبورگ ، NYC در حال ساخت را بارگیری کنیم .

تصاویر را واکشی کنید

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

پرونده TFRecord را بنویسید

مانند قبل ، ویژگی ها را به عنوان انواع سازگار با tf.train.Example . به عنوان tf.train.Example . این ویژگی رشته تصویر خام و همچنین ارتفاع ، عرض ، عمق و ویژگی label دلخواه را ذخیره می کند. دومی هنگام نوشتن پرونده برای تمایز بین تصویر گربه و تصویر پل استفاده می شود. برای تصویر گربه از 0 و برای تصویر پل از 1 کنید:

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

توجه داشته باشید که همه ویژگی ها اکنون در پیام tf.train.Example ذخیره شده اند. بعد ، کد بالا را عملیاتی کنید و پیام های مثال را در فایلی به نام 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

فایل TFRecord را بخوانید

اکنون پرونده را در images.tfrecords - images.tfrecords - و اکنون می توانید از سوابق موجود در آن تکرار کنید تا آنچه را که نوشتید بخوانید. با توجه به اینکه در این مثال شما فقط تصویر را بازتولید می کنید ، تنها ویژگی مورد نیاز رشته تصویر خام است. با استفاده از گیرنده هایی که در بالا توضیح داده شده است ، آن را استخراج کنید ، به عنوان example.features.feature['image_raw'].bytes_list.value[0] . همچنین می توانید از برچسب ها برای تعیین اینکه کدام رکورد گربه و کدام یک پل است استفاده کنید:

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

تصاویر را از پرونده TFRecord بازیابی کنید:

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

jpeg

jpeg