Tải tfrecord bên ngoài với TFDS

Nếu bạn có một proto tf.train.Example (bên trong .tfrecord , .riegeli ,...), được tạo bởi các công cụ của bên thứ ba mà bạn muốn tải trực tiếp bằng API tfds, thì trang này là dành cho bạn.

Để tải các tệp .tfrecord của bạn, bạn chỉ cần:

  • Thực hiện theo quy ước đặt tên TFDS.
  • Thêm các tệp siêu dữ liệu ( dataset_info.json , features.json ) cùng với các tệp tfrecord của bạn.

Hạn chế:

Quy ước đặt tên tập tin

TFDS hỗ trợ xác định mẫu cho tên tệp, mang lại sự linh hoạt khi sử dụng các sơ đồ đặt tên tệp khác nhau. Mẫu được biểu thị bằng tfds.core.ShardedFileTemplate và hỗ trợ các biến sau: {DATASET} , {SPLIT} , {FILEFORMAT} , {SHARD_INDEX} , {NUM_SHARDS}{SHARD_X_OF_Y} . Ví dụ: sơ đồ đặt tên tệp mặc định của TFDS là: {DATASET}-{SPLIT}.{FILEFORMAT}-{SHARD_X_OF_Y} . Đối với MNIST, điều này có nghĩa là tên tệp trông như sau:

  • mnist-test.tfrecord-00000-of-00001
  • mnist-train.tfrecord-00000-of-00001

Thêm siêu dữ liệu

Cung cấp cấu trúc tính năng

Để TFDS có thể giải mã nguyên mẫu tf.train.Example , bạn cần cung cấp cấu trúc tfds.features phù hợp với thông số kỹ thuật của bạn. Ví dụ:

features = tfds.features.FeaturesDict({
    'image':
        tfds.features.Image(
            shape=(256, 256, 3),
            doc='Picture taken by smartphone, downscaled.'),
    'label':
        tfds.features.ClassLabel(names=['dog', 'cat']),
    'objects':
        tfds.features.Sequence({
            'camera/K': tfds.features.Tensor(shape=(3,), dtype=tf.float32),
        }),
})

Tương ứng với các thông số kỹ thuật tf.train.Example sau:

{
    'image': tf.io.FixedLenFeature(shape=(), dtype=tf.string),
    'label': tf.io.FixedLenFeature(shape=(), dtype=tf.int64),
    'objects/camera/K': tf.io.FixedLenSequenceFeature(shape=(3,), dtype=tf.int64),
}

Việc chỉ định các tính năng cho phép TFDS tự động giải mã hình ảnh, video,... Giống như bất kỳ bộ dữ liệu TFDS nào khác, siêu dữ liệu tính năng (ví dụ: tên nhãn,...) sẽ được hiển thị cho người dùng (ví dụ info.features['label'].names ).

Nếu bạn kiểm soát đường ống tạo

Nếu bạn tạo các tập dữ liệu bên ngoài TFDS nhưng vẫn kiểm soát quy trình tạo, bạn có thể sử dụng tfds.features.FeatureConnector.serialize_example để mã hóa dữ liệu của mình từ dict[np.ndarray] thành tf.train.Example proto bytes :

with tf.io.TFRecordWriter('path/to/file.tfrecord') as writer:
  for ex in all_exs:
    ex_bytes = features.serialize_example(data)
    writer.write(ex_bytes)

Điều này sẽ đảm bảo khả năng tương thích tính năng với TFDS.

Tương tự, tồn tại một feature.deserialize_example để giải mã proto ( example )

Nếu bạn không kiểm soát đường dẫn thế hệ

Nếu bạn muốn xem cách tfds.features được thể hiện trong tf.train.Example , bạn có thể kiểm tra điều này trong colab:

  • Để dịch tfds.features sang cấu trúc mà con người có thể đọc được của tf.train.Example , bạn có thể gọi features.get_serialized_info() .
  • Để có được thông số chính xác FixedLenFeature ,... được chuyển đến tf.io.parse_single_example , bạn có thể sử dụng spec = features.tf_example_spec

Nhận số liệu thống kê về các lần chia tách

