Spec-Zone.ru › TensorFlow

tf.data.Dataset

Представляет потенциально большой набор элементов.

tf.data.Dataset(
    variant_tensor
)

Используется в блокнотах

Используется в руководстве Используется в учебных материалах
  • tf.data: создание входных конвейеров TensorFlow
  • Повышение производительности с помощью API tf.data
  • Типы расширений
  • Переход с Estimator на API Keras
  • Распределенное обучение с TensorFlow
  • Распределенный ввод данных
  • Обучение с сервером параметров и ParameterServerStrategy
  • Загрузка данных CSV
  • Пользовательское обучение с tf.distribute.Strategy
  • pix2pix: преобразование изображений в изображения с условной GAN

API tf.data.Dataset поддерживает создание описательных и эффективных входных конвейеров. Использование Dataset соответствует распространенному шаблону:

  1. Создайте исходный набор данных из входных данных.
  2. Примените преобразования набора данных для предварительной обработки данных.
  3. Выполните итерацию по набору данных и обработайте его элементы.

Итерация выполняется в потоковом режиме, поэтому весь набор данных не обязательно должен помещаться в память.

Исходные наборы данных:

Самый простой способ создать набор данных — создать его из объекта Python list:

dataset = tf.data.Dataset.from_tensor_slices([1, 2, 3])
for element in dataset:
  print(element)
tf.Tensor(1, shape=(), dtype=int32)
tf.Tensor(2, shape=(), dtype=int32)
tf.Tensor(3, shape=(), dtype=int32)

Для обработки строк из файлов используйте tf.data.TextLineDataset:

dataset = tf.data.TextLineDataset(["file1.txt", "file2.txt"])

Для обработки записей, записанных в формате TFRecord, используйте TFRecordDataset:

dataset = tf.data.TFRecordDataset(["file1.tfrecords", "file2.tfrecords"])

Чтобы создать набор данных из всех файлов, соответствующих шаблону, используйте tf.data.Dataset.list_files:

dataset = tf.data.Dataset.list_files("/path/*.txt")

Дополнительные способы создания наборов данных см. в разделах tf.data.FixedLengthRecordDataset и tf.data.Dataset.from_generator.

Преобразования:

Создав набор данных, вы можете применить преобразования для подготовки данных к использованию моделью:

dataset = tf.data.Dataset.from_tensor_slices([1, 2, 3])
dataset = dataset.map(lambda x: x*2)
list(dataset.as_numpy_iterator())
[2, 4, 6]

Общие термины:

Элемент: отдельный результат вызова next() для итератора набора данных. Элементы могут представлять собой вложенные структуры, содержащие несколько компонентов. Например, элемент (1, (3, "apple")) содержит кортеж, вложенный в другой кортеж. Его компоненты: 1, 3 и "apple".

Компонент: конечный элемент вложенной структуры элемента.

Поддерживаемые типы:

Элементы могут быть вложенными структурами из кортежей, именованных кортежей и словарей. Обратите внимание, что списки Python не рассматриваются как вложенные структуры компонентов. Вместо этого списки преобразуются в тензоры и рассматриваются как компоненты. Например, элемент (1, [1, 2, 3]) содержит только два компонента: тензор 1 и тензор [1, 2, 3]. Компоненты элементов могут иметь любой тип, представимый с помощью tf.TypeSpec, включая tf.Tensor, tf.data.Dataset, tf.sparse.SparseTensor, tf.RaggedTensor и tf.TensorArray.

a = 1 # Integer element
b = 2.0 # Float element
c = (1, 2) # Tuple element with 2 components
d = {"a": (2, 2), "b": 3} # Dict element with 3 components
Point = collections.namedtuple("Point", ["x", "y"])
e = Point(1, 2) # Named tuple
f = tf.data.Dataset.range(10) # Dataset element

Дополнительную информацию см. в этом руководстве.

Аргументы
variant_tensor Тензор DT_VARIANT, представляющий набор данных.
Атрибуты
element_spec Спецификация типа элемента этого набора данных.
dataset = tf.data.Dataset.from_tensor_slices([1, 2, 3])
dataset.element_spec
TensorSpec(shape=(), dtype=tf.int32, name=None)

Дополнительную информацию см. в этом руководстве.

Методы

apply

Посмотреть исходный код

apply(
    transformation_func
) -> 'DatasetV2'

Применяет функцию преобразования к этому набору данных.

apply позволяет объединять в цепочку пользовательские преобразования Dataset, представленные функциями, которые принимают один аргумент Dataset и возвращают преобразованный Dataset.

dataset = tf.data.Dataset.range(100)
def dataset_fn(ds):
  return ds.filter(lambda x: x < 5)
dataset = dataset.apply(dataset_fn)
list(dataset.as_numpy_iterator())
[0, 1, 2, 3, 4]
Аргументы
transformation_func Функция, принимающая один аргумент Dataset и возвращающая Dataset.
Возвращает
Новый Dataset с примененным преобразованием, описанным выше.

as_numpy_iterator

Посмотреть исходный код

as_numpy_iterator()

Возвращает итератор, преобразующий все элементы набора данных в массивы numpy.

Используйте as_numpy_iterator для проверки содержимого набора данных. Чтобы просмотреть формы и типы элементов, выводите элементы набора данных напрямую, а не используя as_numpy_iterator.

dataset = tf.data.Dataset.from_tensor_slices([1, 2, 3])
for element in dataset:
  print(element)
tf.Tensor(1, shape=(), dtype=int32)
tf.Tensor(2, shape=(), dtype=int32)
tf.Tensor(3, shape=(), dtype=int32)

Для этого метода необходимо, чтобы выполнение происходило в режиме eager, а element_spec набора данных содержал только компоненты TensorSpec.

dataset = tf.data.Dataset.from_tensor_slices([1, 2, 3])
for element in dataset.as_numpy_iterator():
  print(element)
1
2
3
dataset = tf.data.Dataset.from_tensor_slices([1, 2, 3])
print(list(dataset.as_numpy_iterator()))
[1, 2, 3]

as_numpy_iterator() сохраняет вложенную структуру элементов набора данных.

dataset = tf.data.Dataset.from_tensor_slices({'a': ([1, 2], [3, 4]),
                                              'b': [5, 6]})
list(dataset.as_numpy_iterator()) == [{'a': (1, 3), 'b': 5},
                                      {'a': (2, 4), 'b': 6}]
True
Возвращает
Итерируемый объект, содержащий элементы набора данных, тензоры которых преобразованы в массивы numpy.
Вызывает исключение
TypeError если элемент содержит значение, не являющееся Tensor.
RuntimeError если выполнение eager не включено.

batch

Посмотреть исходный код

batch(
    batch_size,
    drop_remainder=False,
    num_parallel_calls=None,
    deterministic=None,
    name=None
) -> 'DatasetV2'

Объединяет последовательные элементы этого набора данных в пакеты.

dataset = tf.data.Dataset.range(8)
dataset = dataset.batch(3)
list(dataset.as_numpy_iterator())
[array([0, 1, 2]), array([3, 4, 5]), array([6, 7])]
dataset = tf.data.Dataset.range(8)
dataset = dataset.batch(3, drop_remainder=True)
list(dataset.as_numpy_iterator())
[array([0, 1, 2]), array([3, 4, 5])]

Компоненты результирующего элемента будут иметь дополнительное внешнее измерение размером batch_size (или N % batch_size для последнего элемента, если batch_size не делит число входных элементов N нацело и drop_remainder равно False). Если программа предполагает, что внешнее измерение пакетов имеет одинаковый размер, задайте аргумент drop_remainder равным True, чтобы предотвратить создание пакета меньшего размера.

Примечание: Если программе нужны данные со статически известной формой (например, при использовании XLA), следует использовать drop_remainder=True. Без drop_remainder=True форма выходного набора данных будет иметь неизвестное ведущее измерение из-за возможности создания последнего пакета меньшего размера.
Аргументы
batch_size Скалярный tf.int64 tf.Tensor, задающий число последовательных элементов этого набора данных, объединяемых в один пакет.
drop_remainder (Необязательно.) Скалярный tf.bool tf.Tensor, указывающий, следует ли отбрасывать последний пакет, если в нем меньше batch_size элементов; по умолчанию пакет меньшего размера не отбрасывается.
num_parallel_calls (Необязательно.) Скалярный tf.int64 tf.Tensor, задающий число пакетов, вычисляемых асинхронно параллельно. Если значение не указано, пакеты вычисляются последовательно. Если используется значение tf.data.AUTOTUNE, число параллельных вызовов устанавливается динамически на основе доступных ресурсов.
deterministic (Необязательно.) Если задан параметр num_parallel_calls, это логическое значение (True или False) определяет порядок, в котором преобразование создает элементы. Если задано значение False, преобразованию разрешается выдавать элементы не по порядку, чтобы повысить производительность за счет детерминированности. Если значение не указано, поведение определяется параметром tf.data.Options.deterministic (по умолчанию — True).
name (Необязательно.) Имя операции tf.data.
Возвращает
Новый Dataset с примененным преобразованием, описанным выше.

bucket_by_sequence_length

Посмотреть исходный код

bucket_by_sequence_length(
    element_length_func,
    bucket_boundaries,
    bucket_batch_sizes,
    padded_shapes=None,
    padding_values=None,
    pad_to_bucket_boundary=False,
    no_padding=False,
    drop_remainder=False,
    name=None
) -> 'DatasetV2'

Преобразование, распределяющее элементы Dataset по корзинам в зависимости от длины.

Элементы Dataset группируются по длине, после чего к ним применяется дополнение и пакетирование.

Это полезно для задач обработки последовательностей, в которых элементы имеют переменную длину. Группировка элементов схожей длины уменьшает долю дополнения в пакете и повышает эффективность шага обучения.

Ниже приведен пример распределения входных данных по трем корзинам «[0, 3), [3, 5), [5, inf)» на основе длины последовательности с размером пакета 2.

elements = [
  [0], [1, 2, 3, 4], [5, 6, 7],
  [7, 8, 9, 10, 11], [13, 14, 15, 16, 19, 20], [21, 22]]
dataset = tf.data.Dataset.from_generator(
    lambda: elements, tf.int64, output_shapes=[None])
dataset = dataset.bucket_by_sequence_length(
        element_length_func=lambda elem: tf.shape(elem)[0],
        bucket_boundaries=[3, 5],
        bucket_batch_sizes=[2, 2, 2])
for elem in dataset.as_numpy_iterator():
  print(elem)
[[1 2 3 4]
[5 6 7 0]]
[[ 7  8  9 10 11  0]
[13 14 15 16 19 20]]
[[ 0  0]
[21 22]]
Аргументы
element_length_func Функция, преобразующая элемент Dataset в tf.int32; определяет длину элемента, по которой выбирается корзина.
bucket_boundaries list<int> — верхние границы длины корзин.
bucket_batch_sizes list<int> — размер пакета для каждой корзины. Длина должна быть равна len(bucket_boundaries) + 1.
padded_shapes Вложенная структура объектов tf.TensorShape, передаваемая в tf.data.Dataset.padded_batch. Если не задана, используется dataset.output_shapes, в результате чего измерения переменной длины дополняются до максимальной длины в каждом пакете.
padding_values Значения для дополнения, передаваемые в tf.data.Dataset.padded_batch. По умолчанию используется дополнение нулями.
pad_to_bucket_boundary Логическое значение; если False, измерения неизвестного размера дополняются до максимальной длины в пакете. Если True, измерения неизвестного размера дополняются до границы корзины минус 1 (то есть до максимальной длины в каждой корзине), и вызывающий код должен гарантировать, что исходный Dataset не содержит элементов длиной более max(bucket_boundaries).
no_padding bool указывает, нужно ли дополнять признаки пакета (признаки должны иметь тип tf.sparse.SparseTensor или одинаковую форму).
drop_remainder (Необязательно.) Скалярный tf.bool tf.Tensor, указывающий, следует ли отбрасывать последний пакет, если в нем меньше batch_size элементов; по умолчанию пакет меньшего размера не отбрасывается.
name (Необязательно.) Имя операции tf.data.
Возвращает
Новый Dataset с примененным преобразованием, описанным выше.
Вызывает исключение
ValueError если len(bucket_batch_sizes) != len(bucket_boundaries) + 1.

cache

Посмотреть исходный код

cache(
    filename='', name=None
) -> 'DatasetV2'

Кэширует элементы этого набора данных.

При первой итерации по набору данных его элементы кэшируются в указанном файле или в памяти. При последующих итерациях используются кэшированные данные.

