tf.compat.v1.data.TFRecordDataset
Набор данных Dataset, содержащий записи из одного или нескольких файлов TFRecord.
Наследует от: Dataset, Dataset
tf.compat.v1.data.TFRecordDataset(
filenames,
compression_type=None,
buffer_size=None,
num_parallel_reads=None,
name=None
)
| Аргументы | |
|---|---|
filenames | Тензор tf.string или набор данных tf.data.Dataset, содержащий одно или несколько имен файлов. |
compression_type | (Необязательно.) Скаляр tf.string, принимающий одно из значений: "" (без сжатия), "ZLIB" или "GZIP". |
buffer_size | (Необязательно.) Скаляр tf.int64, задающий количество байтов в буфере чтения. Если конвейер ввода ограничен пропускной способностью ввода-вывода, рассмотрите возможность задать этому параметру значение в диапазоне 1–100 МБ. Если указано None, используется разумное значение по умолчанию как для локальных, так и для удаленных файловых систем. |
num_parallel_reads | (Необязательно.) Скаляр tf.int64, задающий количество файлов для параллельного чтения. Если значение больше единицы, записи из параллельно читаемых файлов выводятся в перемежающемся порядке. Если конвейер ввода ограничен пропускной способностью ввода-вывода, рассмотрите возможность задать этому параметру значение больше единицы для распараллеливания ввода-вывода. Если указано None, файлы будут читаться последовательно. |
name | (Необязательно.) Имя операции tf.data. |
| Вызывает исключения | |
|---|---|
TypeError | Если аргумент имеет тип, отличный от ожидаемого. |
ValueError | Если аргумент имеет форму, отличную от ожидаемой. |
| Атрибуты | |
|---|---|
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 группируются по длине, затем дополняются и объединяются в пакеты.
Это полезно для задач обработки последовательностей, в которых элементы имеют переменную длину. Группировка элементов похожей длины уменьшает общую долю дополнения в пакете, что повышает эффективность шага обучения.
Ниже приведен пример распределения входных данных по трем корзинам «[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 service. Тело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
)
Разбивает каждый разреженный tf.sparse.SparseTensor ранга N в этом наборе данных на строки. (Устарело)
| Аргументы | |
|---|---|
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, а eager execution отключён, значения будут встроены в граф в виде одной или нескольких операций tf.constant. Для больших наборов данных (> 1 GB) это может привести к чрезмерному расходу памяти и превышению ограничений на размер в байтах при сериализации графа. Если 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, а eager execution отключён, значения будут встроены в граф в виде одной или нескольких операций tf.constant. Для больших наборов данных (> 1 GB) это может привести к чрезмерному расходу памяти и превышению ограничений на размер в байтах при сериализации графа. Если tensors содержит один или несколько больших массивов NumPy, рассмотрите альтернативный способ, описанный в этом руководстве.
| Аргументы | |
|---|---|
tensors | «Элемент» набора данных. Поддерживаемые значения описаны здесь. |
name | (Необязательно.) Имя операции tf.data. |
| Возвращает | |
|---|---|
Dataset | Dataset. |
get_single_element
get_single_element(
name=None
)
Возвращает единственный элемент dataset.
Эта функция позволяет использовать tf.data.Dataset в stateless-выражении «тензор на входе — тензор на выходе», не создавая итератор. Это упрощает преобразование тензоров с помощью оптимизированной абстракции tf.data.Dataset, работающей поверх них.
Например, рассмотрим preprocessing_fn, которое принимает необработанные признаки и возвращает обработанный признак вместе с его меткой.
def preprocessing_fn(raw_feature):
# ... the raw_feature is preprocessed as per the use-case
return feature
raw_features = ... # input batch of BATCH_SIZE elements.
dataset = (tf.data.Dataset.from_tensor_slices(raw_features)
.map(preprocessing_fn, num_parallel_calls=BATCH_SIZE)
.batch(BATCH_SIZE))
processed_features = dataset.get_single_element()
В приведённом выше примере тензор raw_features длины BATCH_SIZE был преобразован в tf.data.Dataset. Затем каждый raw_feature был обработан с помощью preprocessing_fn, а обработанные признаки были объединены в один пакет. Итоговый dataset содержит только один элемент — пакет со всеми обработанными признаками.
Примечание: dataset должен содержать только один элемент.
Теперь вместо создания итератора для dataset и извлечения пакета признаков используется функция tf.data.get_single_element(), которая позволяет пропустить создание итератора и напрямую получить пакет признаков.
Это особенно полезно, когда преобразования тензоров представлены в виде операций tf.data.Dataset и вы хотите использовать эти преобразования при обслуживании модели.
Keras
model = ... # A pre-built or custom model
class PreprocessingModel(tf.keras.Model):
def __init__(self, model):
super().__init__(self)
self.model = model
@tf.function(input_signature=[...])
def serving_fn(self, data):
ds = tf.data.Dataset.from_tensor_slices(data)
ds = ds.map(preprocessing_fn, num_parallel_calls=BATCH_SIZE)
ds = ds.batch(batch_size=BATCH_SIZE)
return tf.argmax(self.model(ds.get_single_element()), axis=-1)
preprocessing_model = PreprocessingModel(model)
your_exported_model_dir = ... # save the model to this path.
tf.saved_model.save(preprocessing_model, your_exported_model_dir,
signatures={'serving_default': preprocessing_model.serving_fn}
)
| Аргументы | |
|---|---|
name | (Необязательно.) Имя операции tf.data. |
| Возвращает | |
|---|---|
Вложенную структуру объектов tf.Tensor, соответствующую единственному элементу dataset. |
| Вызывает исключения | |
|---|---|
InvalidArgumentError | (во время выполнения), если dataset содержит не ровно один элемент. |
group_by_window
group_by_window(
key_func, reduce_func, window_size=None, window_size_func=None, name=None
) -> 'DatasetV2'
Группирует окна элементов по ключу и сокращает их.
Это преобразование сопоставляет каждому элементу набора данных ключ с помощью key_func и группирует элементы по ключам. Затем оно применяет reduce_func не более чем к window_size_func(key) элементам с одинаковым ключом. Все окна, кроме последнего для каждого ключа, будут содержать window_size_func(key) элементов; последнее окно может быть меньше.
Можно указать либо постоянное значение window_size, либо размер окна, определяемый ключом с помощью window_size_func.
dataset = tf.data.Dataset.range(10)
window_size = 5
key_func = lambda x: x%2
reduce_func = lambda key, dataset: dataset.batch(window_size)
dataset = dataset.group_by_window(
key_func=key_func,
reduce_func=reduce_func,
window_size=window_size)
for elem in dataset.as_numpy_iterator():
print(elem)
[0 2 4 6 8]
[1 3 5 7 9]| Аргументы | |
|---|---|
key_func | Функция, преобразующая вложенную структуру тензоров (с формами и типами, определёнными в self.output_shapes и self.output_types) в скалярный тензор tf.int64. |
reduce_func | Функция, преобразующая ключ и набор данных, содержащий до window_size последовательных элементов с этим ключом, в другой набор данных. |
window_size | Скалярный tf.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 определяет его на основе доступных ресурсов CPU. Если для num_parallel_calls задано значение tf.data.AUTOTUNE, аргумент cycle_length определяет максимальный уровень параллелизма. |
block_length | (Необязательно.) Количество последовательных элементов, создаваемых для каждого входного элемента до перехода к следующему входному элементу. По умолчанию равно 1. |
num_parallel_calls | (Необязательно.) Если задано, реализация создаёт пул потоков, используемый для асинхронного и параллельного получения входных данных из элементов цикла. По умолчанию входные данные из элементов цикла получаются синхронно, без параллелизма. Если используется значение tf.data.AUTOTUNE, количество параллельных вызовов динамически определяется на основе доступных ресурсов CPU. |
deterministic | (Необязательно.) Если задан аргумент num_parallel_calls, это логическое значение (True или False) определяет порядок создания элементов преобразованием. Если задано значение False, преобразованию разрешено выдавать элементы не по порядку, чтобы повысить производительность за счёт отказа от детерминизма. Если значение не задано, поведение определяется параметром tf.data.Options.deterministic (по умолчанию — True). |
name | (Необязательно.) Имя операции tf.data. |
| Возвращает | |
|---|---|
Новый Dataset с преобразованием, применённым, как описано выше. |
list_files
@staticmethod
list_files(
file_pattern, shuffle=None, seed=None, name=None
) -> 'DatasetV2'
Набор данных, содержащий все файлы, соответствующие одному или нескольким шаблонам glob.
Аргумент file_pattern должен содержать небольшое количество шаблонов glob. Если имена файлов уже соответствуют шаблонам glob, используйте вместо этого Dataset.from_tensor_slices(filenames), поскольку повторное сопоставление каждого имени файла с шаблоном с помощью list_files может снизить производительность при работе с удалёнными системами хранения.
Примечание: По умолчанию этот метод возвращает имена файлов в случайном, недетерминированном порядке. Передайтеseedилиshuffle=False, чтобы получить результаты в детерминированном порядке.
| Пример | |
|---|---|
Предположим, в файловой системе есть следующие файлы:
Если передать "/path/to/dir/*.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 | (Необязательно.) Целочисленное значение 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_args передан checkpoint. |
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 позволяет объединять повторяющиеся этапы предварительной обработки и повторно использовать уже обработанные данные, обменивая дисковое пространство и пропускную способность сети на высвобождение более ценных ресурсов ЦП и времени вычислений на ускорителе.
Подробное описание архитектуры этой функции приведено здесь: 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) Dataset, состоящий из наборов данных, каждый из которых представляет собой «разбиение» элементов исходного набора данных. Кардинальность входного набора данных соответствует количеству сегментов, указанному в shard_func (см. выше). Функция должна возвращать Dataset с элементами исходного набора данных.
Пользователям может потребоваться задать эту функцию, чтобы управлять способом чтения файлов снимка с диска, в том числе объёмом перемешивания и степенью параллелизма.
Ниже приведён пример стандартной функции чтения, которую может определить пользователь. Эта функция обеспечивает перемешивание набора данных и параллельное чтение наборов данных:
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 может различаться для каждого входного элемента, то для каждого элемента набора данных результатом unbatch будут 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, объединяя указанные наборы данных попарно.
Семантика этого метода аналогична семантике встроенной функции Python zip(), главное отличие состоит в том, что аргумент datasets может быть (вложенной) структурой объектов Dataset. Поддерживаемые способы вложения описаны здесь.
# The datasets or nested structure of datasets `*args` argument
# determines the structure of elements in the resulting dataset.
a = tf.data.Dataset.range(1, 4) # ==> [ 1, 2, 3 ]
b = tf.data.Dataset.range(4, 7) # ==> [ 4, 5, 6 ]
ds = tf.data.Dataset.zip(a, b)
list(ds.as_numpy_iterator())
[(1, 4), (2, 5), (3, 6)]
ds = tf.data.Dataset.zip(b, a)
list(ds.as_numpy_iterator())
[(4, 1), (5, 2), (6, 3)]
# The `datasets` argument may contain an arbitrary number of datasets.
c = tf.data.Dataset.range(7, 13).batch(2) # ==> [ [7, 8],
# [9, 10],
# [11, 12] ]
ds = tf.data.Dataset.zip(a, b, c)
for element in ds.as_numpy_iterator():
print(element)
(1, 4, array([7, 8]))
(2, 5, array([ 9, 10]))
(3, 6, array([11, 12]))
# The number of elements in the resulting dataset is the same as
# the size of the smallest dataset in `datasets`.
d = tf.data.Dataset.range(13, 15) # ==> [ 13, 14 ]
ds = tf.data.Dataset.zip(a, d)
list(ds.as_numpy_iterator())
[(1, 13), (2, 14)]| Аргументы | |
|---|---|
*args | Наборы данных или вложенные структуры наборов данных для попарного объединения. Этот аргумент нельзя задавать, если задан datasets. |
datasets | (Вложенная) структура наборов данных. Этот аргумент нельзя задавать, если задан *args. Обратите внимание: он существует только для обеспечения обратной совместимости; предпочтительно использовать *args. |
name | (Необязательно.) Имя операции tf.data. |
| Возвращает | |
|---|---|
Новый Dataset с преобразованием, применённым, как описано выше. |
__bool__
__bool__()
__iter__
__iter__()
Создаёт итератор для элементов этого набора данных.
Возвращаемый итератор реализует протокол Iterator языка Python.
| Возвращает | |
|---|---|
tf.data.Iterator для элементов этого набора данных. |
| Вызывает исключение | |
|---|---|
RuntimeError | Если вызов выполняется вне tf.function и не в режиме eager execution. |
__len__
__len__()
Возвращает длину набора данных, если она известна и конечна.
Этот метод требует выполнения в режиме eager execution и известной конечной длины набора данных. Если длина может быть неизвестной или бесконечной либо программа выполняется в графовом режиме, используйте вместо него tf.data.Dataset.cardinality.
| Возвращает | |
|---|---|
| Целое число, представляющее длину набора данных. |
| Вызывает исключение | |
|---|---|
RuntimeError | Если длина набора данных неизвестна или бесконечна либо режим eager execution не включён. |
__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/TFRecordDataset