TFDS yêu cầu biết chính xác số lượng mẫu trong mỗi phân đoạn. Điều này là bắt buộc đối với các tính năng như len(ds) hoặc API subplit : split='train[75%:]' .

  • Nếu có thông tin này, bạn có thể tạo danh sách tfds.core.SplitInfo một cách rõ ràng và chuyển sang phần tiếp theo:

    split_infos = [
        tfds.core.SplitInfo(
            name='train',
            shard_lengths=[1024, ...],  # Num of examples in shard0, shard1,...
            num_bytes=0,  # Total size of your dataset (if unknown, set to 0)
        ),
        tfds.core.SplitInfo(name='test', ...),
    ]
    
  • Nếu bạn không biết thông tin này, bạn có thể tính toán nó bằng cách sử dụng tập lệnh compute_split_info.py (hoặc trong tập lệnh của riêng bạn với tfds.folder_dataset.compute_split_info ). Nó sẽ khởi chạy một đường truyền chùm tia sẽ đọc tất cả các phân đoạn trên thư mục nhất định và tính toán thông tin.

Thêm tệp siêu dữ liệu

Để tự động thêm các tệp siêu dữ liệu phù hợp dọc theo tập dữ liệu của bạn, hãy sử dụng tfds.folder_dataset.write_metadata :

tfds.folder_dataset.write_metadata(
    data_dir='/path/to/my/dataset/1.0.0/',
    features=features,
    # Pass the `out_dir` argument of compute_split_info (see section above)
    # You can also explicitly pass a list of `tfds.core.SplitInfo`.
    split_infos='/path/to/my/dataset/1.0.0/',
    # Pass a custom file name template or use None for the default TFDS
    # file name template.
    filename_template='{SPLIT}-{SHARD_X_OF_Y}.{FILEFORMAT}',

    # Optionally, additional DatasetInfo metadata can be provided
    # See:
    # https://www.tensorflow.org/datasets/api_docs/python/tfds/core/DatasetInfo
    description="""Multi-line description."""
    homepage='http://my-project.org',
    supervised_keys=('image', 'label'),
    citation="""BibTex citation.""",
)

Sau khi hàm này được gọi một lần trên thư mục tập dữ liệu của bạn, các tệp siêu dữ liệu ( dataset_info.json ,...) đã được thêm và tập dữ liệu của bạn đã sẵn sàng để tải bằng TFDS (xem phần tiếp theo).

Tải tập dữ liệu bằng TFDS

Trực tiếp từ thư mục

Khi siêu dữ liệu đã được tạo, các bộ dữ liệu có thể được tải bằng cách sử dụng tfds.builder_from_directory để trả về tfds.core.DatasetBuilder với API TFDS tiêu chuẩn (như tfds.builder ):

builder = tfds.builder_from_directory('~/path/to/my_dataset/3.0.0/')

# Metadata are available as usual
builder.info.splits['train'].num_examples

# Construct the tf.data.Dataset pipeline
ds = builder.as_dataset(split='train[75%:]')
for ex in ds:
  ...

Trực tiếp từ nhiều thư mục

Cũng có thể tải dữ liệu từ nhiều thư mục. Ví dụ: điều này có thể xảy ra trong học tăng cường khi nhiều tác nhân tạo ra một tập dữ liệu riêng biệt và bạn muốn tải tất cả chúng lại với nhau. Các trường hợp sử dụng khác là khi một tập dữ liệu mới được tạo thường xuyên, ví dụ: một tập dữ liệu mới mỗi ngày và bạn muốn tải dữ liệu từ một phạm vi ngày.

Để tải dữ liệu từ nhiều thư mục, hãy sử dụng tfds.builder_from_directories , trả về tfds.core.DatasetBuilder với API TFDS tiêu chuẩn (như tfds.builder ):

builder = tfds.builder_from_directories(builder_dirs=[
    '~/path/my_dataset/agent1/1.0.0/',
    '~/path/my_dataset/agent2/1.0.0/',
    '~/path/my_dataset/agent3/1.0.0/',
])

# Metadata are available as usual
builder.info.splits['train'].num_examples

# Construct the tf.data.Dataset pipeline
ds = builder.as_dataset(split='train[75%:]')
for ex in ds:
  ...

Cấu trúc thư mục (tùy chọn)

Để tương thích tốt hơn với TFDS, bạn có thể sắp xếp dữ liệu của mình dưới dạng <data_dir>/<dataset_name>[/<dataset_config>]/<dataset_version> . Ví dụ:

data_dir/
    dataset0/
        1.0.0/
        1.0.1/
    dataset1/
        config0/
            2.0.0/
        config1/
            2.0.0/

Điều này sẽ làm cho tập dữ liệu của bạn tương thích với API tfds.load / tfds.builder , chỉ bằng cách cung cấp data_dir/ :

ds0 = tfds.load('dataset0', data_dir='data_dir/')
ds1 = tfds.load('dataset1/config0', data_dir='data_dir/')