Примечание: Чтобы гарантировать завершение формирования кэша, необходимо выполнить итерацию по входному набору данных до конца, пока не будет вызвано исключение StopIteration. В противном случае при последующих итерациях кэшированные данные могут не использоваться.
dataset = tf.data.Dataset.range(5)
dataset = dataset.map(lambda x: x**2)
dataset = dataset.cache()
# The first time reading through the data will generate the data using
# `range` and `map`.
list(dataset.as_numpy_iterator())
[0, 1, 4, 9, 16]
# Subsequent iterations read from the cache.
list(dataset.as_numpy_iterator())
[0, 1, 4, 9, 16]

При кэшировании в файл кэшированные данные сохраняются между запусками. Даже при первой итерации данные будут считываться из файла кэша. Изменение входного конвейера перед вызовом .cache() не даст эффекта, пока файл кэша не будет удален или имя файла не будет изменено.

dataset = tf.data.Dataset.range(5)
dataset = dataset.cache("/path/to/file")
list(dataset.as_numpy_iterator())
# [0, 1, 2, 3, 4]
dataset = tf.data.Dataset.range(10)
dataset = dataset.cache("/path/to/file")  # Same file!
list(dataset.as_numpy_iterator())
# [0, 1, 2, 3, 4]
Примечание: cache будет создавать одни и те же элементы при каждой итерации по набору данных. Если нужно случайным образом менять порядок итерации, вызывайте shuffle после вызова cache.
Аргументы
filename Скалярный tf.string tf.Tensor, задающий имя каталога в файловой системе, используемого для кэширования элементов этого набора данных. Если имя файла не указано, набор данных кэшируется в памяти.
name (Необязательно.) Имя операции tf.data.
Возвращает
Новый Dataset с примененным преобразованием, описанным выше.

cardinality

Посмотреть исходный код

cardinality()

Возвращает мощность набора данных, если она известна.

cardinality может вернуть tf.data.INFINITE_CARDINALITY, если набор данных содержит бесконечное число элементов, или tf.data.UNKNOWN_CARDINALITY, если анализ не смог определить число элементов набора данных (например, когда источником набора данных является файл).

dataset = tf.data.Dataset.range(42)
print(dataset.cardinality().numpy())
42
dataset = dataset.repeat()
cardinality = dataset.cardinality()
print((cardinality == tf.data.INFINITE_CARDINALITY).numpy())
True
dataset = dataset.filter(lambda x: True)
cardinality = dataset.cardinality()
print((cardinality == tf.data.UNKNOWN_CARDINALITY).numpy())
True
Возвращает
Скалярный tf.int64 Tensor, представляющий мощность набора данных. Если мощность бесконечна или неизвестна, cardinality возвращает именованные константы tf.data.INFINITE_CARDINALITY и tf.data.UNKNOWN_CARDINALITY соответственно.

choose_from_datasets

Посмотреть исходный код

@staticmethod
choose_from_datasets(
    datasets, choice_dataset, stop_on_empty_dataset=True
) -> 'DatasetV2'

Создает набор данных, детерминированно выбирающий элементы из datasets.

Например, заданы следующие наборы данных:

datasets = [tf.data.Dataset.from_tensors("foo").repeat(),
            tf.data.Dataset.from_tensors("bar").repeat(),
            tf.data.Dataset.from_tensors("baz").repeat()]

# Define a dataset containing `[0, 1, 2, 0, 1, 2, 0, 1, 2]`.
choice_dataset = tf.data.Dataset.range(3).repeat(3)

result = tf.data.Dataset.choose_from_datasets(datasets, choice_dataset)

Элементы result будут следующими:

"foo", "bar", "baz", "foo", "bar", "baz", "foo", "bar", "baz"
Аргументы
datasets Непустой список объектов tf.data.Dataset с совместимой структурой.
choice_dataset tf.data.Dataset скалярных тензоров типа tf.int64 со значениями от 0 до len(datasets) - 1.
stop_on_empty_dataset Если True, выбор останавливается при обнаружении пустого набора данных. Если False, пустые наборы данных пропускаются. Рекомендуется задать значение True. В противном случае выбранные элементы сначала будут соответствовать ожиданиям пользователя, но могут измениться, когда входные наборы данных опустеют. Это может быть трудно заметить, поскольку вначале набор данных выглядит правильно. По умолчанию используется True.
Возвращает
Новый Dataset с примененным преобразованием, описанным выше.
Вызывает исключение
TypeError Если datasets или choice_dataset имеет неверный тип.
ValueError Если datasets пуст.

concatenate

Посмотреть исходный код

concatenate(
    dataset, name=None
) -> 'DatasetV2'

Создает Dataset, объединяя указанный набор данных с этим набором данных.

a = tf.data.Dataset.range(1, 4)  # ==> [ 1, 2, 3 ]
b = tf.data.Dataset.range(4, 8)  # ==> [ 4, 5, 6, 7 ]
ds = a.concatenate(b)
list(ds.as_numpy_iterator())
[1, 2, 3, 4, 5, 6, 7]
# The input dataset and dataset to be concatenated should have
# compatible element specs.
c = tf.data.Dataset.zip((a, b))
a.concatenate(c)
Traceback (most recent call last):
TypeError: Two datasets to concatenate have different types
<dtype: 'int64'> and (tf.int64, tf.int64)
d = tf.data.Dataset.from_tensor_slices(["a", "b", "c"])
a.concatenate(d)
Traceback (most recent call last):
TypeError: Two datasets to concatenate have different types
<dtype: 'int64'> and <dtype: 'string'>
Аргументы
dataset Dataset для объединения.
name (Необязательно.) Имя операции tf.data.
Возвращает
Новый Dataset с примененным преобразованием, описанным выше.

counter

Посмотреть исходный код

@staticmethod
counter(
    start=0,
    step=1,
    dtype=tf.dtypes.int64,
    name=None
) -> 'DatasetV2'

Создает Dataset, который считает начиная с start с шагом step.

В отличие от tf.data.Dataset.range, который останавливается на заданном конечном числе, tf.data.Dataset.counter создает элементы бесконечно.

dataset = tf.data.experimental.Counter().take(5)
list(dataset.as_numpy_iterator())
[0, 1, 2, 3, 4]
dataset.element_spec
TensorSpec(shape=(), dtype=tf.int64, name=None)
dataset = tf.data.experimental.Counter(dtype=tf.int32)
dataset.element_spec
TensorSpec(shape=(), dtype=tf.int32, name=None)
dataset = tf.data.experimental.Counter(start=2).take(5)
list(dataset.as_numpy_iterator())
[2, 3, 4, 5, 6]
dataset = tf.data.experimental.Counter(start=2, step=5).take(5)
list(dataset.as_numpy_iterator())
[2, 7, 12, 17, 22]
dataset = tf.data.experimental.Counter(start=10, step=-1).take(5)
list(dataset.as_numpy_iterator())
[10, 9, 8, 7, 6]
Аргументы
start (Необязательно.) Начальное значение счетчика. По умолчанию — 0.
step (Необязательно.) Шаг счетчика. По умолчанию — 1.
dtype (Необязательно.) Тип данных элементов счетчика. По умолчанию — tf.int64.
name (Необязательно.) Имя операции tf.data.
Возвращает
Dataset скалярных элементов dtype.

enumerate

Посмотреть исходный код

enumerate(
    start=0, name=None
) -> 'DatasetV2'

Перечисляет элементы этого набора данных.

Это аналог функции enumerate в Python.

dataset = tf.data.Dataset.from_tensor_slices([1, 2, 3])
dataset = dataset.enumerate(start=5)
for element in dataset.as_numpy_iterator():
  print(element)
(5, 1)
(6, 2)
(7, 3)
# The (nested) structure of the input dataset determines the
# structure of elements in the resulting dataset.
dataset = tf.data.Dataset.from_tensor_slices([(7, 8), (9, 10)])
dataset = dataset.enumerate()
for element in dataset.as_numpy_iterator():
  print(element)
(0, array([7, 8], dtype=int32))
(1, array([ 9, 10], dtype=int32))
Аргументы
start Скалярный tf.int64 tf.Tensor, задающий начальное значение для перечисления.
name Необязательно. Имя операций tf.data, используемых функцией enumerate.
Возвращает
Новый Dataset с примененным преобразованием, описанным выше.

filter

Посмотреть исходный код

filter(
    predicate, name=None
) -> 'DatasetV2'

Фильтрует этот набор данных согласно predicate.

dataset = tf.data.Dataset.from_tensor_slices([1, 2, 3])
dataset = dataset.filter(lambda x: x < 3)
list(dataset.as_numpy_iterator())
[1, 2]
# `tf.math.equal(x, y)` is required for equality comparison
def filter_fn(x):
  return tf.math.equal(x, 1)
dataset = dataset.filter(filter_fn)
list(dataset.as_numpy_iterator())
[1]
Аргументы
predicate Функция, преобразующая элемент набора данных в логическое значение.
name (Необязательно.) Имя операции tf.data.
Возвращает
Новый Dataset с примененным преобразованием, описанным выше.

fingerprint

Посмотреть исходный код

fingerprint()

Вычисляет отпечаток этого Dataset.

Если у двух наборов данных одинаковый отпечаток, гарантируется, что они будут создавать идентичные элементы, пока содержимое исходных входных файлов не изменяется и данные создаются детерминированно.

Однако одинаковые значения, создаваемые двумя наборами данных, не всегда означают, что у них будет одинаковый отпечаток, поскольку графы могут иметь разные структуры.

Иными словами, два набора данных с разными отпечатками все равно могут создавать идентичные значения.

Возвращает
Скалярный tf.Tensor типа tf.uint64.

flat_map

Посмотреть исходный код

flat_map(
    map_func, name=None
) -> 'DatasetV2'

Применяет отображение map_func ко всему набору данных и уплощает результат.

Сигнатура типа:

def flat_map(
  self: Dataset[T],
  map_func: Callable[[T], Dataset[S]]
) -> Dataset[S]

Используйте flat_map, если хотите убедиться, что порядок элементов набора данных остается неизменным. Например, чтобы преобразовать набор данных из пакетов в набор данных из их элементов:

dataset = tf.data.Dataset.from_tensor_slices(
    [[1, 2, 3], [4, 5, 6], [7, 8, 9]])
dataset = dataset.flat_map(tf.data.Dataset.from_tensor_slices)
list(dataset.as_numpy_iterator())
[1, 2, 3, 4, 5, 6, 7, 8, 9]

tf.data.Dataset.interleave() — это обобщение flat_map, поскольку flat_map выдает такой же результат, как tf.data.Dataset.interleave(cycle_length=1)

Аргументы
map_func Функция, преобразующая элемент набора данных в набор данных.
name (Необязательно.) Имя операции tf.data.
Возвращает
Новый Dataset с преобразованием, примененным, как описано выше.

from_generator

Просмотреть исходный код

@staticmethod
from_generator(
    generator,
    output_types=None,
    output_shapes=None,
    args=None,
    output_signature=None,
    name=None
) -> 'DatasetV2'

Создает Dataset, элементы которого генерируются с помощью generator. (Устаревшие аргументы)

Устарело: НЕКОТОРЫЕ АРГУМЕНТЫ УСТАРЕЛИ: (output_shapes, output_types). Они будут удалены в будущей версии. Инструкции по обновлению: используйте output_signature
Примечание: В текущей реализации Dataset.from_generator() используется tf.numpy_function, поэтому на нее распространяются те же ограничения. В частности, операции, связанные с набором данных и итератором, необходимо размещать на устройстве в том же процессе, что и программа Python, вызвавшая Dataset.from_generator(). В частности, использование from_generator исключает возможность применения сервиса tf.data для масштабирования обработки наборов данных. Тело generator не будет сериализовано в GraphDef, поэтому не следует использовать этот метод, если необходимо сериализовать модель и восстановить ее в другой среде.

Аргумент generator должен быть вызываемым объектом, возвращающим объект, который поддерживает протокол iter() (например, функцию-генератор).

Элементы, генерируемые с помощью generator, должны быть совместимы либо с заданным аргументом output_signature, либо с заданными аргументами output_types и (необязательно) output_shapes — в зависимости от того, какие из них указаны.

Рекомендуется вызывать from_generator с аргументом output_signature. В этом случае предполагается, что результат состоит из объектов с классами, формами и типами, заданными объектами tf.TypeSpec из аргумента output_signature:

def gen():
  ragged_tensor = tf.ragged.constant([[1, 2], [3]])
  yield 42, ragged_tensor

dataset = tf.data.Dataset.from_generator(
     gen,
     output_signature=(
         tf.TensorSpec(shape=(), dtype=tf.int32),
         tf.RaggedTensorSpec(shape=(2, None), dtype=tf.int32)))

list(dataset.take(1))
[(<tf.Tensor: shape=(), dtype=int32, numpy=42>,
<tf.RaggedTensor [[1, 2], [3]]>)]

Также существует устаревший способ вызова from_generator: с одним аргументом output_types или вместе с аргументом output_shapes. В этом случае предполагается, что результат функции состоит из объектов tf.Tensor с типами, заданными в output_types, и формами, которые либо неизвестны, либо заданы в output_shapes.

