tf.compat.v1.data.experimental.RandomDataset
Dataset псевдослучайных значений.
tf.compat.v1.data.experimental.RandomDataset(
seed=None, rerandomize_each_iteration=None, name=None
)
| Атрибуты | |
|---|---|
element_spec | Спецификация типов элементов этого набора данных.
dataset = tf.data.Dataset.from_tensor_slices([1, 2, 3]) dataset.element_spec TensorSpec(shape=(), dtype=tf.int32, name=None) Дополнительные сведения см. в этом руководстве. |
output_classes | Возвращает класс каждого компонента элемента этого набора данных. (устарело) |
output_shapes | Возвращает форму каждого компонента элемента этого набора данных. (устарело) |
output_types | Возвращает тип каждого компонента элемента этого набора данных. (устарело) |
Методы
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 | Логическое значение; если False, размерности неизвестного размера дополняются до максимальной длины в пакете. Если True, размерности неизвестного размера дополняются до границы корзины минус 1 (то есть до максимальной длины в каждой корзине), и вызывающий код должен гарантировать, что исходный Dataset не содержит элементов длиной больше max(bucket_boundaries). |
no_padding | bool — указывает, нужно ли дополнять признаки пакета (признаки должны иметь тип tf.sparse.SparseTensor или одинаковую форму). |
drop_remainder | (Необязательно.) Скалярный tf.bool tf.Tensor, указывающий, следует ли отбрасывать последний пакет, если в нем меньше batch_size элементов; по умолчанию пакет меньшего размера не отбрасывается. |
name | (Необязательно.) Имя операции tf.data. |
| Возвращает | |
|---|---|
Новый Dataset с примененным, как описано выше, преобразованием. |
| Вызывает исключения | |
|---|---|
ValueError | если len(bucket_batch_sizes) != len(bucket_boundaries) + 1. |
cache
cache(
filename='', name=None
) -> 'DatasetV2'
Кэширует элементы этого набора данных.
При первом проходе по набору данных его элементы кэшируются в указанном файле или в памяти. При последующих проходах используются кэшированные данные.
Примечание: Чтобы гарантировать завершение формирования кэша, необходимо полностью пройти входной набор данных до возникновения StopIteration. В противном случае при последующих проходах кэшированные данные могут не использоваться.
dataset = tf.data.Dataset.range(5) dataset = dataset.map(lambda x: x**2) dataset = dataset.cache() # The first time reading through the data will generate the data using # `range` and `map`. list(dataset.as_numpy_iterator()) [0, 1, 4, 9, 16] # Subsequent iterations read from the cache. list(dataset.as_numpy_iterator()) [0, 1, 4, 9, 16]
При кэшировании в файл данные сохраняются между запусками. Даже при первом проходе данные считываются из файла кэша. Изменение входного конвейера перед вызовом .cache() не даст эффекта, пока файл кэша не будет удален или его имя не будет изменено.
dataset = tf.data.Dataset.range(5)
dataset = dataset.cache("/path/to/file")
list(dataset.as_numpy_iterator())
# [0, 1, 2, 3, 4]
dataset = tf.data.Dataset.range(10)
dataset = dataset.cache("/path/to/file") # Same file!
list(dataset.as_numpy_iterator())
# [0, 1, 2, 3, 4]
Примечание:cacheбудет выдавать при каждом проходе по набору данных одни и те же элементы. Если требуется случайный порядок элементов, вызывайтеshuffleпосле вызоваcache.
| Аргументы | |
|---|---|
filename | Скалярный tf.string tf.Tensor, задающий имя каталога в файловой системе, который будет использоваться для кэширования элементов этого набора данных. Если имя файла не указано, набор данных кэшируется в памяти. |
name | (Необязательно.) Имя операции tf.data. |
| Возвращает | |
|---|---|
Новый Dataset с примененным, как описано выше, преобразованием. |
cardinality
cardinality()
Возвращает мощность набора данных, если она известна.
cardinality может возвращать tf.data.INFINITE_CARDINALITY, если набор данных содержит бесконечное число элементов, или tf.data.UNKNOWN_CARDINALITY, если анализу не удалось определить число элементов в наборе данных (например, когда источником данных является файл).
dataset = tf.data.Dataset.range(42) print(dataset.cardinality().numpy()) 42 dataset = dataset.repeat() cardinality = dataset.cardinality() print((cardinality == tf.data.INFINITE_CARDINALITY).numpy()) True dataset = dataset.filter(lambda x: True) cardinality = dataset.cardinality() print((cardinality == tf.data.UNKNOWN_CARDINALITY).numpy()) True
| Возвращает | |
|---|---|
Скалярный tf.int64 Tensor, представляющий мощность набора данных. Если мощность бесконечна или неизвестна, cardinality возвращает именованные константы tf.data.INFINITE_CARDINALITY и tf.data.UNKNOWN_CARDINALITY соответственно. |
choose_from_datasets
@staticmethod
choose_from_datasets(
datasets, choice_dataset, stop_on_empty_dataset=True
) -> 'DatasetV2'
Создает набор данных, детерминированно выбирающий элементы из datasets.
Например, для следующих наборов данных:
datasets = [tf.data.Dataset.from_tensors("foo").repeat(),
tf.data.Dataset.from_tensors("bar").repeat(),
tf.data.Dataset.from_tensors("baz").repeat()]
# Define a dataset containing `[0, 1, 2, 0, 1, 2, 0, 1, 2]`.
choice_dataset = tf.data.Dataset.range(3).repeat(3)
result = tf.data.Dataset.choose_from_datasets(datasets, choice_dataset)
Элементами result будут:
"foo", "bar", "baz", "foo", "bar", "baz", "foo", "bar", "baz"
| Аргументы | |
|---|---|
datasets | Непустой список объектов tf.data.Dataset с совместимой структурой. |
choice_dataset | tf.data.Dataset скалярных тензоров tf.int64 со значениями от 0 до len(datasets) - 1. |
stop_on_empty_dataset | Если True, выбор останавливается при обнаружении пустого набора данных. Если False, пустые наборы данных пропускаются. Рекомендуется задать значение True. Иначе выбранные элементы сначала будут соответствовать ожиданиям пользователя, но могут измениться, когда входные наборы данных опустеют. Это может быть трудно обнаружить, поскольку изначально набор данных выглядит корректно. Значение по умолчанию — True. |
| Возвращает | |
|---|---|
Новый Dataset с примененным, как описано выше, преобразованием. |
| Вызывает исключения | |
|---|---|
TypeError | Если datasets или choice_dataset имеет неверный тип. |
ValueError | Если datasets пуст. |
concatenate
concatenate(
dataset, name=None
) -> 'DatasetV2'
Создает Dataset, объединяя указанный набор данных с этим набором данных.
a = tf.data.Dataset.range(1, 4) # ==> [ 1, 2, 3 ] b = tf.data.Dataset.range(4, 8) # ==> [ 4, 5, 6, 7 ] ds = a.concatenate(b) list(ds.as_numpy_iterator()) [1, 2, 3, 4, 5, 6, 7] # The input dataset and dataset to be concatenated should have # compatible element specs. c = tf.data.Dataset.zip((a, b)) a.concatenate(c) Traceback (most recent call last): TypeError: Two datasets to concatenate have different types <dtype: 'int64'> and (tf.int64, tf.int64) d = tf.data.Dataset.from_tensor_slices(["a", "b", "c"]) a.concatenate(d) Traceback (most recent call last): TypeError: Two datasets to concatenate have different types <dtype: 'int64'> and <dtype: 'string'>
| Аргументы | |
|---|---|
dataset | Dataset для объединения. |
name | (Необязательно.) Имя операции tf.data. |
| Возвращает | |
|---|---|
Новый Dataset с примененным, как описано выше, преобразованием. |
counter
@staticmethod
counter(
start=0,
step=1,
dtype=tf.dtypes.int64,
name=None
) -> 'DatasetV2'
Создает Dataset, который считает от start с шагом step.
В отличие от tf.data.Dataset.range, который останавливается на заданном конечном числе, tf.data.Dataset.counter бесконечно выдает элементы.
dataset = tf.data.experimental.Counter().take(5) list(dataset.as_numpy_iterator()) [0, 1, 2, 3, 4] dataset.element_spec TensorSpec(shape=(), dtype=tf.int64, name=None) dataset = tf.data.experimental.Counter(dtype=tf.int32) dataset.element_spec TensorSpec(shape=(), dtype=tf.int32, name=None) dataset = tf.data.experimental.Counter(start=2).take(5) list(dataset.as_numpy_iterator()) [2, 3, 4, 5, 6] dataset = tf.data.experimental.Counter(start=2, step=5).take(5) list(dataset.as_numpy_iterator()) [2, 7, 12, 17, 22] dataset = tf.data.experimental.Counter(start=10, step=-1).take(5) list(dataset.as_numpy_iterator()) [10, 9, 8, 7, 6]
| Аргументы | |
|---|---|
start | (Необязательно.) Начальное значение счетчика. По умолчанию — 0. |
step | (Необязательно.) Шаг счетчика. По умолчанию — 1. |
dtype | (Необязательно.) Тип данных элементов счетчика. По умолчанию — tf.int64. |
name | (Необязательно.) Имя операции tf.data. |
| Возвращает | |
|---|---|
Dataset скалярных элементов типа dtype. |
enumerate
enumerate(
start=0, name=None
) -> 'DatasetV2'
Нумерует элементы этого набора данных.
Аналогично функции enumerate в Python.
dataset = tf.data.Dataset.from_tensor_slices([1, 2, 3]) dataset = dataset.enumerate(start=5) for element in dataset.as_numpy_iterator(): print(element) (5, 1) (6, 2) (7, 3)
# The (nested) structure of the input dataset determines the # structure of elements in the resulting dataset. dataset = tf.data.Dataset.from_tensor_slices([(7, 8), (9, 10)]) dataset = dataset.enumerate() for element in dataset.as_numpy_iterator(): print(element) (0, array([7, 8], dtype=int32)) (1, array([ 9, 10], dtype=int32))
| Аргументы | |
|---|---|
start | Скалярный tf.int64 tf.Tensor, задающий начальное значение нумерации. |
name | Необязательно. Имя операций tf.data, используемых enumerate. |
| Возвращает | |
|---|---|
Новый Dataset с примененным, как описано выше, преобразованием. |
filter
filter(
predicate, name=None
) -> 'DatasetV2'
Фильтрует этот набор данных в соответствии с predicate.
dataset = tf.data.Dataset.from_tensor_slices([1, 2, 3]) dataset = dataset.filter(lambda x: x < 3) list(dataset.as_numpy_iterator()) [1, 2] # `tf.math.equal(x, y)` is required for equality comparison def filter_fn(x): return tf.math.equal(x, 1) dataset = dataset.filter(filter_fn) list(dataset.as_numpy_iterator()) [1]
| Аргументы | |
|---|---|
predicate | Функция, отображающая элемент набора данных в логическое значение. |
name | (Необязательно.) Имя операции tf.data. |
| Возвращает | |
|---|---|
Новый Dataset с примененным, как описано выше, преобразованием. |
filter_with_legacy_function
filter_with_legacy_function(
predicate
) -> 'DatasetV2'
Фильтрует этот набор данных в соответствии с predicate. (устарело)
Примечание: Это обходной путь для существующих вариантов использованияfilter, несовместимых с функциями V2. Настоятельно не рекомендуется применять его в новом коде; существующий код следует перевести наfilter, поскольку этот метод будет удален в V2.
| Аргументы | |
|---|---|
predicate | Функция, отображающая (вложенную) структуру тензоров (с формами и типами, заданными self.output_shapes и self.output_types) в скалярный тензор tf.bool. |
| Возвращает | |
|---|---|
Dataset | Dataset, содержащий элементы этого набора данных, для которых predicate равно True. |
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. (устаревшие аргументы)
Примечание: Текущая реализация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_sparse_tensor_slices
@staticmethod
from_sparse_tensor_slices(
sparse_tensor
)
Разбивает каждый разреженный тензор ранга N tf.sparse.SparseTensor в этом наборе данных построчно. (устарело)
| Аргументы | |
|---|---|
sparse_tensor | Объект tf.sparse.SparseTensor. |
| Возвращает | |
|---|---|
Dataset | Объект Dataset из разреженных тензоров ранга N-1. |
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 в статeless-выражении «тензор на входе — тензор на выходе», не создавая итератор. Это упрощает преобразование тензоров с помощью оптимизированной абстракции 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.int64 типа tf.Tensor, задающий количество последовательных элементов с одинаковым ключом, объединяемых в один пакет, который будет передан в reduce_func. Не может использоваться одновременно с window_size_func. |
window_size_func | Функция, преобразующая ключ в скалярный тензор tf.int64 типа tf.Tensor, задающий количество последовательных элементов с одинаковым ключом, объединяемых в один пакет, который будет передан в 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/*.py", набор данных выдаст:
|
| Аргументы | |
|---|---|
file_pattern | Строка, список строк или tf.Tensor строкового типа (скаляр или вектор), задающие шаблон(ы) glob для имён файлов (то есть шаблон(ы) подстановочных знаков оболочки), которым должны соответствовать имена файлов. |
shuffle | (Необязательно.) Если True, имена файлов будут перемешаны в случайном порядке. По умолчанию — True. |
seed | (Необязательно.) Скалярный тензор tf.int64 типа tf.Tensor, задающий начальное значение генератора случайных чисел, используемое для создания распределения. Описание поведения см. в разделе 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 не задан и метод выполняется в режиме графа. |
make_initializable_iterator
make_initializable_iterator(
shared_name=None
) -> tf.compat.v1.data.Iterator
Создаёт итератор для элементов этого набора данных. (устарело)
Примечание: Возвращённый итератор будет неинициализирован. Перед использованием необходимо выполнить операцию iterator.initializer:
# Building graph ...
dataset = ...
iterator = dataset.make_initializable_iterator()
next_value = iterator.get_next() # This is a Tensor.
# ... from within a session ...
sess.run(iterator.initializer)
try:
while True:
value = sess.run(next_value)
...
except tf.errors.OutOfRangeError:
pass
| Аргументы | |
|---|---|
shared_name | (Необязательно.) Если значение непустое, возвращённый итератор будет доступен под указанным именем в нескольких сеансах, использующих одни и те же устройства (например, при использовании удалённого сервера). |
| Возвращает | |
|---|---|
Объект tf.data.Iterator для элементов этого набора данных. |
| Исключения | |
|---|---|
RuntimeError | Если включен eager-режим выполнения. |
make_one_shot_iterator
make_one_shot_iterator() -> Union[iterator_ops.Iterator, iterator_ops.OwnedIterator]
Создает итератор для элементов этого набора данных. (устарело)
Примечание: Возвращенный итератор будет инициализирован автоматически. «Одноразовый» итератор в настоящее время не поддерживает повторную инициализацию. Для этого см. make_initializable_iterator.
Пример:
# Building graph ...
dataset = ...
next_value = dataset.make_one_shot_iterator().get_next()
# ... from within a session ...
try:
while True:
value = sess.run(next_value)
...
except tf.errors.OutOfRangeError:
pass
| Возвращает | |
|---|---|
tf.data.Iterator для элементов этого набора данных. |
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 (eager-режим или граф), 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 с примененным описанным выше преобразованием. |
map_with_legacy_function
map_with_legacy_function(
map_func, num_parallel_calls=None, deterministic=None
) -> 'DatasetV1Adapter'
Применяет map_func к элементам этого набора данных. (устарело)
Примечание: Это обходной путь для существующих случаев использованияmap, несовместимых с функциями V2. Настоятельно не рекомендуется использовать этот способ в новом коде, а существующий код следует перевести наmap, поскольку этот метод будет удален в V2.
| Аргументы | |
|---|---|
map_func | Функция, отображающая (вложенную) структуру тензоров (с формами и типами, заданными self.output_shapes и self.output_types) в другую (вложенную) структуру тензоров. |
num_parallel_calls | (Необязательно.) Скалярный tf.int32 tf.Tensor, задающий количество элементов, обрабатываемых асинхронно параллельно. Если значение не указано, элементы обрабатываются последовательно. Если используется значение tf.data.AUTOTUNE, количество параллельных вызовов задается динамически на основе доступных ресурсов ЦП. |
deterministic | (Необязательно.) Если задано num_parallel_calls, этот логический параметр управляет порядком выдачи элементов преобразованием. Если задано значение False, преобразованию разрешается выдавать элементы не по порядку, обменивая детерминизм на производительность. Если параметр не указан, поведение определяется параметром tf.data.Options.deterministic (по умолчанию — True). |
| Возвращает | |
|---|---|
Dataset | Dataset. |
options
options()
Возвращает параметры этого набора данных и его входных данных.
| Возвращает | |
|---|---|
Объект tf.data.Options, представляющий параметры набора данных. |
padded_batch
padded_batch(
batch_size,
padded_shapes=None,
padding_values=None,
drop_remainder=False,
name=None
) -> 'DatasetV2'
Объединяет последовательные элементы этого набора данных в дополненные пакеты.
Это преобразование объединяет несколько последовательных элементов входного набора данных в один элемент.
Как и в случае с tf.data.Dataset.batch, компоненты результирующего элемента получат дополнительное внешнее измерение, которое будет равно batch_size (или N % batch_size для последнего элемента, если batch_size не делит количество входных элементов N нацело и drop_remainder имеет значение False). Если программа предполагает, что внешнее измерение пакетов одинаково, задайте аргумент drop_remainder равным True, чтобы предотвратить создание пакета меньшего размера.
В отличие от tf.data.Dataset.batch, входные элементы, объединяемые в пакеты, могут иметь разные формы, и это преобразование дополнит каждый компонент до соответствующей формы, заданной в padded_shapes. Аргумент padded_shapes определяет результирующую форму каждого измерения каждого компонента выходного элемента:
- Если измерение задано константой, компонент будет дополнен до указанной длины по этому измерению.
- Если измерение неизвестно, компонент будет дополнен до максимальной длины всех элементов по этому измерению.
A = (tf.data.Dataset
.range(1, 5, output_type=tf.int32)
.map(lambda x: tf.fill([x], x)))
# Pad to the smallest per-batch size that fits all elements.
B = A.padded_batch(2)
for element in B.as_numpy_iterator():
print(element)
[[1 0]
[2 2]]
[[3 3 3 0]
[4 4 4 4]]
# Pad to a fixed size.
C = A.padded_batch(2, padded_shapes=5)
for element in C.as_numpy_iterator():
print(element)
[[1 0 0 0 0]
[2 2 0 0 0]]
[[3 3 3 0 0]
[4 4 4 4 0]]
# Pad with a custom value.
D = A.padded_batch(2, padded_shapes=5, padding_values=-1)
for element in D.as_numpy_iterator():
print(element)
[[ 1 -1 -1 -1 -1]
[ 2 2 -1 -1 -1]]
[[ 3 3 3 -1 -1]
[ 4 4 4 4 -1]]
# Components of nested elements can be padded independently.
elements = [([1, 2, 3], [10]),
([4, 5], [11, 12])]
dataset = tf.data.Dataset.from_generator(
lambda: iter(elements), (tf.int32, tf.int32))
# Pad the first component of the tuple to length 4, and the second
# component to the smallest size that fits.
dataset = dataset.padded_batch(2,
padded_shapes=([4], [None]),
padding_values=(-1, 100))
list(dataset.as_numpy_iterator())
[(array([[ 1, 2, 3, -1], [ 4, 5, -1, -1]], dtype=int32),
array([[ 10, 100], [ 11, 12]], dtype=int32))]
# Pad with a single value and multiple components.
E = tf.data.Dataset.zip((A, A)).padded_batch(2, padding_values=-1)
for element in E.as_numpy_iterator():
print(element)
(array([[ 1, -1],
[ 2, 2]], dtype=int32), array([[ 1, -1],
[ 2, 2]], dtype=int32))
(array([[ 3, 3, 3, -1],
[ 4, 4, 4, 4]], dtype=int32), array([[ 3, 3, 3, -1],
[ 4, 4, 4, 4]], dtype=int32))См. также tf.data.experimental.dense_to_sparse_batch, которая объединяет элементы, имеющие разные формы, в tf.sparse.SparseTensor.
| Аргументы | |
|---|---|
batch_size | Скалярный tf.int64 tf.Tensor, задающий количество последовательных элементов этого набора данных, которые нужно объединить в один пакет. |
padded_shapes | (Необязательно.) (Вложенная) структура объектов, подобных векторным тензорам, типа tf.TensorShape или tf.int64, задающая форму, до которой следует дополнить соответствующий компонент каждого входного элемента перед пакетированием. Все неизвестные измерения будут дополнены до максимального размера этого измерения в каждом пакете. Если значение не задано, все измерения всех компонентов дополняются до максимального размера в пакете. Если у какого-либо компонента ранг неизвестен, необходимо задать padded_shapes. |
padding_values | (Необязательно.) (Вложенная) структура скалярных tf.Tensor, задающая значения заполнения для соответствующих компонентов. Значение None означает, что для заполнения вложенной структуры следует использовать значения по умолчанию. Для числовых типов по умолчанию используется 0, а для строковых — пустая строка. padding_values должна иметь ту же (вложенную) структуру, что и входной набор данных. Если padding_values состоит из одного элемента, а входной набор данных содержит несколько компонентов, то для заполнения каждого компонента набора данных будет использоваться одно и то же значение padding_values. Если padding_values является скаляром, его значение будет транслировано до формы каждого компонента. |
drop_remainder | (Необязательно.) Скалярный tf.bool tf.Tensor, указывающий, следует ли отбрасывать последний пакет, если в нем меньше batch_size элементов; по умолчанию пакет меньшего размера не отбрасывается. |
name | (Необязательно.) Имя операции tf.data. |
| Возвращает | |
|---|---|
Новый Dataset с примененным описанным выше преобразованием. |
| Исключения | |
|---|---|
ValueError | Если у компонента неизвестен ранг, а аргумент padded_shapes не задан. |
TypeError | Если компонент имеет неподдерживаемый тип. Список поддерживаемых типов приведен в документации: https://www.tensorflow.org/guide/data#dataset_structure |
prefetch
prefetch(
buffer_size, name=None
) -> 'DatasetV2'
Создает Dataset, предварительно загружающий элементы из этого набора данных.
Большинство входных конвейеров наборов данных должны завершаться вызовом prefetch. Это позволяет подготавливать последующие элементы, пока обрабатывается текущий. Это часто повышает скорость отклика и пропускную способность, но требует дополнительной памяти для хранения предварительно загруженных элементов.
Примечание: Как и другие методыDataset, предварительная загрузка работает с элементами входного набора данных. Она не различает примеры и пакеты.examples.prefetch(2)предварительно загрузит два элемента (2 примера), аexamples.batch(20).prefetch(2)— 2 элемента (2 пакета по 20 примеров каждый).
dataset = tf.data.Dataset.range(3) dataset = dataset.prefetch(2) list(dataset.as_numpy_iterator()) [0, 1, 2]
| Аргументы | |
|---|---|
buffer_size | Скалярный tf.int64 tf.Tensor, задающий максимальное количество элементов, буферизуемых при предварительной загрузке. Если используется значение tf.data.AUTOTUNE, размер буфера настраивается динамически. |
name | Необязательно. Имя преобразования tf.data. |
| Возвращает | |
|---|---|
Новый Dataset с примененным описанным выше преобразованием. |
ragged_batch
ragged_batch(
batch_size,
drop_remainder=False,
row_splits_dtype=tf.dtypes.int64,
name=None
) -> 'DatasetV2'
Объединяет последовательные элементы этого набора данных в tf.RaggedTensor.
Как и в случае с tf.data.Dataset.batch, компоненты результирующего элемента получат дополнительное внешнее измерение, которое будет равно batch_size (или N % batch_size для последнего элемента, если batch_size не делит количество входных элементов N нацело и drop_remainder имеет значение False). Если программа предполагает, что внешнее измерение пакетов одинаково, задайте аргумент drop_remainder равным True, чтобы предотвратить создание пакета меньшего размера.
В отличие от tf.data.Dataset.batch, входные элементы, объединяемые в пакеты, могут иметь разные формы:
- Если входной элемент — это
tf.Tensor, статическаяtf.TensorShapeкоторого полностью определена, он пакетируется обычным образом. - Если входной элемент — это
tf.Tensor, статическаяtf.TensorShapeкоторого содержит одну или несколько осей неизвестного размера (то естьshape[i]=None), выходные данные будут содержатьtf.RaggedTensor, разреженный по любым таким измерениям. - Если входной элемент — это
tf.RaggedTensorили объект любого другого типа, он пакетируется обычным образом.
Пример:
dataset = tf.data.Dataset.range(6) dataset = dataset.map(lambda x: tf.range(x)) dataset.element_spec.shape TensorShape([None]) dataset = dataset.ragged_batch(2) for batch in dataset: print(batch) <tf.RaggedTensor [[], [0]]> <tf.RaggedTensor [[0, 1], [0, 1, 2]]> <tf.RaggedTensor [[0, 1, 2, 3], [0, 1, 2, 3, 4]]>
| Аргументы | |
|---|---|
batch_size | Скалярный tf.int64 tf.Tensor, задающий количество последовательных элементов этого набора данных, которые нужно объединить в один пакет. |
drop_remainder | (Необязательно.) Скалярный tf.bool tf.Tensor, указывающий, следует ли отбрасывать последний пакет, если в нем меньше batch_size элементов; по умолчанию пакет меньшего размера не отбрасывается. |
row_splits_dtype | Тип данных, который следует использовать для row_splits любых новых разреженных тензоров. Тип данных row_splits у существующих элементов tf.RaggedTensor не изменяется. |
name | (Необязательно.) Строка, задающая имя операции tf.data. |
| Возвращает | |
|---|---|
Новый Dataset с примененным описанным выше преобразованием. |
random
@staticmethod
random(
seed=None, rerandomize_each_iteration=None, name=None
) -> 'DatasetV2'
Создает Dataset псевдослучайных значений.
Набор данных генерирует последовательность равномерно распределенных целочисленных значений.
Параметр rerandomize_each_iteration определяет, следует ли заново генерировать случайную последовательность чисел для каждой эпохи. По умолчанию используется значение False, при котором набор данных генерирует одну и ту же последовательность случайных чисел для каждой эпохи.
ds1 = tf.data.Dataset.random(seed=4).take(10) ds2 = tf.data.Dataset.random(seed=4).take(10) print(list(ds1.as_numpy_iterator())==list(ds2.as_numpy_iterator())) True
ds3 = tf.data.Dataset.random(seed=4).take(10) ds3_first_epoch = list(ds3.as_numpy_iterator()) ds3_second_epoch = list(ds3.as_numpy_iterator()) print(ds3_first_epoch == ds3_second_epoch) True
ds4 = tf.data.Dataset.random(
seed=4, rerandomize_each_iteration=True).take(10)
ds4_first_epoch = list(ds4.as_numpy_iterator())
ds4_second_epoch = list(ds4.as_numpy_iterator())
print(ds4_first_epoch == ds4_second_epoch)
False| Аргументы | |
|---|---|
seed | (Необязательно.) Если значение задано, набор данных создает детерминированную последовательность значений. |
rerandomize_each_iteration | (Необязательно.) Если задано значение False, набор данных генерирует одну и ту же последовательность случайных чисел для каждой эпохи. Если задано значение True, для каждой эпохи генерируется другая детерминированная последовательность случайных чисел. Если значение не указано, по умолчанию используется False. |
name | (Необязательно.) Имя операции tf.data. |
| Возвращает | |
|---|---|
Dataset | Dataset. |
range
@staticmethod
range(
*args, **kwargs
) -> 'DatasetV2'
Создает Dataset значений диапазона с заданным шагом.
list(Dataset.range(5).as_numpy_iterator()) [0, 1, 2, 3, 4] list(Dataset.range(2, 5).as_numpy_iterator()) [2, 3, 4] list(Dataset.range(1, 5, 2).as_numpy_iterator()) [1, 3] list(Dataset.range(1, 5, -2).as_numpy_iterator()) [] list(Dataset.range(5, 1).as_numpy_iterator()) [] list(Dataset.range(5, 1, -2).as_numpy_iterator()) [5, 3] list(Dataset.range(2, 5, output_type=tf.int32).as_numpy_iterator()) [2, 3, 4] list(Dataset.range(1, 5, 2, output_type=tf.float32).as_numpy_iterator()) [1.0, 3.0]
| Аргументы | |
|---|---|
*args | Использует ту же семантику, что и функция range в Python. len(args) == 1 -> start = 0, stop = args[0], step = 1. len(args) == 2 -> start = args[0], stop = args[1], step = 1. len(args) == 3 -> start = args[0], stop = args[1], step = args[2]. |
**kwargs |
|
| Возвращает | |
|---|---|
Dataset | RangeDataset. |
| Исключения | |
|---|---|
ValueError | если len(args) == 0. |
rebatch
rebatch(
batch_size, drop_remainder=False, name=None
) -> 'DatasetV2'
Создает Dataset, заново формирующий пакеты из элементов этого набора данных.
Функционально rebatch(N) эквивалентен unbatch().batch(N), но работает эффективнее, выполняя одно копирование вместо двух.
ds = tf.data.Dataset.range(6) ds = ds.batch(2) ds = ds.rebatch(3) list(ds.as_numpy_iterator()) [array([0, 1, 2]), array([3, 4, 5])]
ds = tf.data.Dataset.range(7) ds = ds.batch(4) ds = ds.rebatch(3) list(ds.as_numpy_iterator()) [array([0, 1, 2]), array([3, 4, 5]), array([6])]
ds = tf.data.Dataset.range(7) ds = ds.batch(2) ds = ds.rebatch(3, drop_remainder=True) list(ds.as_numpy_iterator()) [array([0, 1, 2]), array([3, 4, 5])]
Если аргумент batch_size является списком, rebatch циклически перебирает его, определяя размер каждого пакета.
ds = tf.data.Dataset.range(8) ds = ds.batch(4) ds = ds.rebatch([2, 1, 1]) list(ds.as_numpy_iterator()) [array([0, 1]), array([2]), array([3]), array([4, 5]), array([6]), array([7])]
| Аргументы | |
|---|---|
batch_size | Скаляр или вектор типа tf.int64, задающий размеры создаваемых пакетов. Если этот аргумент является вектором, значения циклически перебираются по кругу. |
drop_remainder | (Необязательно.) Скалярный tf.bool tf.Tensor, указывающий, следует ли отбрасывать последний пакет, если в нем меньше batch_size[cycle_index] элементов; по умолчанию пакет меньшего размера не отбрасывается. |
name | (Необязательно.) Имя операции tf.data. |
| Возвращает | |
|---|---|
Dataset со скалярными элементами dtype. |
reduce
reduce(
initial_state, reduce_func, name=None
)
Сводит входной набор данных к одному элементу.
Это преобразование последовательно вызывает reduce_func для каждого элемента входного набора данных, пока набор не будет исчерпан, накапливая информацию во внутреннем состоянии. Аргумент initial_state используется в качестве начального состояния, а конечное состояние возвращается в качестве результата.
tf.data.Dataset.range(5).reduce(np.int64(0), lambda x, _: x + 1).numpy() 5 tf.data.Dataset.range(5).reduce(np.int64(0), lambda x, y: x + y).numpy() 10
| Аргументы | |
|---|---|
initial_state | Элемент, представляющий начальное состояние преобразования. |
reduce_func | Функция, отображающая (old_state, input_element) в new_state. Она должна принимать два аргумента и возвращать новый элемент. Структура new_state должна соответствовать структуре initial_state. |
name | (Необязательно.) Имя операции tf.data. |
| Возвращает | |
|---|---|
| Элемент набора данных, соответствующий конечному состоянию преобразования. |
rejection_resample
rejection_resample(
class_func, target_dist, initial_dist=None, seed=None, name=None
) -> 'DatasetV2'
Повторно выбирает элементы, чтобы достичь целевого распределения.
Примечание: Эта реализация может отбрасывать или повторять элементы для достиженияtarget_dist. Поэтому в некоторых случаях выходнойDatasetможет быть больше входногоDataset.
initial_dist = [0.6, 0.4] n = 1000 elems = np.random.choice(len(initial_dist), size=n, p=initial_dist) dataset = tf.data.Dataset.from_tensor_slices(elems) zero, one = np.bincount(list(dataset.as_numpy_iterator())) / n
Исходя из initial_dist, zero составляет примерно 0,6, а one — примерно 0,4.
target_dist = [0.5, 0.5] dataset = dataset.rejection_resample( class_func=lambda x: x, target_dist=target_dist, initial_dist=initial_dist) dataset = dataset.map(lambda class_func_result, data: data) zero, one = np.bincount(list(dataset.as_numpy_iterator())) / n
Исходя из target_dist, zero составляет примерно 0,5, а one — примерно 0,5.
| Аргументы | |
|---|---|
class_func | Функция, отображающая элемент входного набора данных в скалярный тензор типа tf.int32. Значения должны находиться в диапазоне [0, num_classes). |
target_dist | Тензор с плавающей точкой формы [num_classes]. |
initial_dist | (Необязательно.) Тензор с плавающей точкой формы [num_classes]. Если он не задан, истинное распределение классов оценивается в реальном времени в потоковом режиме. |
seed | (Необязательно.) Целочисленное значение seed на Python для повторной выборки. |
name | (Необязательно.) Имя операции tf.data. |
| Возвращает | |
|---|---|
Новый Dataset с примененным описанным выше преобразованием. |
repeat
repeat(
count=None, name=None
) -> 'DatasetV2'
Повторяет этот набор данных, чтобы каждое исходное значение встречалось count раз.
dataset = tf.data.Dataset.from_tensor_slices([1, 2, 3]) dataset = dataset.repeat(3) list(dataset.as_numpy_iterator()) [1, 2, 3, 1, 2, 3, 1, 2, 3]
Примечание: Если входной набор данных зависит от глобального состояния (например, генератора случайных чисел) или его выходные данные недетерминированы (например, из-за вышестоящего shuffle), при разных повторах могут выдаваться разные элементы.
| Аргументы | |
|---|---|
count | (Необязательно.) Скалярный tf.int64 tf.Tensor, представляющий количество повторений набора данных. По умолчанию (если count равно None или -1) набор данных повторяется бесконечно. |
name | (Необязательно.) Имя операции tf.data. |
| Возвращает | |
|---|---|
Новый объект Dataset с примененным описанным выше преобразованием. |
sample_from_datasets
@staticmethod
sample_from_datasets(
datasets,
weights=None,
seed=None,
stop_on_empty_dataset=False,
rerandomize_each_iteration=None
) -> 'DatasetV2'
Случайным образом выбирает элементы из наборов данных в datasets.
Создает набор данных, чередуя элементы из datasets с weight[i] вероятностью выбора элемента из набора данных i. Выборка выполняется без возвращения. Например, предположим, что у нас есть 2 набора данных:
dataset1 = tf.data.Dataset.range(0, 3) dataset2 = tf.data.Dataset.range(100, 103)
Предположим, что мы выбираем элементы из этих 2 наборов данных со следующими весами:
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 |
|
save
save(
path, compression=None, shard_func=None, checkpoint_args=None
)
Сохраняет содержимое указанного набора данных.
Пример использования:
import tempfile path = os.path.join(tempfile.gettempdir(), "saved_data") # Save a dataset dataset = tf.data.Dataset.range(2) dataset.save(path) new_dataset = tf.data.Dataset.load(path) for elem in new_dataset: print(elem) tf.Tensor(0, shape=(), dtype=int64) tf.Tensor(1, shape=(), dtype=int64)
Набор данных сохраняется в нескольких файлах-«фрагментах». По умолчанию выходные данные набора данных распределяются по фрагментам циклически, но можно указать пользовательское распределение с помощью функции shard_func. Например, можно сохранить набор данных в один фрагмент следующим образом:
dataset = make_dataset()
def custom_shard_func(element):
return np.int64(0)
dataset.save(
path="/path/to/data", ..., shard_func=custom_shard_func)
Чтобы включить контрольные точки, передайте checkpoint_args в метод save следующим образом:
dataset = tf.data.Dataset.range(100)
save_dir = "..."
checkpoint_prefix = "..."
step_counter = tf.Variable(0, trainable=False)
checkpoint_args = {
"checkpoint_interval": 50,
"step_counter": step_counter,
"directory": checkpoint_prefix,
"max_to_keep": 20,
}
dataset.save(dataset, save_dir, checkpoint_args=checkpoint_args)
Примечание: Структура каталогов и формат файлов, используемые для сохранения набора данных, считаются деталями реализации и могут измениться. Поэтому наборы данных, сохраненные с помощьюtf.data.Dataset.save, следует загружать только с помощьюtf.data.Dataset.load, для которого гарантирована обратная совместимость.
| Аргументы | |
|---|---|
path | Обязательный аргумент. Каталог для сохранения набора данных. |
compression | Необязательный аргумент. Алгоритм сжатия данных при записи. Поддерживаются варианты GZIP и NONE. По умолчанию используется NONE. |
shard_func | Необязательный аргумент. Функция, управляющая сопоставлением элементов набора данных с файловыми фрагментами. Ожидается, что функция будет сопоставлять элементы входного набора данных с идентификаторами фрагментов типа int64. Если функция задана, она будет трассирована и выполнена как вычисление графа. |
checkpoint_args | Необязательные аргументы для контрольных точек, которые будут переданы в tf.train.CheckpointManager. Если checkpoint_args не указаны, контрольные точки создаваться не будут. Реализация save() внутри создает объект tf.train.Checkpoint, поэтому пользователям не следует задавать аргумент checkpoint в checkpoint_args. |
| Возвращает | |
|---|---|
| Операцию, выполнение которой сохраняет набор данных. При записи контрольных точек возвращает None. Возвращаемое значение полезно в модульных тестах. |
| Вызывает исключения | |
|---|---|
ValueError, если checkpoint передан в checkpoint_args. |
scan
scan(
initial_state, scan_func, name=None
) -> 'DatasetV2'
Преобразование, применяющее функцию сканирования к входному набору данных.
Это преобразование является версией tf.data.Dataset.map с состоянием. Помимо применения scan_func к элементам входного набора данных, scan() накапливает один или несколько тензоров состояния, начальные значения которых — initial_state.
dataset = tf.data.Dataset.range(10) initial_state = tf.constant(0, dtype=tf.int64) scan_func = lambda state, i: (state + i, state + i) dataset = dataset.scan(initial_state=initial_state, scan_func=scan_func) list(dataset.as_numpy_iterator()) [0, 1, 3, 6, 10, 15, 21, 28, 36, 45]
| Аргументы | |
|---|---|
initial_state | Вложенная структура тензоров, представляющая начальное состояние аккумулятора. |
scan_func | Функция, сопоставляющая (old_state, input_element) с (new_state, output_element). Она должна принимать два аргумента и возвращать пару вложенных структур тензоров. Структура new_state должна совпадать со структурой initial_state. |
name | (Необязательно.) Имя операции tf.data. |
| Возвращает | |
|---|---|
Новый объект Dataset с примененным описанным выше преобразованием. |
shard
shard(
num_shards, index, name=None
) -> 'DatasetV2'
Создает Dataset, включающий только 1/num_shards этого набора данных.
shard является детерминированным. Набор данных, созданный с помощью A.shard(n, i), будет содержать все элементы A, для которых индекс mod n = i.
A = tf.data.Dataset.range(10) B = A.shard(num_shards=3, index=0) list(B.as_numpy_iterator()) [0, 3, 6, 9] C = A.shard(num_shards=3, index=1) list(C.as_numpy_iterator()) [1, 4, 7] D = A.shard(num_shards=3, index=2) list(D.as_numpy_iterator()) [2, 5, 8]
Этот оператор набора данных очень полезен при распределенном обучении, поскольку позволяет каждому рабочему узлу считывать уникальное подмножество данных.
При чтении одного входного файла можно распределить элементы по фрагментам следующим образом:
d = tf.data.TFRecordDataset(input_file) d = d.shard(num_workers, worker_index) d = d.repeat(num_epochs) d = d.shuffle(shuffle_buffer_size) d = d.map(parser_fn, num_parallel_calls=num_map_threads)
Важные замечания:
- Обязательно распределите данные по фрагментам до использования операторов, меняющих порядок элементов случайным образом (например, shuffle).
- Как правило, оператор распределения по фрагментам лучше использовать на раннем этапе конвейера обработки набора данных. Например, при чтении из набора файлов TFRecord распределите данные по фрагментам до преобразования набора данных во входные образцы. Это позволяет избежать чтения каждого файла на каждом рабочем узле. Ниже приведен пример эффективной стратегии распределения по фрагментам в полном конвейере:
d = Dataset.list_files(pattern, shuffle=False)
d = d.shard(num_workers, worker_index)
d = d.repeat(num_epochs)
d = d.shuffle(shuffle_buffer_size)
d = d.interleave(tf.data.TFRecordDataset,
cycle_length=num_readers, block_length=1)
d = d.map(parser_fn, num_parallel_calls=num_map_threads)
| Аргументы | |
|---|---|
num_shards | Скалярный tf.int64 tf.Tensor, представляющий количество параллельно работающих фрагментов. |
index | Скалярный tf.int64 tf.Tensor, представляющий индекс рабочего узла. |
name | (Необязательно.) Имя операции tf.data. |
| Возвращает | |
|---|---|
Новый объект Dataset с примененным описанным выше преобразованием. |
| Вызывает исключения | |
|---|---|
InvalidArgumentError | если num_shards или index имеют недопустимые значения. Примечание: Проверка ошибок выполняется по возможности, и обнаружение ошибок при создании набора данных не гарантируется. (Например, передача тензора-заполнителя обходит раннюю проверку, и ошибка возникнет при вызове session.run.) |
shuffle
shuffle(
buffer_size, seed=None, reshuffle_each_iteration=None, name=None
) -> 'DatasetV2'
Перемешивает элементы этого набора данных в случайном порядке.
Этот набор данных заполняет буфер элементами buffer_size, а затем случайным образом выбирает элементы из этого буфера, заменяя выбранные элементы новыми. Для идеального перемешивания размер буфера должен быть не меньше полного размера набора данных.
Например, если ваш набор данных содержит 10 000 элементов, а buffer_size равно 1 000, то shuffle сначала будет выбирать случайный элемент только из первых 1 000 элементов в буфере. После выбора элемента его место в буфере займет следующий элемент (то есть элемент 1 001), сохраняя размер буфера равным 1 000 элементам.
reshuffle_each_iteration определяет, должен ли порядок перемешивания меняться для каждой эпохи. В TF 1.X идиоматическим способом создания эпох было преобразование repeat:
dataset = tf.data.Dataset.range(3) dataset = dataset.shuffle(3, reshuffle_each_iteration=True) dataset = dataset.repeat(2) # [1, 0, 2, 1, 2, 0] dataset = tf.data.Dataset.range(3) dataset = dataset.shuffle(3, reshuffle_each_iteration=False) dataset = dataset.repeat(2) # [1, 0, 2, 1, 0, 2]
В TF 2.0 объекты tf.data.Dataset являются итерируемыми объектами Python, что позволяет также создавать эпохи с помощью итерации Python:
dataset = tf.data.Dataset.range(3) dataset = dataset.shuffle(3, reshuffle_each_iteration=True) list(dataset.as_numpy_iterator()) # [1, 0, 2] list(dataset.as_numpy_iterator()) # [1, 2, 0]
dataset = tf.data.Dataset.range(3) dataset = dataset.shuffle(3, reshuffle_each_iteration=False) list(dataset.as_numpy_iterator()) # [1, 0, 2] list(dataset.as_numpy_iterator()) # [1, 0, 2]
Полное перемешивание всех данных
Чтобы перемешать весь набор данных, задайте buffer_size=dataset.cardinality(). Это эквивалентно установке значения buffer_size, равного количеству элементов в наборе данных, что обеспечивает равномерное перемешивание.
Примечание: shuffle(dataset.cardinality()) загружает весь набор данных в память для его перемешивания. Если набор данных слишком велик, это приведет к ошибке переполнения памяти (OOM), поэтому полное перемешивание следует использовать только для наборов данных, которые заведомо помещаются в память, например для наборов имен файлов или других небольших наборов данных.
dataset = tf.data.Dataset.range(20) dataset = dataset.shuffle(dataset.cardinality()) # [18, 4, 9, 2, 17, 8, 5, 10, 0, 6, 16, 3, 19, 7, 14, 11, 15, 13, 12, 1]
| Аргументы | |
|---|---|
buffer_size | Скалярный tf.int64 tf.Tensor, представляющий количество элементов этого набора данных, из которых новый набор данных будет выбирать элементы. Чтобы равномерно перемешать весь набор данных, используйте buffer_size=dataset.cardinality(). |
seed | (Необязательно.) Скалярный tf.int64 tf.Tensor, представляющий случайное начальное значение, используемое для создания распределения. Описание поведения см. в разделе tf.random.set_seed. |
reshuffle_each_iteration | (Необязательно.) Логическое значение: если оно равно true, набор данных будет псевдослучайно перемешиваться при каждом обходе. (По умолчанию равно True.) |
name | (Необязательно.) Имя операции tf.data. |
| Возвращает | |
|---|---|
Новый объект Dataset с примененным описанным выше преобразованием. |
skip
skip(
count, name=None
) -> 'DatasetV2'
Создает Dataset, пропускающий count элементов этого набора данных.
dataset = tf.data.Dataset.range(10) dataset = dataset.skip(7) list(dataset.as_numpy_iterator()) [7, 8, 9]
| Аргументы | |
|---|---|
count | Скалярный tf.int64 tf.Tensor, представляющий количество элементов этого набора данных, которые следует пропустить при создании нового набора данных. Если count больше размера этого набора данных, новый набор данных не будет содержать элементов. Если count равно -1, пропускается весь набор данных. |
name | (Необязательно.) Имя операции tf.data. |
| Возвращает | |
|---|---|
Новый объект Dataset с примененным описанным выше преобразованием. |
snapshot
snapshot(
path,
compression='AUTO',
reader_func=None,
shard_func=None,
name=None
) -> 'DatasetV2'
API для сохранения выходных данных входного набора данных.
API snapshot позволяет пользователям прозрачно сохранять на диск выходные данные конвейера предварительной обработки, а затем использовать предварительно обработанные данные в другом запуске обучения.
Этот API позволяет объединять повторяющиеся шаги предварительной обработки и повторно использовать уже обработанные данные, обменивая дисковое пространство и пропускную способность сети на высвобождение более ценных ресурсов CPU и времени вычислений на ускорителе.
Подробная документация по проектированию этой функции приведена по адресу https://github.com/tensorflow/community/blob/master/rfcs/20200107-tf-data-snapshot.md.
Пользователи могут задавать различные параметры для управления поведением snapshot, в том числе способом чтения и записи снимков, передавая пользовательские функции в параметры reader_func и shard_func.
shard_func — это заданная пользователем функция, сопоставляющая входные элементы с фрагментами снимка.
Пользователи могут задать эту функцию, чтобы управлять записью файлов снимка на диск. Ниже приведен пример возможной реализации shard_func.
dataset = ...
dataset = dataset.enumerate()
dataset = dataset.snapshot("/path/to/snapshot/dir",
shard_func=lambda x, y: x % NUM_SHARDS, ...)
dataset = dataset.map(lambda x, y: y)
reader_func — это заданная пользователем функция, принимающая один аргумент: (1) набор данных из наборов данных, каждый из которых представляет собой «раздел» элементов исходного набора данных. Кардинальность входного набора данных соответствует количеству фрагментов, указанному в shard_func (см. выше). Функция должна возвращать набор данных, состоящий из элементов исходного набора данных.
Пользователи могут задать эту функцию, чтобы управлять чтением файлов снимка с диска, в том числе степенью перемешивания и параллелизма.
Ниже приведен пример стандартной функции чтения, которую может определить пользователь. Эта функция обеспечивает как перемешивание наборов данных, так и параллельное чтение наборов данных:
def user_reader_func(datasets):
# shuffle the datasets splits
datasets = datasets.shuffle(NUM_CORES)
# read datasets in parallel and interleave their elements
return datasets.interleave(lambda x: x, num_parallel_calls=AUTOTUNE)
dataset = dataset.snapshot("/path/to/snapshot/dir",
reader_func=user_reader_func)
По умолчанию snapshot выполняет чтение параллельно в соответствии с количеством доступных в системе ядер, но не пытается перемешивать данные.
| Аргументы | |
|---|---|
path | Обязательный аргумент. Каталог для сохранения и загрузки снимка. |
compression | Необязательный аргумент. Тип сжатия для снимка, записываемого на диск. Поддерживаются варианты GZIP, SNAPPY, AUTO или None. По умолчанию используется AUTO, который пытается подобрать подходящий алгоритм сжатия для набора данных. |
reader_func | Необязательный аргумент. Функция, управляющая чтением данных из фрагментов снимка. |
shard_func | Необязательный аргумент. Функция, управляющая распределением данных по фрагментам при записи снимка. |
name | (Необязательно.) Имя операции tf.data. |
| Возвращает | |
|---|---|
Новый объект Dataset с примененным описанным выше преобразованием. |
sparse_batch
sparse_batch(
batch_size, row_shape, name=None
) -> 'DatasetV2'
Объединяет последовательные элементы в объекты tf.sparse.SparseTensor.
Подобно Dataset.padded_batch(), это преобразование объединяет несколько последовательных элементов набора данных, которые могут иметь разные формы, в один элемент. Результирующий элемент состоит из трех компонентов (indices, values и dense_shape), образующих объект tf.sparse.SparseTensor, представляющий те же данные. row_shape представляет плотную форму каждой строки в результирующем объекте tf.sparse.SparseTensor, к которой добавляется эффективный размер пакета. Например:
# NOTE: The following examples use `{ ... }` to represent the
# contents of a dataset.
a = { ['a', 'b', 'c'], ['a', 'b'], ['a', 'b', 'c', 'd'] }
a.apply(tf.data.experimental.dense_to_sparse_batch(
batch_size=2, row_shape=[6])) ==
{
([[0, 0], [0, 1], [0, 2], [1, 0], [1, 1]], # indices
['a', 'b', 'c', 'a', 'b'], # values
[2, 6]), # dense_shape
([[0, 0], [0, 1], [0, 2], [0, 3]],
['a', 'b', 'c', 'd'],
[1, 6])
}
| Аргументы | |
|---|---|
batch_size | Скалярный tf.int64 tf.Tensor, представляющий количество последовательных элементов этого набора данных, объединяемых в один пакет. |
row_shape | Объект типа tf.TensorShape или вектороподобный объект-тензор типа tf.int64, представляющий эквивалентную плотную форму строки в результирующем объекте tf.sparse.SparseTensor. Ранг каждого элемента этого набора данных должен совпадать с рангом row_shape, а размерность в каждом измерении не должна превышать row_shape. |
name | (Необязательно.) Строка, задающая имя операции tf.data. |
| Возвращает | |
|---|---|
Новый объект Dataset с примененным описанным выше преобразованием. |
take
take(
count, name=None
) -> 'DatasetV2'
Создает Dataset, содержащий не более count элементов этого набора данных.
dataset = tf.data.Dataset.range(10) dataset = dataset.take(3) list(dataset.as_numpy_iterator()) [0, 1, 2]
| Аргументы | |
|---|---|
count | Скалярный tf.int64 tf.Tensor, представляющий количество элементов этого набора данных, которые следует взять для создания нового набора данных. Если count равно -1 или count больше размера этого набора данных, новый набор данных будет содержать все его элементы. |
name | (Необязательно.) Имя операции tf.data. |
| Возвращает | |
|---|---|
Новый объект Dataset с примененным описанным выше преобразованием. |
take_while
take_while(
predicate, name=None
) -> 'DatasetV2'
Преобразование, прекращающее итерацию по набору данных на основании predicate.
dataset = tf.data.Dataset.range(10) dataset = dataset.take_while(lambda x: x < 5) list(dataset.as_numpy_iterator()) [0, 1, 2, 3, 4]
| Аргументы | |
|---|---|
predicate | Функция, сопоставляющая вложенную структуру тензоров (формы и типы которых заданы параметрами self.output_shapes и self.output_types) со скалярным тензором tf.bool. |
name | (Необязательно.) Имя операции tf.data. |
| Возвращает | |
|---|---|
Новый объект Dataset с примененным описанным выше преобразованием. |
unbatch
unbatch(
name=None
) -> 'DatasetV2'
Разбивает элементы набора данных на несколько элементов.
Например, если форма элементов набора данных — [B, a0, a1, ...], где B может различаться для каждого входного элемента, то для каждого элемента набора данных набор данных после разделения на отдельные элементы будет содержать B последовательных элементов формы [a0, a1, ...].
elements = [ [1, 2, 3], [1, 2], [1, 2, 3, 4] ] dataset = tf.data.Dataset.from_generator(lambda: elements, tf.int64) dataset = dataset.unbatch() list(dataset.as_numpy_iterator()) [1, 2, 3, 1, 2, 1, 2, 3, 4]
Примечание:unbatchкопирует данные, чтобы разделить пакетный тензор на более мелкие тензоры без пакетирования. При оптимизации производительности старайтесь избегать ненужного использованияunbatch.
| Аргументы | |
|---|---|
name | (Необязательно.) Имя операции tf.data. |
| Возвращает | |
|---|---|
Новый объект Dataset с примененным описанным выше преобразованием. |
unique
unique(
name=None
) -> 'DatasetV2'
Преобразование, удаляющее повторяющиеся элементы из Dataset.
Используйте это преобразование, чтобы создать набор данных, содержащий по одному экземпляру каждого уникального элемента входных данных. Например:
dataset = tf.data.Dataset.from_tensor_slices([1, 37, 2, 37, 2, 1]) dataset = dataset.unique() sorted(list(dataset.as_numpy_iterator())) [1, 2, 37]
Примечание: Это преобразование поддерживает только наборы данных, помещающиеся в память, с элементами типаtf.int32,tf.int64илиtf.string.
| Аргументы | |
|---|---|
name | (Необязательно.) Имя операции tf.data. |
| Возвращает | |
|---|---|
Новый объект Dataset с примененным описанным выше преобразованием. |
window
window(
size, shift=None, stride=1, drop_remainder=False, name=None
) -> 'DatasetV2'
Возвращает набор данных, состоящий из «окон».
Каждое «окно» — это набор данных, содержащий подмножество элементов входного набора данных. Эти конечные наборы данных имеют размер size (или меньший, если входных элементов недостаточно для заполнения окна и drop_remainder принимает значение False).
Например:
dataset = tf.data.Dataset.range(7).window(3) for window in dataset: print(window) <...Dataset element_spec=TensorSpec(shape=(), dtype=tf.int64, name=None)> <...Dataset element_spec=TensorSpec(shape=(), dtype=tf.int64, name=None)> <...Dataset element_spec=TensorSpec(shape=(), dtype=tf.int64, name=None)>
Поскольку окна являются наборами данных, по ним можно выполнять итерацию:
for window in dataset: print(list(window.as_numpy_iterator())) [0, 1, 2] [3, 4, 5] [6]
Сдвиг
Аргумент shift задает количество входных элементов, на которое нужно сдвигаться между началами окон. Если окна и элементы нумеруются с 0, первый элемент окна k будет элементом k * shift входного набора данных. В частности, первым элементом первого окна всегда будет первый элемент входного набора данных.
dataset = tf.data.Dataset.range(7).window(3, shift=1,
drop_remainder=True)
for window in dataset:
print(list(window.as_numpy_iterator()))
[0, 1, 2]
[1, 2, 3]
[2, 3, 4]
[3, 4, 5]
[4, 5, 6]Шаг
Аргумент stride задает шаг между входными элементами внутри окна.
dataset = tf.data.Dataset.range(7).window(3, shift=1, stride=2,
drop_remainder=True)
for window in dataset:
print(list(window.as_numpy_iterator()))
[0, 2, 4]
[1, 3, 5]
[2, 4, 6]Вложенные элементы
Когда преобразование window применяется к набору данных, элементы которого представляют собой вложенные структуры, оно создает набор данных, элементы которого имеют ту же вложенную структуру, но каждый лист заменен окном. Другими словами, вложенность применяется вне окон, а не внутри них.
Сигнатура типа:
def window(
self: Dataset[Nest[T]], ...
) -> Dataset[Nest[Dataset[T]]]
Применение window к Dataset кортежей дает кортеж окон:
dataset = tf.data.Dataset.from_tensor_slices(([1, 2, 3, 4, 5],
[6, 7, 8, 9, 10]))
dataset = dataset.window(2)
windows = next(iter(dataset))
windows
(<...Dataset element_spec=TensorSpec(shape=(), dtype=tf.int32, name=None)>,
<...Dataset element_spec=TensorSpec(shape=(), dtype=tf.int32, name=None)>)def to_numpy(ds): return list(ds.as_numpy_iterator()) for windows in dataset: print(to_numpy(windows[0]), to_numpy(windows[1])) [1, 2] [6, 7] [3, 4] [8, 9] [5] [10]
Применение window к Dataset словарей дает словарь Datasets:
dataset = tf.data.Dataset.from_tensor_slices({'a': [1, 2, 3],
'b': [4, 5, 6],
'c': [7, 8, 9]})
dataset = dataset.window(2)
def to_numpy(ds):
return list(ds.as_numpy_iterator())
for windows in dataset:
print(tf.nest.map_structure(to_numpy, windows))
{'a': [1, 2], 'b': [4, 5], 'c': [7, 8]}
{'a': [3], 'b': [6], 'c': [9]}Преобразование набора окон в плоскую структуру
Методы Dataset.flat_map и Dataset.interleave можно использовать для объединения набора окон в один набор данных.
Аргумент flat_map — это функция, которая принимает элемент из набора данных и возвращает Dataset. flat_map последовательно объединяет полученные наборы данных.
Например, чтобы преобразовать каждое окно в плотный тензор:
dataset = tf.data.Dataset.range(7).window(3, shift=1,
drop_remainder=True)
batched = dataset.flat_map(lambda x:x.batch(3))
for batch in batched:
print(batch.numpy())
[0 1 2]
[1 2 3]
[2 3 4]
[3 4 5]
[4 5 6]| Аргументы | |
|---|---|
size | Скалярный tf.int64 tf.Tensor, задающий количество элементов входного набора данных, объединяемых в окно. Значение должно быть положительным. |
shift | (Необязательно.) Скалярный tf.int64 tf.Tensor, задающий количество входных элементов, на которое окно сдвигается при каждой итерации. По умолчанию — size. Значение должно быть положительным. |
stride | (Необязательно.) Скалярный tf.int64 tf.Tensor, задающий шаг входных элементов в скользящем окне. Значение должно быть положительным. Значение по умолчанию 1 означает «сохранять каждый входной элемент». |
drop_remainder | (Необязательно.) Скалярный tf.bool tf.Tensor, задающий, следует ли отбрасывать последние окна, если их размер меньше size. |
name | (Необязательно.) Имя операции tf.data. |
| Возвращает | |
|---|---|
Новый Dataset с преобразованием, примененным, как описано выше. |
with_options
with_options(
options, name=None
) -> 'DatasetV2'
Возвращает новый tf.data.Dataset с заданными параметрами.
Параметры являются «глобальными» в том смысле, что применяются ко всему набору данных. Если параметры задаются несколько раз, они объединяются, если только для разных параметров не указаны разные значения, отличные от значений по умолчанию.
ds = tf.data.Dataset.range(5)
ds = ds.interleave(lambda x: tf.data.Dataset.range(5),
cycle_length=3,
num_parallel_calls=3)
options = tf.data.Options()
# This will make the interleave order non-deterministic.
options.deterministic = False
ds = ds.with_options(options)| Аргументы | |
|---|---|
options | tf.data.Options, задающий используемые параметры. |
name | (Необязательно.) Имя операции tf.data. |
| Возвращает | |
|---|---|
Новый Dataset с преобразованием, примененным, как описано выше. |
| Вызывает исключение | |
|---|---|
ValueError | если для параметра более одного раза задано значение, отличное от значения по умолчанию |
zip
@staticmethod
zip(
*args, datasets=None, name=None
) -> 'DatasetV2'
Создает Dataset, объединяя указанные наборы данных с помощью zip.
Семантика этого метода похожа на семантику встроенной функции zip() в Python. Основное отличие состоит в том, что аргумент datasets может представлять собой (вложенную) структуру объектов Dataset. Поддерживаемые механизмы вложения описаны здесь.
# The datasets or nested structure of datasets `*args` argument
# determines the structure of elements in the resulting dataset.
a = tf.data.Dataset.range(1, 4) # ==> [ 1, 2, 3 ]
b = tf.data.Dataset.range(4, 7) # ==> [ 4, 5, 6 ]
ds = tf.data.Dataset.zip(a, b)
list(ds.as_numpy_iterator())
[(1, 4), (2, 5), (3, 6)]
ds = tf.data.Dataset.zip(b, a)
list(ds.as_numpy_iterator())
[(4, 1), (5, 2), (6, 3)]
# The `datasets` argument may contain an arbitrary number of datasets.
c = tf.data.Dataset.range(7, 13).batch(2) # ==> [ [7, 8],
# [9, 10],
# [11, 12] ]
ds = tf.data.Dataset.zip(a, b, c)
for element in ds.as_numpy_iterator():
print(element)
(1, 4, array([7, 8]))
(2, 5, array([ 9, 10]))
(3, 6, array([11, 12]))
# The number of elements in the resulting dataset is the same as
# the size of the smallest dataset in `datasets`.
d = tf.data.Dataset.range(13, 15) # ==> [ 13, 14 ]
ds = tf.data.Dataset.zip(a, d)
list(ds.as_numpy_iterator())
[(1, 13), (2, 14)]| Аргументы | |
|---|---|
*args | Наборы данных или их вложенные структуры, которые необходимо объединить с помощью zip. Этот аргумент нельзя задавать, если задан datasets. |
datasets | (Вложенная) структура наборов данных. Этот аргумент нельзя задавать, если задан *args. Обратите внимание, что этот аргумент существует только для обратной совместимости; предпочтительно использовать *args. |
name | (Необязательно.) Имя операции tf.data. |
| Возвращает | |
|---|---|
Новый Dataset с преобразованием, примененным, как описано выше. |
__bool__
__bool__()
__iter__
__iter__()
Создает итератор для элементов этого набора данных.
Возвращаемый итератор реализует протокол итератора Python.
| Возвращает | |
|---|---|
tf.data.Iterator для элементов этого набора данных. |
| Вызывает исключение | |
|---|---|
RuntimeError | Если выполнение происходит вне tf.function и не в eager-режиме. |
__len__
__len__()
Возвращает длину набора данных, если она известна и конечна.
Этот метод требует выполнения в eager-режиме и известной конечной длины набора данных. Если длина может быть неизвестной или бесконечной либо выполнение происходит в графовом режиме, используйте вместо этого tf.data.Dataset.cardinality.
| Возвращает | |
|---|---|
| Целое число, представляющее длину набора данных. |
| Вызывает исключение | |
|---|---|
RuntimeError | Если длина набора данных неизвестна или бесконечна либо eager-выполнение не включено. |
__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/compat/v1/data/experimental/RandomDataset