Spec-Zone.ru › TensorFlow

tf.experimental.dtensor.DTensorDataset

Набор данных DTensor.

Наследует от: Dataset

tf.experimental.dtensor.DTensorDataset(
    dataset: data_types.DatasetV2,
    *,
    mesh: tf.experimental.dtensor.Mesh,
    layouts: Any,
    global_batch_size: int,
    dataset_already_batched: bool = False,
    batch_dim: Optional[str] = None,
    prefetch: Optional[int] = None,
    tf_data_service_config: Optional[TFDataServiceConfig] = None
)

DTensorDataset инкапсулирует tf.data.Dataset, элементы которого автоматически упаковываются и возвращаются как DTensors на основе заданной mesh и layouts.

Аргументы
dataset объект tf.data.Dataset.
mesh mesh DTensor, в которой размещаются пакеты набора данных.
layouts структура layouts DTensor, применяемых к значениям входного набора данных. Это может быть один layout или (возможно, вложенные) кортежи либо словари layouts; структура должна соответствовать структуре набора данных. Все layouts должны быть сегментированы по измерению пакета либо ни один из них не должен быть сегментирован по нему; частичная сегментация layouts по пакетам не поддерживается и вызывает ValueError.
global_batch_size требуемый глобальный размер пакета.
dataset_already_batched следует задавать только в том случае, если набор данных уже разбит на пакеты размера для каждой реплики. Для пакетированного набора данных должно быть задано drop_remainder=True, поскольку DTensor требуется статическая форма для разбиения входных тензоров.
batch_dim измерение mesh, по которому сегментируется измерение пакета входных данных. Укажите None, если layouts входных данных не сегментируют измерение пакета.
prefetch количество пакетов для предварительной выборки с помощью Dataset.prefetch.
tf_data_service_config при работе в режиме с несколькими клиентами эта конфигурация задает используемые параметры сервиса tf.data.
Вызывает исключения
ValueError в любой из следующих ситуаций:
  1. если структуры и ранги layouts и набора данных не совпадают.
  2. если формы в спецификации набора данных определены не полностью.
  3. если задан batch_dim и не все layouts сегментированы по пакетам.
  4. если для уже пакетированного Dataset задан per_replica_batch_size, но его значение не соответствует ожидаемому размеру для каждой реплики на основе предоставленной mesh.
TypeError если типы структур layouts и набора данных не совпадают.
Атрибуты
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 группируются по длине, затем дополняются и объединяются в пакеты.

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

Ниже приведен пример распределения входных данных по 3 корзинам «[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 bool; если 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, задающий имя каталога в файловой системе для кэширования элементов этого Dataset. Если имя файла не указано, набор данных кэшируется в памяти.
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 в не содержащем состояния выражении «тензор на входе — тензор на выходе» без создания итератора. Это упрощает преобразование данных в тензорах с помощью оптимизированной абстракции 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), поскольку повторное применение glob к каждому имени файла с помощью 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, prefetch работает с элементами входного набора данных. Он не различает примеры и пакеты. 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; вероятность выбора элемента из набора данных i равна weight[i]. Выборка выполняется без возвращения. Например, предположим, что у нас есть два набора данных:

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)

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

  • Обязательно выполняйте разбиение на шарды до применения любого оператора рандомизации (например, перемешивания).
  • Как правило, оператор разбиения на шарды лучше использовать в начале конвейера обработки набора данных. Например, при чтении из набора файлов 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.)
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.

Этот метод имеет семантику, схожую со встроенной функцией Python zip(), но с одним основным отличием: аргумент 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__()

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

Возвращаемый итератор реализует протокол итератора 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/experimental/dtensor/DTensorDataset

Spec-Zone.ru

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