Примечание: Если generator зависит от изменяемых глобальных переменных или другого внешнего состояния, имейте в виду, что среда выполнения может вызвать generator несколько раз (например, для поддержки повторения Dataset) и в любой момент между вызовом Dataset.from_generator() и получением первого элемента генератора. Изменение глобальных переменных или внешнего состояния может привести к неопределенному поведению. Рекомендуем явно кэшировать любое внешнее состояние в generator перед вызовом Dataset.from_generator().
Примечание: Хотя параметр output_signature позволяет выдавать элементы Dataset, область применения Dataset.from_generator() следует ограничить логикой, которую нельзя выразить с помощью операций tf.data. Использование операций tf.data внутри функции-генератора является антипаттерном и может привести к постепенному росту потребления памяти.
Аргументы
generator Вызываемый объект, возвращающий объект, который поддерживает протокол iter(). Если args не указан, generator не должен принимать аргументов; в противном случае он должен принимать столько аргументов, сколько значений содержится в args.
output_types (Необязательно.) (Вложенная) структура объектов tf.DType, соответствующих каждому компоненту элемента, выдаваемого generator.
output_shapes (Необязательно.) (Вложенная) структура объектов tf.TensorShape, соответствующих каждому компоненту элемента, выдаваемого generator.
args (Необязательно.) Кортеж объектов tf.Tensor, которые будут вычислены и переданы в generator в качестве аргументов-массивов NumPy.
output_signature (Необязательно.) (Вложенная) структура объектов tf.TypeSpec, соответствующих каждому компоненту элемента, выдаваемого generator.
name (Необязательно.) Имя операций tf.data, используемых from_generator.
Возвращает
Dataset Dataset.

from_tensor_slices

Просмотреть исходный код

@staticmethod
from_tensor_slices(
    tensors, name=None
) -> 'DatasetV2'

Создает Dataset, элементы которого представляют собой срезы заданных тензоров.

Заданные тензоры разделяются вдоль первого измерения. Эта операция сохраняет структуру входных тензоров, удаляя первое измерение каждого тензора и используя его в качестве измерения набора данных. Все входные тензоры должны иметь одинаковый размер по первому измерению.

# Slicing a 1D tensor produces scalar tensor elements.
dataset = tf.data.Dataset.from_tensor_slices([1, 2, 3])
list(dataset.as_numpy_iterator())
[1, 2, 3]
# Slicing a 2D tensor produces 1D tensor elements.
dataset = tf.data.Dataset.from_tensor_slices([[1, 2], [3, 4]])
list(dataset.as_numpy_iterator())
[array([1, 2], dtype=int32), array([3, 4], dtype=int32)]
# Slicing a tuple of 1D tensors produces tuple elements containing
# scalar tensors.
dataset = tf.data.Dataset.from_tensor_slices(([1, 2], [3, 4], [5, 6]))
list(dataset.as_numpy_iterator())
[(1, 3, 5), (2, 4, 6)]
# Dictionary structure is also preserved.
dataset = tf.data.Dataset.from_tensor_slices({"a": [1, 2], "b": [3, 4]})
list(dataset.as_numpy_iterator()) == [{'a': 1, 'b': 3},
                                      {'a': 2, 'b': 4}]
True
# Two tensors can be combined into one Dataset object.
features = tf.constant([[1, 3], [2, 1], [3, 3]]) # ==> 3x2 tensor
labels = tf.constant(['A', 'B', 'A']) # ==> 3x1 tensor
dataset = Dataset.from_tensor_slices((features, labels))
# Both the features and the labels tensors can be converted
# to a Dataset object separately and combined after.
features_dataset = Dataset.from_tensor_slices(features)
labels_dataset = Dataset.from_tensor_slices(labels)
dataset = Dataset.zip((features_dataset, labels_dataset))
# A batched feature and label set can be converted to a Dataset
# in similar fashion.
batched_features = tf.constant([[[1, 3], [2, 3]],
                                [[2, 1], [1, 2]],
                                [[3, 3], [3, 2]]], shape=(3, 2, 2))
batched_labels = tf.constant([['A', 'A'],
                              ['B', 'B'],
                              ['A', 'B']], shape=(3, 2, 1))
dataset = Dataset.from_tensor_slices((batched_features, batched_labels))
for element in dataset.as_numpy_iterator():
  print(element)
(array([[1, 3],
       [2, 3]], dtype=int32), array([[b'A'],
       [b'A']], dtype=object))
(array([[2, 1],
       [1, 2]], dtype=int32), array([[b'B'],
       [b'B']], dtype=object))
(array([[3, 3],
       [3, 2]], dtype=int32), array([[b'A'],
       [b'B']], dtype=object))

Обратите внимание: если tensors содержит массив NumPy, а немедленное выполнение не включено, значения будут встроены в граф в виде одной или нескольких операций tf.constant. Для больших наборов данных (> 1 ГБ) это может привести к нерациональному расходу памяти и превышению ограничений на размер сериализуемого графа. Если tensors содержит один или несколько больших массивов NumPy, рассмотрите альтернативный способ, описанный в этом руководстве.

Аргументы
tensors Элемент набора данных, компоненты которого имеют одинаковое первое измерение. Поддерживаемые значения описаны здесь.
name (Необязательно.) Имя операции tf.data.
Возвращает
Dataset Dataset.

from_tensors

Просмотреть исходный код

@staticmethod
from_tensors(
    tensors, name=None
) -> 'DatasetV2'

Создает Dataset с одним элементом, состоящим из заданных тензоров.

from_tensors создает набор данных, содержащий только один элемент. Чтобы разделить входной тензор на несколько элементов, используйте вместо этого from_tensor_slices.

dataset = tf.data.Dataset.from_tensors([1, 2, 3])
list(dataset.as_numpy_iterator())
[array([1, 2, 3], dtype=int32)]
dataset = tf.data.Dataset.from_tensors(([1, 2, 3], 'A'))
list(dataset.as_numpy_iterator())
[(array([1, 2, 3], dtype=int32), b'A')]
# You can use `from_tensors` to produce a dataset which repeats
# the same example many times.
example = tf.constant([1,2,3])
dataset = tf.data.Dataset.from_tensors(example).repeat(2)
list(dataset.as_numpy_iterator())
[array([1, 2, 3], dtype=int32), array([1, 2, 3], dtype=int32)]

Обратите внимание: если tensors содержит массив NumPy, а немедленное выполнение не включено, значения будут встроены в граф в виде одной или нескольких операций tf.constant. Для больших наборов данных (> 1 ГБ) это может привести к нерациональному расходу памяти и превышению ограничений на размер сериализуемого графа. Если tensors содержит один или несколько больших массивов NumPy, рассмотрите альтернативный способ, описанный в этом руководстве.

Аргументы
tensors «Элемент» набора данных. Поддерживаемые значения описаны здесь.
name (Необязательно.) Имя операции tf.data.
Возвращает
Dataset Dataset.

get_single_element

Просмотреть исходный код

get_single_element(
    name=None
)

Возвращает единственный элемент dataset.

Эта функция позволяет использовать tf.data.Dataset в stateless-выражении «тензор на входе — тензор на выходе» без создания итератора. Это упрощает преобразование данных в тензорах с помощью оптимизированной абстракции tf.data.Dataset.

Для примера рассмотрим preprocessing_fn, которая принимает необработанные признаки и возвращает обработанный признак вместе с его меткой.

def preprocessing_fn(raw_feature):
  # ... the raw_feature is preprocessed as per the use-case
  return feature

raw_features = ...  # input batch of BATCH_SIZE elements.
dataset = (tf.data.Dataset.from_tensor_slices(raw_features)
          .map(preprocessing_fn, num_parallel_calls=BATCH_SIZE)
          .batch(BATCH_SIZE))

processed_features = dataset.get_single_element()

В приведенном выше примере тензор raw_features длины BATCH_SIZE был преобразован в tf.data.Dataset. Затем каждый элемент raw_feature был обработан с помощью preprocessing_fn, а обработанные признаки были объединены в один пакет. Итоговый dataset содержит только один элемент — пакет со всеми обработанными признаками.

Примечание: dataset должен содержать только один элемент.

Теперь вместо создания итератора для dataset и получения пакета признаков используется функция tf.data.get_single_element(), которая позволяет пропустить создание итератора и напрямую получить пакет признаков.

Это особенно полезно, если преобразования тензоров представлены операциями tf.data.Dataset и вы хотите использовать эти преобразования при обслуживании модели.

Keras

model = ... # A pre-built or custom model

class PreprocessingModel(tf.keras.Model):
  def __init__(self, model):
    super().__init__(self)
    self.model = model

  @tf.function(input_signature=[...])
  def serving_fn(self, data):
    ds = tf.data.Dataset.from_tensor_slices(data)
    ds = ds.map(preprocessing_fn, num_parallel_calls=BATCH_SIZE)
    ds = ds.batch(batch_size=BATCH_SIZE)
    return tf.argmax(self.model(ds.get_single_element()), axis=-1)

preprocessing_model = PreprocessingModel(model)
your_exported_model_dir = ... # save the model to this path.
tf.saved_model.save(preprocessing_model, your_exported_model_dir,
              signatures={'serving_default': preprocessing_model.serving_fn}
              )
Аргументы
name (Необязательно.) Имя операции tf.data.
Возвращает
Вложенную структуру объектов tf.Tensor, соответствующую единственному элементу dataset.
Вызывает исключение
InvalidArgumentError (во время выполнения), если dataset содержит не ровно один элемент.

group_by_window

Просмотреть исходный код

group_by_window(
    key_func, reduce_func, window_size=None, window_size_func=None, name=None
) -> 'DatasetV2'

Группирует окна элементов по ключу и сокращает их.

Это преобразование сопоставляет каждому следующему элементу набора данных ключ с помощью key_func и группирует элементы по ключу. Затем оно применяет reduce_func не более чем к window_size_func(key) элементам с одним и тем же ключом. Все окна, кроме последнего для каждого ключа, содержат window_size_func(key) элементов; последнее окно может быть меньше.

Можно указать постоянный window_size или размер окна, определяемый ключом с помощью window_size_func.

dataset = tf.data.Dataset.range(10)
window_size = 5
key_func = lambda x: x%2
reduce_func = lambda key, dataset: dataset.batch(window_size)
dataset = dataset.group_by_window(
          key_func=key_func,
          reduce_func=reduce_func,
          window_size=window_size)
for elem in dataset.as_numpy_iterator():
  print(elem)
[0 2 4 6 8]
[1 3 5 7 9]
Аргументы
key_func Функция, преобразующая вложенную структуру тензоров (с формами и типами, заданными в self.output_shapes и self.output_types) в скалярный тензор tf.int64.
reduce_func Функция, преобразующая ключ и набор данных, содержащий до window_size следующих подряд элементов с этим ключом, в другой набор данных.
window_size Скалярный тензор tf.Tensor типа tf.int64, задающий число следующих подряд элементов с одним и тем же ключом, объединяемых в один пакет и передаваемых в reduce_func. Не может использоваться одновременно с window_size_func.
window_size_func Функция, преобразующая ключ в скалярный тензор tf.Tensor типа tf.int64, задающий число следующих подряд элементов с одним и тем же ключом, объединяемых в один пакет и передаваемых в reduce_func. Не может использоваться одновременно с window_size.
name (Необязательно.) Имя операции tf.data.
Возвращает
Новый Dataset с преобразованием, примененным, как описано выше.
Вызывает исключение
ValueError если не передан ни один из аргументов {window_size, window_size_func} или переданы оба.

ignore_errors

Просмотреть исходный код

ignore_errors(
    log_warning=False, name=None
) -> 'DatasetV2'

Отбрасывает элементы, вызывающие ошибки.

dataset = tf.data.Dataset.from_tensor_slices([1., 2., 0., 4.])
dataset = dataset.map(lambda x: tf.debugging.check_numerics(1. / x, ""))
list(dataset.as_numpy_iterator())
Traceback (most recent call last):

InvalidArgumentError: ... Tensor had Inf values
dataset = dataset.ignore_errors()
list(dataset.as_numpy_iterator())
[1.0, 0.5, 0.25]
Аргументы
log_warning (Необязательно.) Логическое значение, указывающее, следует ли записывать сведения об игнорируемых ошибках в stderr. По умолчанию — False.
name (Необязательно.) Строка с именем операции tf.data.
Возвращает
Новый Dataset с преобразованием, примененным, как описано выше.

interleave

Просмотреть исходный код

interleave(
    map_func,
    cycle_length=None,
    block_length=None,
    num_parallel_calls=None,
    deterministic=None,
    name=None
) -> 'DatasetV2'

Применяет map_func к этому набору данных и чередует полученные результаты.

Сигнатура типа:

def interleave(
  self: Dataset[T],
  map_func: Callable[[T], Dataset[S]]
) -> Dataset[S]

Например, Dataset.interleave() можно использовать для параллельной обработки множества входных файлов:

# Preprocess 4 files concurrently, and interleave blocks of 16 records
# from each file.
filenames = ["/var/data/file1.txt", "/var/data/file2.txt",
             "/var/data/file3.txt", "/var/data/file4.txt"]
dataset = tf.data.Dataset.from_tensor_slices(filenames)
def parse_fn(filename):
  return tf.data.Dataset.range(10)
dataset = dataset.interleave(lambda x:
    tf.data.TextLineDataset(x).map(parse_fn, num_parallel_calls=1),
    cycle_length=4, block_length=16)

Аргументы cycle_length и block_length определяют порядок выдачи элементов. cycle_length определяет число входных элементов, обрабатываемых одновременно. Если задать для cycle_length значение 1, это преобразование будет обрабатывать по одному входному элементу за раз и выдавать результаты, идентичные tf.data.Dataset.flat_map. Как правило, это преобразование применяет map_func к cycle_length входным элементам, открывает итераторы для возвращенных объектов Dataset, затем поочередно извлекает из каждого итератора block_length следующих подряд элементов и каждый раз, когда итератор достигает конца, получает следующий входной элемент.

Например:

dataset = Dataset.range(1, 6)  # ==> [ 1, 2, 3, 4, 5 ]
# NOTE: New lines indicate "block" boundaries.
dataset = dataset.interleave(
    lambda x: Dataset.from_tensors(x).repeat(6),
    cycle_length=2, block_length=4)
list(dataset.as_numpy_iterator())
[1, 1, 1, 1,
 2, 2, 2, 2,
 1, 1,
 2, 2,
 3, 3, 3, 3,
 4, 4, 4, 4,
 3, 3,
 4, 4,
 5, 5, 5, 5,
 5, 5]
Примечание: Порядок элементов, выдаваемых этим преобразованием, является детерминированным, если map_func — чистая функция и deterministic=True. Если map_func содержит операции с состоянием, порядок доступа к этому состоянию не определен.

Производительность часто можно повысить, задав num_parallel_calls, чтобы interleave использовал несколько потоков для получения элементов. Если детерминированность не требуется, производительность также можно повысить, задав deterministic=False.

filenames = ["/var/data/file1.txt", "/var/data/file2.txt",
             "/var/data/file3.txt", "/var/data/file4.txt"]
dataset = tf.data.Dataset.from_tensor_slices(filenames)
dataset = dataset.interleave(lambda x: tf.data.TFRecordDataset(x),
    cycle_length=4, num_parallel_calls=tf.data.AUTOTUNE,
    deterministic=False)
Аргументы
map_func Функция, принимающая элемент набора данных и возвращающая tf.data.Dataset.
cycle_length (Необязательно.) Число входных элементов, обрабатываемых одновременно. Если значение не задано, среда выполнения tf.data определяет его на основе доступных ресурсов ЦП. Если для num_parallel_calls задано значение tf.data.AUTOTUNE, аргумент cycle_length задает максимальную степень параллелизма.
block_length (Необязательно.) Число следующих подряд элементов, выдаваемых для каждого входного элемента до переключения на другой входной элемент. По умолчанию — 1.
num_parallel_calls (Необязательно.) Если задано это значение, реализация создает пул потоков, используемый для асинхронного и параллельного получения входных данных из элементов цикла. По умолчанию входные данные из элементов цикла извлекаются синхронно, без параллелизма. Если используется значение tf.data.AUTOTUNE, число параллельных вызовов динамически определяется на основе доступных ресурсов ЦП.
deterministic (Необязательно.) Если задан параметр num_parallel_calls и указано это логическое значение (True или False), оно определяет порядок выдачи элементов преобразованием. Если задано значение False, преобразование может выдавать элементы не по порядку, жертвуя детерминированностью ради производительности. Если значение не задано, поведение определяется параметром tf.data.Options.deterministic (по умолчанию — True).
name (Необязательно.) Имя операции tf.data.
Возвращает
Новый Dataset с преобразованием, примененным, как описано выше.

list_files

Просмотреть исходный код

@staticmethod
list_files(
    file_pattern, shuffle=None, seed=None, name=None
) -> 'DatasetV2'

Набор данных, содержащий все файлы, соответствующие одному или нескольким шаблонам glob.

Аргумент file_pattern должен содержать небольшое число шаблонов glob. Если имена файлов уже обработаны с помощью glob, используйте вместо этого Dataset.from_tensor_slices(filenames), поскольку повторная обработка каждого имени файла с помощью list_files может снизить производительность при работе с удаленными системами хранения.

Примечание: По умолчанию этот метод возвращает имена файлов в недетерминированном случайном порядке. Передайте seed или shuffle=False, чтобы получить результаты в детерминированном порядке.
Пример
Предположим, в нашей файловой системе есть следующие файлы:
  • /path/to/dir/a.txt
  • /path/to/dir/b.py
  • /path/to/dir/c.py

Если передать "/path/to/dir/*.py" в качестве каталога, набор данных будет содержать:

  • /path/to/dir/b.py
  • /path/to/dir/c.py
Аргументы
file_pattern Строка, список строк или tf.Tensor строкового типа (скаляр или вектор), представляющие шаблон(ы) glob для имен файлов (то есть шаблон(ы) подстановки оболочки), которым должны соответствовать имена.
shuffle (Необязательно.) Если True, имена файлов будут перемешаны в случайном порядке. По умолчанию — True.
seed (Необязательно.) Скалярный тензор tf.Tensor типа tf.int64, представляющий начальное значение для генератора случайных чисел, используемого при создании распределения. Описание поведения см. в разделе tf.random.set_seed.
name Необязательно. Имя операций tf.data, используемых list_files.
Возвращает
Dataset Dataset строк, соответствующий именам файлов.

load

Просмотреть исходный код

@staticmethod
load(
    path, element_spec=None, compression=None, reader_func=None
) -> 'DatasetV2'

Загружает ранее сохраненный набор данных.

Пример использования:

import tempfile
path = os.path.join(tempfile.gettempdir(), "saved_data")
# Save a dataset
dataset = tf.data.Dataset.range(2)
tf.data.Dataset.save(dataset, path)
new_dataset = tf.data.Dataset.load(path)
for elem in new_dataset:
  print(elem)
tf.Tensor(0, shape=(), dtype=int64)
tf.Tensor(1, shape=(), dtype=int64)

Если при сохранении набора данных использовался параметр сегментирования по умолчанию, при загрузке порядок элементов сохраненного набора данных будет сохранен.

Аргумент reader_func позволяет указать пользовательский порядок загрузки элементов из отдельных сегментов. Ожидается, что reader_func принимает один аргумент — набор данных из наборов данных, каждый из которых содержит элементы одного из сегментов, — и возвращает набор данных из элементов. Например, при загрузке сегменты можно перемешать следующим образом:

def custom_reader_func(datasets):
  datasets = datasets.shuffle(NUM_SHARDS)
  return datasets.interleave(lambda x: x, num_parallel_calls=AUTOTUNE)

dataset = tf.data.Dataset.load(
    path="/path/to/data", ..., reader_func=custom_reader_func)
Аргументы
path Обязательный аргумент. Путь к ранее сохраненному набору данных.
element_spec Необязательно. Вложенная структура объектов tf.TypeSpec, соответствующая структуре элемента сохраненного набора данных и задающая тип отдельных компонентов элемента. Если не указана, используется вложенная структура tf.TypeSpec, сохраненная вместе с набором данных. Обратите внимание, что в режиме графа этот аргумент является обязательным.
compression Необязательно. Алгоритм распаковки данных при чтении. Поддерживаются варианты GZIP и NONE. По умолчанию — NONE.
reader_func Необязательно. Функция, управляющая чтением данных из сегментов. Если она указана, функция будет преобразована в граф и выполнена как вычисление графа.
Возвращает
Экземпляр tf.data.Dataset.
Вызывает исключение
FileNotFoundError Если параметр element_spec не указан и сохраненную вложенную структуру tf.TypeSpec невозможно найти вместе с сохраненным набором данных.
ValueError Если параметр element_spec не указан, а метод выполняется в режиме графа.

map

Просмотреть исходный код

map(
    map_func, num_parallel_calls=None, deterministic=None, name=None
)

Применяет map_func к элементам этого набора данных.

Это преобразование применяет map_func к каждому элементу данного набора данных и возвращает новый набор данных с преобразованными элементами в том же порядке, в котором они следовали во входных данных. map_func можно использовать для изменения как значений, так и структуры элементов набора данных. Поддерживаемые конструкции структуры описаны здесь.

Например, map можно использовать, чтобы прибавить 1 к каждому элементу или выбрать подмножество компонентов элемента.

dataset = Dataset.range(1, 6)  # ==> [ 1, 2, 3, 4, 5 ]
dataset = dataset.map(lambda x: x + 1)
list(dataset.as_numpy_iterator())
[2, 3, 4, 5, 6]

Входная сигнатура map_func определяется структурой каждого элемента этого набора данных.

dataset = Dataset.range(5)
# `map_func` takes a single argument of type `tf.Tensor` with the same
# shape and dtype.
result = dataset.map(lambda x: x + 1)
# Each element is a tuple containing two `tf.Tensor` objects.
elements = [(1, "foo"), (2, "bar"), (3, "baz")]
dataset = tf.data.Dataset.from_generator(
    lambda: elements, (tf.int32, tf.string))
# `map_func` takes two arguments of type `tf.Tensor`. This function
# projects out just the first component.
result = dataset.map(lambda x_int, y_str: x_int)
list(result.as_numpy_iterator())
[1, 2, 3]
# Each element is a dictionary mapping strings to `tf.Tensor` objects.
elements =  ([{"a": 1, "b": "foo"},
              {"a": 2, "b": "bar"},
              {"a": 3, "b": "baz"}])
dataset = tf.data.Dataset.from_generator(
    lambda: elements, {"a": tf.int32, "b": tf.string})
# `map_func` takes a single argument of type `dict` with the same keys
# as the elements.
result = dataset.map(lambda d: str(d["a"]) + d["b"])

Значение или значения, возвращаемые map_func, определяют структуру каждого элемента возвращаемого набора данных.

dataset = tf.data.Dataset.range(3)
# `map_func` returns two `tf.Tensor` objects.
def g(x):
  return tf.constant(37.0), tf.constant(["Foo", "Bar", "Baz"])
result = dataset.map(g)
result.element_spec
(TensorSpec(shape=(), dtype=tf.float32, name=None), TensorSpec(shape=(3,), dtype=tf.string, name=None))
# Python primitives, lists, and NumPy arrays are implicitly converted to
# `tf.Tensor`.
def h(x):
  return 37.0, ["Foo", "Bar"], np.array([1.0, 2.0], dtype=np.float64)
result = dataset.map(h)
result.element_spec
(TensorSpec(shape=(), dtype=tf.float32, name=None), TensorSpec(shape=(2,), dtype=tf.string, name=None), TensorSpec(shape=(2,), dtype=tf.float64, name=None))
# `map_func` can return nested structures.
def i(x):
  return (37.0, [42, 16]), "foo"
result = dataset.map(i)
result.element_spec
((TensorSpec(shape=(), dtype=tf.float32, name=None),
  TensorSpec(shape=(2,), dtype=tf.int32, name=None)),
 TensorSpec(shape=(), dtype=tf.string, name=None))

map_func может принимать в качестве аргументов и возвращать данные любого типа, используемого в элементах набора данных.

Обратите внимание: независимо от контекста, в котором определена map_func (немедленное выполнение или режим графа), tf.data преобразует функцию в граф и выполняет ее как граф. Чтобы использовать код Python внутри функции, можно выбрать один из следующих вариантов:

1) Полагаться на AutoGraph, преобразующий код Python в эквивалентное вычисление графа. Недостаток этого подхода заключается в том, что AutoGraph может преобразовать не весь код Python.

2) Использовать tf.py_function, позволяющую писать произвольный код Python, но обычно обеспечивающую худшую производительность, чем вариант 1). Например:

d = tf.data.Dataset.from_tensor_slices(['hello', 'world'])
# transform a string tensor to upper case string using a Python function
def upper_case_fn(t: tf.Tensor):
  return t.numpy().decode('utf-8').upper()
d = d.map(lambda x: tf.py_function(func=upper_case_fn,
          inp=[x], Tout=tf.string))
list(d.as_numpy_iterator())
[b'HELLO', b'WORLD']

3) Использовать tf.numpy_function, которая также позволяет писать произвольный код Python. Обратите внимание: tf.py_function принимает объекты tf.Tensor, а tf.numpy_function принимает массивы NumPy и возвращает только массивы NumPy. Например:

d = tf.data.Dataset.from_tensor_slices(['hello', 'world'])
def upper_case_fn(t: np.ndarray):
  return t.decode('utf-8').upper()
d = d.map(lambda x: tf.numpy_function(func=upper_case_fn,
          inp=[x], Tout=tf.string))
list(d.as_numpy_iterator())
[b'HELLO', b'WORLD']

Обратите внимание: использование tf.numpy_function и tf.py_function обычно исключает возможность параллельного выполнения пользовательских преобразований (из-за GIL Python).

Производительность часто можно повысить, задав num_parallel_calls, чтобы map использовал несколько потоков для обработки элементов. Если детерминированный порядок не требуется, производительность также можно повысить, задав deterministic=False.

dataset = Dataset.range(1, 6)  # ==> [ 1, 2, 3, 4, 5 ]
dataset = dataset.map(lambda x: x + 1,
    num_parallel_calls=tf.data.AUTOTUNE,
    deterministic=False)

Порядок элементов, выдаваемых этим преобразованием, детерминирован, если deterministic=True. Если map_func содержит операции с состоянием и num_parallel_calls > 1, порядок доступа к этому состоянию не определен, поэтому значения выходных элементов могут быть недетерминированными независимо от значения флага deterministic.

Аргументы
map_func Функция, сопоставляющая элемент набора данных другому элементу набора данных.
num_parallel_calls (Необязательно.) Скалярный tf.int64 tf.Tensor, представляющий количество элементов, обрабатываемых асинхронно параллельно. Если значение не указано, элементы обрабатываются последовательно. Если используется значение tf.data.AUTOTUNE, количество параллельных вызовов динамически задается на основе доступных ресурсов ЦП.
deterministic (Необязательно.) Если указано num_parallel_calls и задан этот логический параметр (True или False), он определяет порядок выдачи элементов преобразованием. Если задано значение False, преобразованию разрешено выдавать элементы не по порядку, чтобы повысить производительность за счет детерминированности. Если параметр не указан, поведение определяется параметром tf.data.Options.deterministic (по умолчанию — True).
name (Необязательно.) Имя операции tf.data.
Возвращает
Новый Dataset с примененным описанным выше преобразованием.

options

Посмотреть исходный код

options()

Возвращает параметры этого набора данных и его входных данных.

Возвращает
Объект tf.data.Options, представляющий параметры набора данных.

padded_batch

Посмотреть исходный код

padded_batch(
    batch_size,
    padded_shapes=None,
    padding_values=None,
    drop_remainder=False,
    name=None
) -> 'DatasetV2'

Объединяет последовательные элементы этого набора данных в дополненные пакеты.

Это преобразование объединяет несколько последовательных элементов входного набора данных в один элемент.

Как и в случае с tf.data.Dataset.batch, компоненты результирующего элемента получат дополнительное внешнее измерение, размер которого будет равен batch_size (или N % batch_size для последнего элемента, если batch_size не делит количество входных элементов N без остатка и drop_remainder имеет значение False). Если работа вашей программы зависит от одинакового размера внешнего измерения у всех пакетов, задайте для аргумента drop_remainder значение True, чтобы предотвратить создание меньшего пакета.

В отличие от tf.data.Dataset.batch, входные элементы, объединяемые в пакеты, могут иметь разные формы, и это преобразование дополнит каждый компонент до соответствующей формы в padded_shapes. Аргумент padded_shapes определяет результирующую форму каждого измерения каждого компонента выходного элемента:

  • Если размер измерения задан константой, компонент будет дополнен до этой длины в данном измерении.
  • Если размер измерения не задан, компонент будет дополнен до максимальной длины всех элементов в этом измерении.
A = (tf.data.Dataset
     .range(1, 5, output_type=tf.int32)
     .map(lambda x: tf.fill([x], x)))
# Pad to the smallest per-batch size that fits all elements.
B = A.padded_batch(2)
for element in B.as_numpy_iterator():
  print(element)
[[1 0]
 [2 2]]
[[3 3 3 0]
 [4 4 4 4]]
# Pad to a fixed size.
C = A.padded_batch(2, padded_shapes=5)
for element in C.as_numpy_iterator():
  print(element)
[[1 0 0 0 0]
 [2 2 0 0 0]]
[[3 3 3 0 0]
 [4 4 4 4 0]]
# Pad with a custom value.
D = A.padded_batch(2, padded_shapes=5, padding_values=-1)
for element in D.as_numpy_iterator():
  print(element)
[[ 1 -1 -1 -1 -1]
 [ 2  2 -1 -1 -1]]
[[ 3  3  3 -1 -1]
 [ 4  4  4  4 -1]]
# Components of nested elements can be padded independently.
elements = [([1, 2, 3], [10]),
            ([4, 5], [11, 12])]
dataset = tf.data.Dataset.from_generator(
    lambda: iter(elements), (tf.int32, tf.int32))
# Pad the first component of the tuple to length 4, and the second
# component to the smallest size that fits.
dataset = dataset.padded_batch(2,
    padded_shapes=([4], [None]),
    padding_values=(-1, 100))
list(dataset.as_numpy_iterator())
[(array([[ 1,  2,  3, -1], [ 4,  5, -1, -1]], dtype=int32),
  array([[ 10, 100], [ 11,  12]], dtype=int32))]
# Pad with a single value and multiple components.
E = tf.data.Dataset.zip((A, A)).padded_batch(2, padding_values=-1)
for element in E.as_numpy_iterator():
  print(element)
(array([[ 1, -1],
       [ 2,  2]], dtype=int32), array([[ 1, -1],
       [ 2,  2]], dtype=int32))
(array([[ 3,  3,  3, -1],
       [ 4,  4,  4,  4]], dtype=int32), array([[ 3,  3,  3, -1],
       [ 4,  4,  4,  4]], dtype=int32))

См. также tf.data.experimental.dense_to_sparse_batch, которое объединяет элементы с разными формами в tf.sparse.SparseTensor.

Аргументы
batch_size Скалярный tf.int64 tf.Tensor, представляющий количество последовательных элементов этого набора данных, объединяемых в один пакет.
padded_shapes (Необязательно.) (Вложенная) структура из tf.TensorShape или объектов, подобных векторным тензорам tf.int64, представляющая форму, до которой следует дополнить соответствующий компонент каждого входного элемента перед пакетированием. Все измерения с неизвестным размером будут дополнены до максимального размера этого измерения в каждом пакете. Если параметр не задан, все измерения всех компонентов дополняются до максимального размера в пакете. Параметр padded_shapes необходимо задать, если какой-либо компонент имеет неизвестный ранг.
padding_values (Необязательно.) (Вложенная) структура из tf.Tensor скалярной формы, представляющая значения заполнения для соответствующих компонентов. Значение None означает, что (вложенная) структура должна быть дополнена значениями по умолчанию. Для числовых типов по умолчанию используется 0, а для строковых типов — пустая строка. padding_values должна иметь ту же (вложенную) структуру, что и входной набор данных. Если padding_values содержит один элемент, а входной набор данных — несколько компонентов, для заполнения каждого компонента набора данных будет использоваться одно и то же значение padding_values. Если padding_values является скаляром, его значение будет распространено до формы каждого компонента.
drop_remainder (Необязательно.) Скалярный tf.bool tf.Tensor, указывающий, следует ли отбрасывать последний пакет, если в нем меньше batch_size элементов; по умолчанию меньший пакет не отбрасывается.
name (Необязательно.) Имя операции tf.data.
Возвращает
Новый Dataset с примененным описанным выше преобразованием.
Вызывает исключение
ValueError Если компонент имеет неизвестный ранг, а аргумент padded_shapes не задан.
TypeError Если компонент имеет неподдерживаемый тип. Список поддерживаемых типов описан в https://www.tensorflow.org/guide/data#dataset_structure

prefetch

Посмотреть исходный код

prefetch(
    buffer_size, name=None
) -> 'DatasetV2'

Создает Dataset, предварительно извлекающий элементы из этого набора данных.

Большинство конвейеров ввода данных должны завершаться вызовом prefetch. Это позволяет подготавливать последующие элементы, пока обрабатывается текущий элемент. Зачастую это повышает производительность и снижает задержку, но требует дополнительной памяти для хранения предварительно извлеченных элементов.

Примечание: Как и другие методы Dataset, предварительная выборка работает с элементами входного набора данных. Она не различает примеры и пакеты. examples.prefetch(2) предварительно извлечет два элемента (2 примера), а examples.batch(20).prefetch(2) — 2 элемента (2 пакета по 20 примеров в каждом).
dataset = tf.data.Dataset.range(3)
dataset = dataset.prefetch(2)
list(dataset.as_numpy_iterator())
[0, 1, 2]
Аргументы
buffer_size Скалярный tf.int64 tf.Tensor, представляющий максимальное количество элементов, буферизуемых при предварительной выборке. Если используется значение tf.data.AUTOTUNE, размер буфера настраивается динамически.
name Необязательно. Имя преобразования tf.data.
Возвращает
Новый Dataset с примененным описанным выше преобразованием.

ragged_batch

Посмотреть исходный код

ragged_batch(
    batch_size,
    drop_remainder=False,
    row_splits_dtype=tf.dtypes.int64,
    name=None
) -> 'DatasetV2'

Объединяет последовательные элементы этого набора данных в tf.RaggedTensor.

Как и в случае с tf.data.Dataset.batch, компоненты результирующего элемента получат дополнительное внешнее измерение, размер которого будет равен batch_size (или N % batch_size для последнего элемента, если batch_size не делит количество входных элементов N без остатка и drop_remainder имеет значение False). Если работа вашей программы зависит от одинакового размера внешнего измерения у всех пакетов, задайте для аргумента drop_remainder значение True, чтобы предотвратить создание меньшего пакета.

В отличие от tf.data.Dataset.batch, входные элементы, объединяемые в пакеты, могут иметь разные формы:

  • Если входной элемент — это tf.Tensor, статический tf.TensorShape которого полностью определен, он пакетируется обычным образом.
  • Если входной элемент — это tf.Tensor, статический tf.TensorShape которого содержит одну или несколько осей с неизвестным размером (т. е. shape[i]=None), выходные данные будут содержать tf.RaggedTensor, разреженный до всех таких измерений.
  • Если входной элемент — это tf.RaggedTensor или любой другой тип, он пакетируется обычным образом.

Пример:

dataset = tf.data.Dataset.range(6)
dataset = dataset.map(lambda x: tf.range(x))
dataset.element_spec.shape
TensorShape([None])
dataset = dataset.ragged_batch(2)
for batch in dataset:
  print(batch)
<tf.RaggedTensor [[], [0]]>
<tf.RaggedTensor [[0, 1], [0, 1, 2]]>
<tf.RaggedTensor [[0, 1, 2, 3], [0, 1, 2, 3, 4]]>
Аргументы
batch_size Скалярный tf.int64 tf.Tensor, представляющий количество последовательных элементов этого набора данных, объединяемых в один пакет.
drop_remainder (Необязательно.) Скалярный tf.bool tf.Tensor, указывающий, следует ли отбрасывать последний пакет, если в нем меньше batch_size элементов; по умолчанию меньший пакет не отбрасывается.
row_splits_dtype Тип данных, который следует использовать для row_splits любых новых разреженных тензоров. Тип данных row_splits существующих элементов tf.RaggedTensor не изменяется.
name (Необязательно.) Строка с именем операции tf.data.
Возвращает
Новый Dataset с примененным описанным выше преобразованием.

random

Посмотреть исходный код

@staticmethod
random(
    seed=None, rerandomize_each_iteration=None, name=None
) -> 'DatasetV2'

Создает Dataset псевдослучайных значений.

Набор данных генерирует последовательность равномерно распределенных целочисленных значений.

Параметр rerandomize_each_iteration определяет, следует ли заново рандомизировать последовательность случайных чисел для каждой эпохи. Значение по умолчанию — False: в этом случае для каждой эпохи набор данных генерирует одну и ту же последовательность случайных чисел.

ds1 = tf.data.Dataset.random(seed=4).take(10)
ds2 = tf.data.Dataset.random(seed=4).take(10)
print(list(ds1.as_numpy_iterator())==list(ds2.as_numpy_iterator()))
True
ds3 = tf.data.Dataset.random(seed=4).take(10)
ds3_first_epoch = list(ds3.as_numpy_iterator())
ds3_second_epoch = list(ds3.as_numpy_iterator())
print(ds3_first_epoch == ds3_second_epoch)
True
ds4 = tf.data.Dataset.random(
    seed=4, rerandomize_each_iteration=True).take(10)
ds4_first_epoch = list(ds4.as_numpy_iterator())
ds4_second_epoch = list(ds4.as_numpy_iterator())
print(ds4_first_epoch == ds4_second_epoch)
False
Аргументы
seed (Необязательно.) Если указан, набор данных создает детерминированную последовательность значений.
rerandomize_each_iteration (Необязательно.) Если задано значение False, набор данных генерирует одну и ту же последовательность случайных чисел для каждой эпохи. Если задано значение True, для каждой эпохи генерируется другая детерминированная последовательность случайных чисел. Если параметр не указан, по умолчанию используется False.
name (Необязательно.) Имя операции tf.data.
Возвращает
Dataset Объект Dataset.

range

Посмотреть исходный код

@staticmethod
range(
    *args, **kwargs
) -> 'DatasetV2'

Создает Dataset значений диапазона с заданным шагом.

list(Dataset.range(5).as_numpy_iterator())
[0, 1, 2, 3, 4]
list(Dataset.range(2, 5).as_numpy_iterator())
[2, 3, 4]
list(Dataset.range(1, 5, 2).as_numpy_iterator())
[1, 3]
list(Dataset.range(1, 5, -2).as_numpy_iterator())
[]
list(Dataset.range(5, 1).as_numpy_iterator())
[]
list(Dataset.range(5, 1, -2).as_numpy_iterator())
[5, 3]
list(Dataset.range(2, 5, output_type=tf.int32).as_numpy_iterator())
[2, 3, 4]
list(Dataset.range(1, 5, 2, output_type=tf.float32).as_numpy_iterator())
[1.0, 3.0]
Аргументы
*args Имеет ту же семантику, что и range в Python. len(args) == 1 -> start = 0, stop = args[0], step = 1. len(args) == 2 -> start = args[0], stop = args[1], step = 1. len(args) == 3 -> start = args[0], stop = args[1], step = args[2].
**kwargs
  • output_type: ожидаемый тип данных. (Необязательно, по умолчанию: tf.int64).
  • name: (Необязательно.) Имя операции tf.data.
Возвращает
Dataset Объект RangeDataset.
Вызывает исключение
ValueError если len(args) == 0.

rebatch

Посмотреть исходный код

rebatch(
    batch_size, drop_remainder=False, name=None
) -> 'DatasetV2'

Создает Dataset, который повторно пакетирует элементы этого набора данных.

Функционально rebatch(N) эквивалентен unbatch().batch(N), но работает эффективнее, выполняя одно копирование вместо двух.

ds = tf.data.Dataset.range(6)
ds = ds.batch(2)
ds = ds.rebatch(3)
list(ds.as_numpy_iterator())
[array([0, 1, 2]), array([3, 4, 5])]
ds = tf.data.Dataset.range(7)
ds = ds.batch(4)
ds = ds.rebatch(3)
list(ds.as_numpy_iterator())
[array([0, 1, 2]), array([3, 4, 5]), array([6])]
ds = tf.data.Dataset.range(7)
ds = ds.batch(2)
ds = ds.rebatch(3, drop_remainder=True)
list(ds.as_numpy_iterator())
[array([0, 1, 2]), array([3, 4, 5])]

Если аргумент batch_size представляет собой список, rebatch циклически перебирает его, определяя размер каждого пакета.

ds = tf.data.Dataset.range(8)
ds = ds.batch(4)
ds = ds.rebatch([2, 1, 1])
list(ds.as_numpy_iterator())
[array([0, 1]), array([2]), array([3]), array([4, 5]), array([6]),
array([7])]
Аргументы
batch_size Скаляр или вектор tf.int64, представляющий размеры создаваемых пакетов. Если этот аргумент является вектором, его значения циклически перебираются по очереди.
drop_remainder (Необязательно.) Скалярный tf.bool tf.Tensor, указывающий, следует ли отбрасывать последний пакет, если в нем меньше batch_size[cycle_index] элементов; по умолчанию меньший пакет не отбрасывается.
name (Необязательно.) Имя операции tf.data.
Возвращает
Dataset скалярных элементов dtype.

reduce

Посмотреть исходный код

reduce(
    initial_state, reduce_func, name=None
)

Сводит входной набор данных к одному элементу.

Преобразование последовательно вызывает reduce_func для каждого элемента входного набора данных, пока набор не будет исчерпан, накапливая информацию во внутреннем состоянии. Аргумент initial_state используется для задания начального состояния, а конечное состояние возвращается в качестве результата.

tf.data.Dataset.range(5).reduce(np.int64(0), lambda x, _: x + 1).numpy()
5
tf.data.Dataset.range(5).reduce(np.int64(0), lambda x, y: x + y).numpy()
10
Аргументы
initial_state Элемент, представляющий начальное состояние преобразования.
reduce_func Функция, сопоставляющая (old_state, input_element) с new_state. Она должна принимать два аргумента и возвращать новый элемент. Структура new_state должна соответствовать структуре initial_state.
name (Необязательно.) Имя операции tf.data.
Возвращает
Элемент набора данных, соответствующий конечному состоянию преобразования.

rejection_resample

Посмотреть исходный код

rejection_resample(
    class_func, target_dist, initial_dist=None, seed=None, name=None
) -> 'DatasetV2'

Выполняет повторную выборку элементов для достижения целевого распределения.

Примечание: Эта реализация может отбрасывать или повторять элементы для достижения target_dist. Поэтому в некоторых случаях выходной Dataset может быть больше входного Dataset.
initial_dist = [0.6, 0.4]
n = 1000
elems = np.random.choice(len(initial_dist), size=n, p=initial_dist)
dataset = tf.data.Dataset.from_tensor_slices(elems)
zero, one = np.bincount(list(dataset.as_numpy_iterator())) / n

Согласно initial_dist, zero составляет ~0.6, а one — ~0.4.

target_dist = [0.5, 0.5]
dataset = dataset.rejection_resample(
   class_func=lambda x: x,
   target_dist=target_dist,
   initial_dist=initial_dist)
dataset = dataset.map(lambda class_func_result, data: data)
zero, one = np.bincount(list(dataset.as_numpy_iterator())) / n

Согласно target_dist, zero составляет ~0.5, а one — ~0.5.

Аргументы
class_func Функция, сопоставляющая элемент входного набора данных скалярному тензору tf.int32. Значения должны находиться в диапазоне [0, num_classes).
target_dist Тензор с плавающей точкой формы [num_classes].
initial_dist (Необязательно.) Тензор с плавающей точкой формы [num_classes]. Если он не указан, истинное распределение классов оценивается на лету в потоковом режиме.
seed (Необязательно.) Целочисленное значение seed Python для повторной выборки.
name (Необязательно.) Имя операции tf.data.
Возвращает
Новый Dataset с примененным описанным выше преобразованием.

repeat

Посмотреть исходный код

repeat(
    count=None, name=None
) -> 'DatasetV2'

Повторяет этот набор данных, чтобы каждое исходное значение встречалось count раз.

dataset = tf.data.Dataset.from_tensor_slices([1, 2, 3])
dataset = dataset.repeat(3)
list(dataset.as_numpy_iterator())
[1, 2, 3, 1, 2, 3, 1, 2, 3]
Примечание: Если входной набор данных зависит от глобального состояния (например, генератора случайных чисел) или его выходные данные недетерминированы (например, из-за вышестоящего shuffle), при разных повторениях могут генерироваться разные элементы.
Аргументы
count (Необязательно.) Скалярный tf.int64 tf.Tensor, представляющий количество повторений набора данных. По умолчанию (если count имеет значение None или -1) набор данных повторяется бесконечно.
name (Необязательно.) Имя операции tf.data.
Возвращает
Новый Dataset с примененным описанным выше преобразованием.

sample_from_datasets

Посмотреть исходный код

@staticmethod
sample_from_datasets(
    datasets,
    weights=None,
    seed=None,
    stop_on_empty_dataset=False,
    rerandomize_each_iteration=None
) -> 'DatasetV2'

Случайным образом выбирает элементы из наборов данных в datasets.

Создает набор данных, чередуя элементы из datasets с вероятностью weight[i] выбора элемента из набора данных i. Выборка выполняется без возвращения. Например, предположим, что у нас есть 2 набора данных:

dataset1 = tf.data.Dataset.range(0, 3)
dataset2 = tf.data.Dataset.range(100, 103)

Предположим, что мы выбираем элементы из этих двух наборов данных со следующими весами:

sample_dataset = tf.data.Dataset.sample_from_datasets(
    [dataset1, dataset2], weights=[0.5, 0.5])

Один из возможных результатов для элементов в sample_dataset:

print(list(sample_dataset.as_numpy_iterator()))
# [100, 0, 1, 101, 2, 102]
Аргументы
datasets Непустой список объектов tf.data.Dataset с совместимой структурой.
weights (Необязательно.) Список или тензор значений с плавающей точкой len(datasets), где weights[i] обозначает вероятность выборки из datasets[i], либо объект tf.data.Dataset, каждый элемент которого является таким списком. По умолчанию используется равномерное распределение по datasets.
seed (Необязательно.) Скалярный tf.int64 tf.Tensor, представляющий случайное начальное значение, используемое для создания распределения. Описание поведения см. в разделе tf.random.set_seed.
stop_on_empty_dataset Если задано значение True, выборка прекращается при обнаружении пустого набора данных. Если задано значение False, выборка продолжается, а пустые наборы данных пропускаются. Рекомендуется задать значение True. В противном случае распределение выборок сначала будет соответствовать заданному пользователем, но может измениться, когда входные наборы данных опустеют. Это может быть трудно заметить, поскольку изначально набор данных выглядит корректно. Для обеспечения обратной совместимости по умолчанию используется False.
rerandomize_each_iteration Необязательный bool. Логический аргумент определяет, будет ли последовательность случайных чисел, используемых для выбора набора данных, рандомизироваться заново для каждой эпохи. Иными словами, он определяет, будут ли наборы данных выбираться в одном и том же порядке в разных эпохах (поведение по умолчанию).
Возвращает
Набор данных, который случайным образом чередует элементы из datasets в соответствии с weights, если оно задано, или с равномерной вероятностью в противном случае.
Вызывает исключение
TypeError Если аргументы datasets или weights имеют неверный тип.
ValueError
  • Если datasets пуст, или
  • Если указан weights, но его длина не совпадает с длиной datasets.

save

Посмотреть исходный код

save(
    path, compression=None, shard_func=None, checkpoint_args=None
)

Сохраняет содержимое указанного набора данных.

Пример использования:

import tempfile
path = os.path.join(tempfile.gettempdir(), "saved_data")
# Save a dataset
dataset = tf.data.Dataset.range(2)
dataset.save(path)
new_dataset = tf.data.Dataset.load(path)
for elem in new_dataset:
  print(elem)
  tf.Tensor(0, shape=(), dtype=int64)
  tf.Tensor(1, shape=(), dtype=int64)
  

Сохраненный набор данных записывается в несколько файловых «фрагментов». По умолчанию выходные данные набора распределяются по фрагментам по кругу, но можно задать пользовательское распределение с помощью функции shard_func. Например, набор данных можно сохранить в одном фрагменте следующим образом:

dataset = make_dataset()
def custom_shard_func(element):
  return np.int64(0)
dataset.save(
    path="/path/to/data", ..., shard_func=custom_shard_func)

Чтобы включить создание контрольных точек, передайте checkpoint_args методу save следующим образом:

dataset = tf.data.Dataset.range(100)
save_dir = "..."
checkpoint_prefix = "..."
step_counter = tf.Variable(0, trainable=False)
checkpoint_args = {
  "checkpoint_interval": 50,
  "step_counter": step_counter,
  "directory": checkpoint_prefix,
  "max_to_keep": 20,
}
dataset.save(dataset, save_dir, checkpoint_args=checkpoint_args)
Примечание: Структура каталогов и формат файлов, используемые для сохранения набора данных, являются деталями реализации и могут измениться. Поэтому наборы данных, сохраненные с помощью tf.data.Dataset.save, следует использовать только через tf.data.Dataset.load, для которого гарантирована обратная совместимость.
Аргументы
path Обязательный параметр. Каталог для сохранения набора данных.
compression Необязательный параметр. Алгоритм сжатия данных при записи. Поддерживаются параметры GZIP и NONE. По умолчанию используется NONE.
shard_func Необязательный параметр. Функция для управления сопоставлением элементов набора данных файловым фрагментам. Функция должна сопоставлять элементы входного набора данных целочисленным идентификаторам фрагментов int64. Если функция задана, она будет трассирована и выполнена как вычисление графа.
checkpoint_args Необязательные аргументы для создания контрольных точек, которые будут переданы в tf.train.CheckpointManager. Если checkpoint_args не указаны, контрольные точки создаваться не будут. Реализация save() создает объект tf.train.Checkpoint внутри, поэтому пользователям не следует задавать аргумент checkpoint в checkpoint_args.
Возвращает
Операцию, выполнение которой приводит к сохранению данных. При создании контрольных точек возвращает None. Возвращаемое значение полезно для модульных тестов.
Вызывает исключение
ValueError, если checkpoint передан в checkpoint_args.

scan

Посмотреть исходный код

scan(
    initial_state, scan_func, name=None
) -> 'DatasetV2'

Преобразование, применяющее функцию сканирования к входному набору данных.

Это преобразование является вариантом tf.data.Dataset.map с состоянием. Помимо отображения scan_func для элементов входного набора данных, scan() накапливает один или несколько тензоров состояния, начальные значения которых — initial_state.

dataset = tf.data.Dataset.range(10)
initial_state = tf.constant(0, dtype=tf.int64)
scan_func = lambda state, i: (state + i, state + i)
dataset = dataset.scan(initial_state=initial_state, scan_func=scan_func)
list(dataset.as_numpy_iterator())
[0, 1, 3, 6, 10, 15, 21, 28, 36, 45]
Аргументы
initial_state Вложенная структура тензоров, представляющая начальное состояние аккумулятора.
scan_func Функция, отображающая (old_state, input_element) в (new_state, output_element). Она должна принимать два аргумента и возвращать пару вложенных структур тензоров. new_state должна соответствовать структуре initial_state.
name (Необязательно.) Имя операции tf.data.
Возвращает
Новый объект Dataset с примененным описанным выше преобразованием.

shard

Посмотреть исходный код

shard(
    num_shards, index, name=None
) -> 'DatasetV2'

Создает Dataset, содержащий только 1/num_shards этого набора данных.

shard является детерминированным. Набор данных, созданный с помощью A.shard(n, i), будет содержать все элементы A, для которых индекс mod n = i.

A = tf.data.Dataset.range(10)
B = A.shard(num_shards=3, index=0)
list(B.as_numpy_iterator())
[0, 3, 6, 9]
C = A.shard(num_shards=3, index=1)
list(C.as_numpy_iterator())
[1, 4, 7]
D = A.shard(num_shards=3, index=2)
list(D.as_numpy_iterator())
[2, 5, 8]

Этот оператор набора данных очень полезен при распределенном обучении, поскольку позволяет каждому рабочему процессу считывать уникальное подмножество данных.

При чтении одного входного файла можно разделить элементы следующим образом:

d = tf.data.TFRecordDataset(input_file)
d = d.shard(num_workers, worker_index)
d = d.repeat(num_epochs)
d = d.shuffle(shuffle_buffer_size)
d = d.map(parser_fn, num_parallel_calls=num_map_threads)

Важные замечания:

  • Обязательно разделите данные до использования любого оператора рандомизации (например, shuffle).
  • Как правило, оператор shard лучше использовать в начале конвейера обработки набора данных. Например, при чтении набора файлов TFRecord разделите данные до преобразования набора данных во входные образцы. Это позволит избежать чтения каждого файла на каждом рабочем процессе. Ниже приведен пример эффективной стратегии разделения данных в полном конвейере:
d = Dataset.list_files(pattern, shuffle=False)
d = d.shard(num_workers, worker_index)
d = d.repeat(num_epochs)
d = d.shuffle(shuffle_buffer_size)
d = d.interleave(tf.data.TFRecordDataset,
                 cycle_length=num_readers, block_length=1)
d = d.map(parser_fn, num_parallel_calls=num_map_threads)
Аргументы
num_shards Скалярный tf.int64 tf.Tensor, обозначающий количество фрагментов, обрабатываемых параллельно.
index Скалярный tf.int64 tf.Tensor, обозначающий индекс рабочего процесса.
name (Необязательно.) Имя операции tf.data.
Возвращает
Новый объект Dataset с примененным описанным выше преобразованием.
Вызывает исключение
InvalidArgumentError если num_shards или index имеют недопустимые значения.
Примечание: проверка ошибок выполняется по мере возможности, и не гарантируется, что ошибки будут обнаружены при создании набора данных. (Например, передача тензора-заполнителя позволяет обойти раннюю проверку и вместо этого приводит к ошибке во время вызова session.run.)

shuffle

Посмотреть исходный код

shuffle(
    buffer_size, seed=None, reshuffle_each_iteration=None, name=None
) -> 'DatasetV2'

Случайным образом перемешивает элементы этого набора данных.

Этот оператор набора данных заполняет буфер элементами buffer_size, а затем случайным образом выбирает элементы из этого буфера, заменяя выбранные элементы новыми. Для идеального перемешивания размер буфера должен быть не меньше общего размера набора данных.

Например, если набор данных содержит 10 000 элементов, а buffer_size задано равным 1 000, то shuffle сначала будет случайным образом выбирать элементы только из первых 1 000 элементов в буфере. После выбора элемента его место в буфере занимает следующий элемент (то есть элемент 1 001), благодаря чему в буфере по-прежнему остается 1 000 элементов.

reshuffle_each_iteration определяет, должен ли порядок перемешивания меняться на каждой эпохе. В TF 1.X стандартным способом создания эпох было преобразование repeat:

dataset = tf.data.Dataset.range(3)
dataset = dataset.shuffle(3, reshuffle_each_iteration=True)
dataset = dataset.repeat(2)
# [1, 0, 2, 1, 2, 0]

dataset = tf.data.Dataset.range(3)
dataset = dataset.shuffle(3, reshuffle_each_iteration=False)
dataset = dataset.repeat(2)
# [1, 0, 2, 1, 0, 2]

В TF 2.0 объекты tf.data.Dataset являются итерируемыми объектами Python, поэтому эпохи можно также создавать с помощью итерации Python:

dataset = tf.data.Dataset.range(3)
dataset = dataset.shuffle(3, reshuffle_each_iteration=True)
list(dataset.as_numpy_iterator())
# [1, 0, 2]
list(dataset.as_numpy_iterator())
# [1, 2, 0]
dataset = tf.data.Dataset.range(3)
dataset = dataset.shuffle(3, reshuffle_each_iteration=False)
list(dataset.as_numpy_iterator())
# [1, 0, 2]
list(dataset.as_numpy_iterator())
# [1, 0, 2]

Полное перемешивание всех данных

Чтобы перемешать весь набор данных, задайте buffer_size=dataset.cardinality(). Это эквивалентно заданию значения buffer_size, равного количеству элементов в наборе данных, что приводит к равномерному перемешиванию.

Примечание: shuffle(dataset.cardinality()) загружает весь набор данных в память, чтобы его можно было перемешать. Если набор данных слишком велик, это приведет к ошибке переполнения памяти (OOM), поэтому полное перемешивание следует применять только к наборам данных, которые заведомо помещаются в памяти, например к спискам имен файлов или другим небольшим наборам данных.
dataset = tf.data.Dataset.range(20)
dataset = dataset.shuffle(dataset.cardinality())
# [18, 4, 9, 2, 17, 8, 5, 10, 0, 6, 16, 3, 19, 7, 14, 11, 15, 13, 12, 1]
Аргументы
buffer_size Скалярный tf.int64 tf.Tensor, обозначающий количество элементов этого набора данных, из которых будет производиться выборка для нового набора данных. Для равномерного перемешивания всего набора данных используйте buffer_size=dataset.cardinality().
seed (Необязательно.) Скалярный tf.int64 tf.Tensor, обозначающий случайное начальное значение, которое будет использоваться для создания распределения. Описание поведения см. в разделе tf.random.set_seed.
reshuffle_each_iteration (Необязательно.) Логическое значение: если оно равно true, набор данных будет псевдослучайно перемешиваться заново при каждой итерации. (По умолчанию равно True.)
name (Необязательно.) Имя операции tf.data.
Возвращает
Новый объект Dataset с примененным описанным выше преобразованием.

skip

Посмотреть исходный код

skip(
    count, name=None
) -> 'DatasetV2'

Создает Dataset, пропускающий count элементов этого набора данных.

dataset = tf.data.Dataset.range(10)
dataset = dataset.skip(7)
list(dataset.as_numpy_iterator())
[7, 8, 9]
Аргументы
count Скалярный tf.int64 tf.Tensor, обозначающий количество элементов этого набора данных, которые следует пропустить при создании нового набора данных. Если count больше размера этого набора данных, новый набор данных не будет содержать элементов. Если count равно -1, пропускается весь набор данных.
name (Необязательно.) Имя операции tf.data.
Возвращает
Новый объект Dataset с примененным описанным выше преобразованием.

snapshot

Посмотреть исходный код

snapshot(
    path,
    compression='AUTO',
    reader_func=None,
    shard_func=None,
    name=None
) -> 'DatasetV2'

API для сохранения результатов обработки входного набора данных.

API snapshot позволяет прозрачно сохранять результаты конвейера предварительной обработки на диск и материализовать предварительно обработанные данные при другом запуске обучения.

Этот API позволяет объединять повторяющиеся шаги предварительной обработки и повторно использовать уже обработанные данные, обменивая дисковое пространство и пропускную способность сети на высвобождение более ценных ресурсов ЦП и вычислительного времени ускорителей.

Подробная документация по проектированию этой функции приведена по адресу https://github.com/tensorflow/community/blob/master/rfcs/20200107-tf-data-snapshot.md.

Пользователи могут задавать различные параметры, управляющие поведением snapshot, в том числе способ чтения и записи снимков, передавая пользовательские функции в параметры reader_func и shard_func.

shard_func — это заданная пользователем функция, которая сопоставляет входные элементы фрагментам снимка.

Пользователи могут задать эту функцию, чтобы управлять записью файлов снимка на диск. Ниже показан пример возможной реализации shard_func.

dataset = ...
dataset = dataset.enumerate()
dataset = dataset.snapshot("/path/to/snapshot/dir",
    shard_func=lambda x, y: x % NUM_SHARDS, ...)
dataset = dataset.map(lambda x, y: y)

reader_func — это заданная пользователем функция, принимающая один аргумент: (1) набор данных, состоящий из наборов данных, каждый из которых представляет собой «часть» элементов исходного набора данных. Кардинальность входного набора данных соответствует количеству фрагментов, указанному в shard_func (см. выше). Функция должна возвращать набор данных, содержащий элементы исходного набора данных.

Пользователи могут задать эту функцию, чтобы управлять чтением файлов снимка с диска, в том числе объемом перемешивания и степенью параллелизма.

Ниже приведен пример стандартной функции чтения, которую может определить пользователь. Эта функция включает перемешивание набора данных и параллельное чтение наборов данных:

def user_reader_func(datasets):
  # shuffle the datasets splits
  datasets = datasets.shuffle(NUM_CORES)
  # read datasets in parallel and interleave their elements
  return datasets.interleave(lambda x: x, num_parallel_calls=AUTOTUNE)

dataset = dataset.snapshot("/path/to/snapshot/dir",
    reader_func=user_reader_func)

По умолчанию snapshot распараллеливает чтение по числу доступных в системе ядер, но не пытается перемешивать данные.

Аргументы
path Обязательный параметр. Каталог для сохранения и загрузки снимка.
compression Необязательный параметр. Тип сжатия, применяемого к снимку, записываемому на диск. Поддерживаются варианты GZIP, SNAPPY, AUTO или None. По умолчанию используется AUTO, которое пытается выбрать подходящий алгоритм сжатия для набора данных.
reader_func Необязательный параметр. Функция, управляющая чтением данных из фрагментов снимка.
shard_func Необязательный параметр. Функция, управляющая разделением данных на фрагменты при записи снимка.
name (Необязательно.) Имя операции tf.data.
Возвращает
Новый объект Dataset с примененным описанным выше преобразованием.

sparse_batch

Посмотреть исходный код

sparse_batch(
    batch_size, row_shape, name=None
) -> 'DatasetV2'

Объединяет последовательные элементы в объекты tf.sparse.SparseTensor.

Как и Dataset.padded_batch(), это преобразование объединяет несколько последовательных элементов набора данных, которые могут иметь разные формы, в один элемент. Полученный элемент состоит из трех компонентов (indices, values и dense_shape), которые образуют tf.sparse.SparseTensor, представляющий те же данные. row_shape представляет плотную форму каждой строки в результирующем tf.sparse.SparseTensor; к ней добавляется эффективный размер пакета. Например:

# NOTE: The following examples use `{ ... }` to represent the
# contents of a dataset.
a = { ['a', 'b', 'c'], ['a', 'b'], ['a', 'b', 'c', 'd'] }

a.apply(tf.data.experimental.dense_to_sparse_batch(
    batch_size=2, row_shape=[6])) ==
{
    ([[0, 0], [0, 1], [0, 2], [1, 0], [1, 1]],  # indices
     ['a', 'b', 'c', 'a', 'b'],                 # values
     [2, 6]),                                   # dense_shape
    ([[0, 0], [0, 1], [0, 2], [0, 3]],
     ['a', 'b', 'c', 'd'],
     [1, 6])
}
Аргументы
batch_size Скалярный tf.int64 tf.Tensor, обозначающий количество последовательных элементов этого набора данных, объединяемых в один пакет.
row_shape Объект, похожий на векторный тензор tf.TensorShape или tf.int64, представляющий эквивалентную плотную форму строки в результирующем tf.sparse.SparseTensor. Каждый элемент этого набора данных должен иметь тот же ранг, что и row_shape, а его размер в каждом измерении не должен превышать row_shape.
name (Необязательно.) Строка, задающая имя операции tf.data.
Возвращает
Новый объект Dataset с примененным описанным выше преобразованием.

take

Посмотреть исходный код

take(
    count, name=None
) -> 'DatasetV2'

Создает Dataset, содержащий не более count элементов этого набора данных.

dataset = tf.data.Dataset.range(10)
dataset = dataset.take(3)
list(dataset.as_numpy_iterator())
[0, 1, 2]
Аргументы
count Скалярный tf.int64 tf.Tensor, обозначающий количество элементов этого набора данных, которые следует взять для формирования нового набора данных. Если count равно -1 или count превышает размер этого набора данных, новый набор данных будет содержать все его элементы.
name (Необязательно.) Имя операции tf.data.
Возвращает
Новый объект Dataset с примененным описанным выше преобразованием.

take_while

Посмотреть исходный код

take_while(
    predicate, name=None
) -> 'DatasetV2'

Преобразование, прекращающее итерацию по набору данных на основании predicate.

dataset = tf.data.Dataset.range(10)
dataset = dataset.take_while(lambda x: x < 5)
list(dataset.as_numpy_iterator())
[0, 1, 2, 3, 4]
Аргументы
predicate Функция, отображающая вложенную структуру тензоров (с формами и типами, заданными self.output_shapes и self.output_types) в скалярный тензор tf.bool.
name (Необязательно.) Имя операции tf.data.
Возвращает
Новый объект Dataset с примененным описанным выше преобразованием.

unbatch

Посмотреть исходный код

unbatch(
    name=None
) -> 'DatasetV2'

Разбивает элементы набора данных на несколько элементов.

Например, если элементы набора данных имеют форму [B, a0, a1, ...], где B может различаться для каждого входного элемента, то для каждого элемента набора данных набор данных без пакетирования будет содержать B последовательных элементов формы [a0, a1, ...].

elements = [ [1, 2, 3], [1, 2], [1, 2, 3, 4] ]
dataset = tf.data.Dataset.from_generator(lambda: elements, tf.int64)
dataset = dataset.unbatch()
list(dataset.as_numpy_iterator())
[1, 2, 3, 1, 2, 1, 2, 3, 4]
Примечание: для unbatch требуется копирование данных, чтобы разделить пакетированный тензор на более мелкие тензоры без пакетирования. При оптимизации производительности старайтесь избегать ненужного использования unbatch.
Аргументы
name (Необязательно.) Имя операции tf.data.
Возвращает
Новый объект Dataset с примененным описанным выше преобразованием.

unique

Посмотреть исходный код

unique(
    name=None
) -> 'DatasetV2'

Преобразование, удаляющее повторяющиеся элементы из Dataset.

Используйте это преобразование, чтобы создать набор данных, содержащий по одному экземпляру каждого уникального элемента входных данных. Например:

dataset = tf.data.Dataset.from_tensor_slices([1, 37, 2, 37, 2, 1])
dataset = dataset.unique()
sorted(list(dataset.as_numpy_iterator()))
[1, 2, 37]
Примечание: это преобразование поддерживает только наборы данных, которые помещаются в память и содержат элементы типа tf.int32, tf.int64 или tf.string.
Аргументы
name (Необязательно.) Имя операции tf.data.
Возвращает
Новый объект Dataset с примененным описанным выше преобразованием.

window

Посмотреть исходный код

window(
    size, shift=None, stride=1, drop_remainder=False, name=None
) -> 'DatasetV2'

Возвращает набор данных, состоящий из «окон».

Каждое «окно» — это набор данных, содержащий подмножество элементов входного набора данных. Это конечные наборы данных размером size (или меньше, если входных элементов недостаточно для заполнения окна и drop_remainder имеет значение False).

Например:

dataset = tf.data.Dataset.range(7).window(3)
for window in dataset:
  print(window)
<...Dataset element_spec=TensorSpec(shape=(), dtype=tf.int64, name=None)>
<...Dataset element_spec=TensorSpec(shape=(), dtype=tf.int64, name=None)>
<...Dataset element_spec=TensorSpec(shape=(), dtype=tf.int64, name=None)>

Поскольку окна являются наборами данных, по ним можно выполнять итерацию:

for window in dataset:
  print(list(window.as_numpy_iterator()))
[0, 1, 2]
[3, 4, 5]
[6]

Смещение

Аргумент shift задает количество входных элементов, на которое нужно сместиться между началами окон. Если окна и элементы нумеруются с 0, первый элемент окна k будет элементом k * shift входного набора данных. В частности, первый элемент первого окна всегда будет первым элементом входного набора данных.

dataset = tf.data.Dataset.range(7).window(3, shift=1,
                                          drop_remainder=True)
for window in dataset:
  print(list(window.as_numpy_iterator()))
[0, 1, 2]
[1, 2, 3]
[2, 3, 4]
[3, 4, 5]
[4, 5, 6]

Шаг

Аргумент stride задает шаг между входными элементами внутри окна.

dataset = tf.data.Dataset.range(7).window(3, shift=1, stride=2,
                                          drop_remainder=True)
for window in dataset:
  print(list(window.as_numpy_iterator()))
[0, 2, 4]
[1, 3, 5]
[2, 4, 6]

Вложенные элементы

При применении преобразования window к набору данных, элементы которого являются вложенными структурами, создается набор данных с такой же вложенной структурой элементов, но каждый лист заменяется окном. Иными словами, вложенность применяется снаружи окон, а не внутри них.

Сигнатура типа:

def window(
    self: Dataset[Nest[T]], ...
) -> Dataset[Nest[Dataset[T]]]

Применение window к Dataset кортежей дает кортеж окон:

dataset = tf.data.Dataset.from_tensor_slices(([1, 2, 3, 4, 5],
                                              [6, 7, 8, 9, 10]))
dataset = dataset.window(2)
windows = next(iter(dataset))
windows
(<...Dataset element_spec=TensorSpec(shape=(), dtype=tf.int32, name=None)>,
 <...Dataset element_spec=TensorSpec(shape=(), dtype=tf.int32, name=None)>)
def to_numpy(ds):
  return list(ds.as_numpy_iterator())

for windows in dataset:
  print(to_numpy(windows[0]), to_numpy(windows[1]))
[1, 2] [6, 7]
[3, 4] [8, 9]
[5] [10]

Применение window к Dataset словарей дает словарь объектов Datasets:

dataset = tf.data.Dataset.from_tensor_slices({'a': [1, 2, 3],
                                              'b': [4, 5, 6],
                                              'c': [7, 8, 9]})
dataset = dataset.window(2)
def to_numpy(ds):
  return list(ds.as_numpy_iterator())

for windows in dataset:
  print(tf.nest.map_structure(to_numpy, windows))
{'a': [1, 2], 'b': [4, 5], 'c': [7, 8]}
{'a': [3], 'b': [6], 'c': [9]}

Преобразование набора данных окон в плоский набор

Методы Dataset.flat_map и Dataset.interleave можно использовать для преобразования набора данных окон в один набор данных.

Аргументом flat_map является функция, которая принимает элемент набора данных и возвращает Dataset. flat_map последовательно объединяет полученные наборы данных.

Например, чтобы преобразовать каждое окно в плотный тензор:

dataset = tf.data.Dataset.range(7).window(3, shift=1,
                                          drop_remainder=True)
batched = dataset.flat_map(lambda x:x.batch(3))
for batch in batched:
  print(batch.numpy())
[0 1 2]
[1 2 3]
[2 3 4]
[3 4 5]
[4 5 6]
Аргументы
size Скалярный tf.int64 tf.Tensor, обозначающий количество элементов входного набора данных, объединяемых в окно. Должно быть положительным.
shift (Необязательно.) Скалярный tf.int64 tf.Tensor, обозначающий количество входных элементов, на которое сдвигается окно при каждой итерации. По умолчанию равно size. Должно быть положительным.
stride (Необязательно.) Скалярный tf.int64 tf.Tensor, обозначающий шаг входных элементов в скользящем окне. Должен быть положительным. Значение по умолчанию 1 означает «сохранять каждый входной элемент».
drop_remainder (Необязательно.) Скалярный tf.bool tf.Tensor, указывающий, следует ли отбрасывать последние окна, если их размер меньше size.
name (Необязательно.) Имя операции tf.data.
Возвращает
Новый объект Dataset с примененным описанным выше преобразованием.

with_options

Посмотреть исходный код

with_options(
    options, name=None
) -> 'DatasetV2'

Возвращает новый объект tf.data.Dataset с заданными параметрами.

Параметры являются «глобальными» в том смысле, что применяются ко всему набору данных. Если параметры задаются несколько раз, они объединяются, если только для одних и тех же параметров не указаны различные значения, отличные от значений по умолчанию.

ds = tf.data.Dataset.range(5)
ds = ds.interleave(lambda x: tf.data.Dataset.range(5),
                   cycle_length=3,
                   num_parallel_calls=3)
options = tf.data.Options()
# This will make the interleave order non-deterministic.
options.deterministic = False
ds = ds.with_options(options)
Аргументы
options Объект tf.data.Options, задающий используемые параметры.
name (Необязательно.) Имя операции tf.data.
Возвращает
Новый объект Dataset с примененным описанным выше преобразованием.
Вызывает исключение
ValueError если для параметра несколько раз задано значение, отличное от значения по умолчанию

zip

Посмотреть исходный код

@staticmethod
zip(
    *args, datasets=None, name=None
) -> 'DatasetV2'

Создает Dataset, объединяя указанные наборы данных с помощью zip.

Семантика этого метода аналогична семантике встроенной функции zip() в Python. Основное отличие состоит в том, что аргумент datasets может представлять собой (вложенную) структуру объектов Dataset. Поддерживаемые механизмы вложенности описаны здесь.

# The datasets or nested structure of datasets `*args` argument
# determines the structure of elements in the resulting dataset.
a = tf.data.Dataset.range(1, 4)  # ==> [ 1, 2, 3 ]
b = tf.data.Dataset.range(4, 7)  # ==> [ 4, 5, 6 ]
ds = tf.data.Dataset.zip(a, b)
list(ds.as_numpy_iterator())
[(1, 4), (2, 5), (3, 6)]
ds = tf.data.Dataset.zip(b, a)
list(ds.as_numpy_iterator())
[(4, 1), (5, 2), (6, 3)]

# The `datasets` argument may contain an arbitrary number of datasets.
c = tf.data.Dataset.range(7, 13).batch(2)  # ==> [ [7, 8],
                                           #       [9, 10],
                                           #       [11, 12] ]
ds = tf.data.Dataset.zip(a, b, c)
for element in ds.as_numpy_iterator():
  print(element)
(1, 4, array([7, 8]))
(2, 5, array([ 9, 10]))
(3, 6, array([11, 12]))

# The number of elements in the resulting dataset is the same as
# the size of the smallest dataset in `datasets`.
d = tf.data.Dataset.range(13, 15)  # ==> [ 13, 14 ]
ds = tf.data.Dataset.zip(a, d)
list(ds.as_numpy_iterator())
[(1, 13), (2, 14)]
Аргументы
*args Наборы данных или их вложенные структуры для объединения с помощью zip. Этот параметр нельзя задавать, если задан datasets.
datasets (Вложенная) структура наборов данных. Этот параметр нельзя задавать, если задан *args. Обратите внимание: он существует только для обратной совместимости; предпочтительно использовать *args.
name (Необязательно.) Имя операции tf.data.
Возвращает
Новый объект Dataset с примененным описанным выше преобразованием.

__bool__

Посмотреть исходный код

__bool__()

__iter__

Посмотреть исходный код

__iter__() -> iterator_ops.OwnedIterator

Создает итератор для элементов этого набора данных.

Возвращаемый итератор реализует протокол Iterator языка Python.

Возвращает
tf.data.Iterator для элементов этого набора данных.
Вызывает исключение
RuntimeError Если выполнение происходит не внутри tf.function и не в eager-режиме.

__len__

Посмотреть исходный код

__len__()

Возвращает длину набора данных, если она известна и конечна.

Этот метод требует выполнения в eager-режиме, а также чтобы длина набора данных была известна и конечна. Если длина неизвестна или бесконечна либо выполнение происходит в графовом режиме, вместо этого используйте tf.data.Dataset.cardinality.

Возвращает
Целое число, представляющее длину набора данных.
Вызывает
RuntimeError Если длина набора данных неизвестна или бесконечна либо если жадное выполнение не включено.

__nonzero__

Просмотреть исходный код

__nonzero__()

© 2022 The TensorFlow Authors. All rights reserved.
Licensed under the Creative Commons Attribution License 4.0.
Code samples licensed under the Apache 2.0 License.
https://www.tensorflow.org/api_docs/python/tf/data/Dataset

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API