tf.compat.v1.data.experimental.CsvDataset
Набор данных, состоящий из строк одного или нескольких CSV-файлов.
Наследует от: Dataset, Dataset
tf.compat.v1.data.experimental.CsvDataset(
filenames,
record_defaults,
compression_type=None,
buffer_size=None,
header=False,
field_delim=',',
use_quote_delim=True,
na_value='',
select_cols=None,
exclude_cols=None
)
| Аргументы | |
|---|---|
filenames | Тензор tf.string, содержащий одно или несколько имен файлов. |
record_defaults | Список значений по умолчанию для полей CSV. Каждый элемент списка — это либо допустимый тип данных CSV DType (float32, float64, int32, int64, string), либо объект Tensor одного из перечисленных выше типов. По одному значению на каждый столбец данных CSV: либо скалярное значение Tensor по умолчанию для необязательного столбца, либо DType или пустое значение Tensor для обязательного столбца. Если указаны и этот параметр, и select_columns, их длины должны совпадать, а column_defaults предполагается отсортированным в порядке возрастания индексов столбцов. Если указаны и этот параметр, и 'exclude_cols', сумма длин record_defaults и exclude_cols должна равняться общему числу столбцов в CSV-файле. |
compression_type | (Необязательно.) Скаляр tf.string, принимающий одно из значений "" (без сжатия), "ZLIB" или "GZIP". По умолчанию сжатие не используется. |
buffer_size | (Необязательно.) Скаляр tf.int64, задающий количество байтов для буферизации при чтении файлов. По умолчанию — 4 МБ. |
header | (Необязательно.) Скаляр tf.bool, указывающий, содержат ли CSV-файлы заголовки, которые следует пропустить при разборе. По умолчанию — False. |
field_delim | (Необязательно.) Скаляр tf.string, содержащий символ-разделитель полей в записи. По умолчанию — ",". |
use_quote_delim | (Необязательно.) Скаляр tf.bool. Если False, двойные кавычки рассматриваются как обычные символы внутри строковых полей (игнорируется RFC 4180, раздел 2, пункт 5). По умолчанию — True. |
na_value | (Необязательно.) Скаляр tf.string, задающий значение, которое будет считаться NA/NaN. |
select_cols | (Необязательно.) Отсортированный список индексов столбцов для выбора из входных данных. Если задан, будет выполнен разбор только этого подмножества столбцов. По умолчанию выполняется разбор всех столбцов. Можно указать не более одного из параметров select_cols и exclude_cols. |
| Атрибуты | |
|---|---|
element_spec | Спецификация типов элемента этого набора данных.
dataset = tf.data.Dataset.from_tensor_slices([1, 2, 3]) dataset.element_spec TensorSpec(shape=(), dtype=tf.int32, name=None) Дополнительные сведения см. в этом руководстве. |
output_classes | Возвращает класс каждого компонента элемента этого набора данных. (устарело) |
output_shapes | Возвращает форму каждого компонента элемента этого набора данных. (устарело) |
output_types | Возвращает тип каждого компонента элемента этого набора данных. (устарело) |
Методы
apply
apply(
transformation_func
) -> 'DatasetV2'
Применяет функцию преобразования к этому набору данных.
apply позволяет объединять в цепочку пользовательские преобразования Dataset, представленные функциями, которые принимают один аргумент Dataset и возвращают преобразованный Dataset.
dataset = tf.data.Dataset.range(100) def dataset_fn(ds): return ds.filter(lambda x: x < 5) dataset = dataset.apply(dataset_fn) list(dataset.as_numpy_iterator()) [0, 1, 2, 3, 4]
| Аргументы | |
|---|---|
transformation_func | Функция, принимающая один аргумент Dataset и возвращающая Dataset. |
| Возвращает | |
|---|---|
Новый объект Dataset с примененным описанным выше преобразованием. |
as_numpy_iterator
as_numpy_iterator()
Возвращает итератор, преобразующий все элементы набора данных в объекты numpy.
Используйте as_numpy_iterator для просмотра содержимого набора данных. Чтобы увидеть формы и типы элементов, выводите элементы набора данных напрямую, а не используйте as_numpy_iterator.
dataset = tf.data.Dataset.from_tensor_slices([1, 2, 3]) for element in dataset: print(element) tf.Tensor(1, shape=(), dtype=int32) tf.Tensor(2, shape=(), dtype=int32) tf.Tensor(3, shape=(), dtype=int32)
Этот метод требует выполнения в eager-режиме, а element_spec набора данных должен содержать только компоненты TensorSpec.
dataset = tf.data.Dataset.from_tensor_slices([1, 2, 3]) for element in dataset.as_numpy_iterator(): print(element) 1 2 3
dataset = tf.data.Dataset.from_tensor_slices([1, 2, 3]) print(list(dataset.as_numpy_iterator())) [1, 2, 3]
as_numpy_iterator() сохраняет вложенную структуру элементов набора данных.
dataset = tf.data.Dataset.from_tensor_slices({'a': ([1, 2], [3, 4]),
'b': [5, 6]})
list(dataset.as_numpy_iterator()) == [{'a': (1, 3), 'b': 5},
{'a': (2, 4), 'b': 6}]
True| Возвращает | |
|---|---|
| Итерируемый объект с элементами набора данных, тензоры которых преобразованы в массивы numpy. |
| Вызывает исключения | |
|---|---|
TypeError | если элемент содержит значение, не являющееся Tensor. |
RuntimeError | если eager-выполнение не включено. |
batch
batch(
batch_size,
drop_remainder=False,
num_parallel_calls=None,
deterministic=None,
name=None
) -> 'DatasetV2'
Объединяет последовательные элементы этого набора данных в пакеты.
dataset = tf.data.Dataset.range(8) dataset = dataset.batch(3) list(dataset.as_numpy_iterator()) [array([0, 1, 2]), array([3, 4, 5]), array([6, 7])]
dataset = tf.data.Dataset.range(8) dataset = dataset.batch(3, drop_remainder=True) list(dataset.as_numpy_iterator()) [array([0, 1, 2]), array([3, 4, 5])]
Компоненты результирующего элемента получат дополнительное внешнее измерение размером batch_size (или N % batch_size для последнего элемента, если batch_size не делит число входных элементов N без остатка и drop_remainder имеет значение False). Если программа требует, чтобы внешнее измерение пакетов имело одинаковый размер, задайте для аргумента drop_remainder значение True, чтобы предотвратить создание пакета меньшего размера.
Примечание: Если программе нужны данные со статически известной формой (например, при использовании XLA), следует использоватьdrop_remainder=True. Безdrop_remainder=Trueформа выходного набора данных будет иметь неизвестное ведущее измерение из-за возможного создания последнего пакета меньшего размера.
| Аргументы | |
|---|---|
batch_size | Скалярный tf.int64 tf.Tensor, задающий число последовательных элементов этого набора данных, объединяемых в один пакет. |
drop_remainder | (Необязательно.) Скалярный tf.bool tf.Tensor, указывающий, следует ли отбрасывать последний пакет, если в нем меньше batch_size элементов; по умолчанию пакет меньшего размера не отбрасывается. |
num_parallel_calls | (Необязательно.) Скалярный tf.int64 tf.Tensor, задающий число пакетов, вычисляемых асинхронно параллельно. Если не задан, пакеты вычисляются последовательно. Если используется значение tf.data.AUTOTUNE, число параллельных вызовов динамически определяется с учетом доступных ресурсов. |
deterministic | (Необязательно.) Если задан num_parallel_calls, этот логический параметр (True или False) управляет порядком выдачи элементов преобразованием. При значении False преобразованию разрешается выдавать элементы не по порядку в обмен на производительность и отказ от детерминированности. Если параметр не задан, поведение определяется параметром tf.data.Options.deterministic (по умолчанию True). |
name | (Необязательно.) Имя операции tf.data. |
| Возвращает | |
|---|---|
Новый объект Dataset с примененным описанным выше преобразованием. |
bucket_by_sequence_length
bucket_by_sequence_length(
element_length_func,
bucket_boundaries,
bucket_batch_sizes,
padded_shapes=None,
padding_values=None,
pad_to_bucket_boundary=False,
no_padding=False,
drop_remainder=False,
name=None
) -> 'DatasetV2'
Преобразование, распределяющее элементы Dataset по корзинам в зависимости от длины.
Элементы Dataset группируются по длине, затем дополняются и объединяются в пакеты.
Это полезно для задач с последовательностями переменной длины. Группировка элементов близкой длины уменьшает общий объем дополнения в пакете и повышает эффективность шага обучения.
Ниже приведен пример распределения входных данных по 3 корзинам «[0, 3), [3, 5), [5, inf)» на основе длины последовательности с размером пакета 2.
elements = [
[0], [1, 2, 3, 4], [5, 6, 7],
[7, 8, 9, 10, 11], [13, 14, 15, 16, 19, 20], [21, 22]]
dataset = tf.data.Dataset.from_generator(
lambda: elements, tf.int64, output_shapes=[None])
dataset = dataset.bucket_by_sequence_length(
element_length_func=lambda elem: tf.shape(elem)[0],
bucket_boundaries=[3, 5],
bucket_batch_sizes=[2, 2, 2])
for elem in dataset.as_numpy_iterator():
print(elem)
[[1 2 3 4]
[5 6 7 0]]
[[ 7 8 9 10 11 0]
[13 14 15 16 19 20]]
[[ 0 0]
[21 22]]| Аргументы | |
|---|---|
element_length_func | Функция, преобразующая элемент Dataset в tf.int32; определяет длину элемента, от которой зависит выбранная корзина. |
bucket_boundaries | list<int>, верхние границы длины для корзин. |
bucket_batch_sizes | list<int>, размер пакета для каждой корзины. Длина должна быть len(bucket_boundaries) + 1. |
padded_shapes | Вложенная структура объектов tf.TensorShape, передаваемая в tf.data.Dataset.padded_batch. Если не задана, будет использоваться dataset.output_shapes, в результате чего измерения переменной длины будут дополнены до максимальной длины в каждом пакете. |
padding_values | Значения для дополнения, передаваемые в tf.data.Dataset.padded_batch. По умолчанию дополнение выполняется нулями. |
pad_to_bucket_boundary | Логическое значение: если False, измерения с неизвестным размером дополняются до максимальной длины в пакете. Если True, измерения с неизвестным размером дополняются до границы корзины минус 1 (то есть до максимальной длины в каждой корзине); вызывающий код должен гарантировать, что исходный Dataset не содержит элементов длиной больше max(bucket_boundaries). |
no_padding | bool, указывает, следует ли дополнять признаки пакета (признаки должны иметь тип tf.sparse.SparseTensor или одинаковую форму). |
drop_remainder | (Необязательно.) Скалярный tf.bool tf.Tensor, указывающий, следует ли отбрасывать последний пакет, если в нем меньше batch_size элементов; по умолчанию пакет меньшего размера не отбрасывается. |
name | (Необязательно.) Имя операции tf.data. |
| Возвращает | |
|---|---|
Новый объект Dataset с примененным описанным выше преобразованием. |
| Вызывает исключения | |
|---|---|
ValueError | если len(bucket_batch_sizes) != len(bucket_boundaries) + 1. |
cache
cache(
filename='', name=None
) -> 'DatasetV2'
Кэширует элементы этого набора данных.
При первой итерации по набору данных его элементы кэшируются в указанном файле или в памяти. В последующих итерациях используются кэшированные данные.
Примечание: Чтобы гарантировать завершение заполнения кэша, необходимо полностью пройти входной набор данных, пока не будет вызвано StopIteration. Иначе при последующих итерациях кэшированные данные могут не использоваться.
dataset = tf.data.Dataset.range(5) dataset = dataset.map(lambda x: x**2) dataset = dataset.cache() # The first time reading through the data will generate the data using # `range` and `map`. list(dataset.as_numpy_iterator()) [0, 1, 4, 9, 16] # Subsequent iterations read from the cache. list(dataset.as_numpy_iterator()) [0, 1, 4, 9, 16]
При кэшировании в файл данные сохраняются между запусками. Даже первая итерация по данным будет читать их из файла кэша. Изменение входного конвейера перед вызовом .cache() не повлияет на результат, пока файл кэша не будет удален или имя файла не будет изменено.
dataset = tf.data.Dataset.range(5)
dataset = dataset.cache("/path/to/file")
list(dataset.as_numpy_iterator())
# [0, 1, 2, 3, 4]
dataset = tf.data.Dataset.range(10)
dataset = dataset.cache("/path/to/file") # Same file!
list(dataset.as_numpy_iterator())
# [0, 1, 2, 3, 4]
Примечание:cacheбудет выдавать одни и те же элементы при каждой итерации по набору данных. Если требуется рандомизировать порядок итерации, вызовитеshuffleпосле вызоваcache.
| Аргументы | |
|---|---|
filename | Скалярный tf.string tf.Tensor, задающий имя каталога в файловой системе, используемого для кэширования элементов этого набора данных. Если имя файла не указано, набор данных кэшируется в памяти. |
name | (Необязательно.) Имя операции tf.data. |
| Возвращает | |
|---|---|
Новый объект Dataset с примененным описанным выше преобразованием. |
cardinality
cardinality()
Возвращает мощность набора данных, если она известна.
cardinality может возвращать tf.data.INFINITE_CARDINALITY, если набор данных содержит бесконечное число элементов, или tf.data.UNKNOWN_CARDINALITY, если анализ не позволяет определить число элементов набора данных (например, когда источником набора данных является файл).
dataset = tf.data.Dataset.range(42) print(dataset.cardinality().numpy()) 42 dataset = dataset.repeat() cardinality = dataset.cardinality() print((cardinality == tf.data.INFINITE_CARDINALITY).numpy()) True dataset = dataset.filter(lambda x: True) cardinality = dataset.cardinality() print((cardinality == tf.data.UNKNOWN_CARDINALITY).numpy()) True
| Возвращает | |
|---|---|
Скалярный tf.int64 Tensor, представляющий мощность набора данных. Если мощность бесконечна или неизвестна, cardinality возвращает именованные константы tf.data.INFINITE_CARDINALITY и tf.data.UNKNOWN_CARDINALITY соответственно. |
choose_from_datasets
@staticmethod
choose_from_datasets(
datasets, choice_dataset, stop_on_empty_dataset=True
) -> 'DatasetV2'
Создает набор данных, детерминированно выбирающий элементы из datasets.
Например, для следующих наборов данных:
datasets = [tf.data.Dataset.from_tensors("foo").repeat(),
tf.data.Dataset.from_tensors("bar").repeat(),
tf.data.Dataset.from_tensors("baz").repeat()]
# Define a dataset containing `[0, 1, 2, 0, 1, 2, 0, 1, 2]`.
choice_dataset = tf.data.Dataset.range(3).repeat(3)
result = tf.data.Dataset.choose_from_datasets(datasets, choice_dataset)
Элементами result будут:
"foo", "bar", "baz", "foo", "bar", "baz", "foo", "bar", "baz"
| Аргументы | |
|---|---|
datasets | Непустой список объектов tf.data.Dataset с совместимой структурой. |
choice_dataset | Объект tf.data.Dataset, содержащий скалярные тензоры tf.int64 со значениями от 0 до len(datasets) - 1. |
stop_on_empty_dataset | Если True, выбор прекращается при обнаружении пустого набора данных. Если False, пустые наборы данных пропускаются. Рекомендуется установить значение True. В противном случае выбранные элементы сначала будут соответствовать ожиданиям пользователя, но могут измениться, когда входные наборы данных опустеют. Это трудно заметить, поскольку изначально набор данных выглядит корректно. По умолчанию — True. |
| Возвращает | |
|---|---|
Новый объект Dataset с примененным описанным выше преобразованием. |
| Вызывает исключения | |
|---|---|
TypeError | Если datasets или choice_dataset имеет неправильный тип. |
ValueError | Если datasets пуст. |
concatenate
concatenate(
dataset, name=None
) -> 'DatasetV2'
Создает Dataset путем объединения указанного набора данных с этим набором данных.
a = tf.data.Dataset.range(1, 4) # ==> [ 1, 2, 3 ] b = tf.data.Dataset.range(4, 8) # ==> [ 4, 5, 6, 7 ] ds = a.concatenate(b) list(ds.as_numpy_iterator()) [1, 2, 3, 4, 5, 6, 7] # The input dataset and dataset to be concatenated should have # compatible element specs. c = tf.data.Dataset.zip((a, b)) a.concatenate(c) Traceback (most recent call last): TypeError: Two datasets to concatenate have different types <dtype: 'int64'> and (tf.int64, tf.int64) d = tf.data.Dataset.from_tensor_slices(["a", "b", "c"]) a.concatenate(d) Traceback (most recent call last): TypeError: Two datasets to concatenate have different types <dtype: 'int64'> and <dtype: 'string'>
| Аргументы | |
|---|---|
dataset | Dataset для объединения. |
name | (Необязательно.) Имя операции tf.data. |
| Возвращает | |
|---|---|
Новый объект Dataset с примененным описанным выше преобразованием. |
counter
@staticmethod
counter(
start=0,
step=1,
dtype=tf.dtypes.int64,
name=None
) -> 'DatasetV2'
Создает Dataset, который считает от start с шагом step.
В отличие от tf.data.Dataset.range, который останавливается на заданном конечном значении, tf.data.Dataset.counter бесконечно генерирует элементы.
dataset = tf.data.experimental.Counter().take(5) list(dataset.as_numpy_iterator()) [0, 1, 2, 3, 4] dataset.element_spec TensorSpec(shape=(), dtype=tf.int64, name=None) dataset = tf.data.experimental.Counter(dtype=tf.int32) dataset.element_spec TensorSpec(shape=(), dtype=tf.int32, name=None) dataset = tf.data.experimental.Counter(start=2).take(5) list(dataset.as_numpy_iterator()) [2, 3, 4, 5, 6] dataset = tf.data.experimental.Counter(start=2, step=5).take(5) list(dataset.as_numpy_iterator()) [2, 7, 12, 17, 22] dataset = tf.data.experimental.Counter(start=10, step=-1).take(5) list(dataset.as_numpy_iterator()) [10, 9, 8, 7, 6]
| Аргументы | |
|---|---|
start | (Необязательно.) Начальное значение счетчика. По умолчанию — 0. |
step | (Необязательно.) Шаг счетчика. По умолчанию — 1. |
dtype | (Необязательно.) Тип данных элементов счетчика. По умолчанию — tf.int64. |
name | (Необязательно.) Имя операции tf.data. |
| Возвращает | |
|---|---|
Dataset, содержащий скалярные элементы dtype. |
enumerate
enumerate(
start=0, name=None
) -> 'DatasetV2'
Нумерует элементы этого набора данных.
Работает аналогично enumerate в Python.
dataset = tf.data.Dataset.from_tensor_slices([1, 2, 3]) dataset = dataset.enumerate(start=5) for element in dataset.as_numpy_iterator(): print(element) (5, 1) (6, 2) (7, 3)
# The (nested) structure of the input dataset determines the # structure of elements in the resulting dataset. dataset = tf.data.Dataset.from_tensor_slices([(7, 8), (9, 10)]) dataset = dataset.enumerate() for element in dataset.as_numpy_iterator(): print(element) (0, array([7, 8], dtype=int32)) (1, array([ 9, 10], dtype=int32))
| Аргументы | |
|---|---|
start | Скалярный tf.int64 tf.Tensor, задающий начальное значение нумерации. |
name | Необязательно. Имя операций tf.data, используемых enumerate. |
| Возвращает | |
|---|---|
Новый объект Dataset с примененным описанным выше преобразованием. |
filter
filter(
predicate, name=None
) -> 'DatasetV2'
Фильтрует этот набор данных согласно predicate.
dataset = tf.data.Dataset.from_tensor_slices([1, 2, 3]) dataset = dataset.filter(lambda x: x < 3) list(dataset.as_numpy_iterator()) [1, 2] # `tf.math.equal(x, y)` is required for equality comparison def filter_fn(x): return tf.math.equal(x, 1) dataset = dataset.filter(filter_fn) list(dataset.as_numpy_iterator()) [1]
| Аргументы | |
|---|---|
predicate | Функция, преобразующая элемент набора данных в логическое значение. |
name | (Необязательно.) Имя операции tf.data. |
| Возвращает | |
|---|---|
Новый объект Dataset с примененным описанным выше преобразованием. |
filter_with_legacy_function
filter_with_legacy_function(
predicate
) -> 'DatasetV2'
Фильтрует этот набор данных согласно predicate. (устарело)
Примечание: Это обходной путь для существующих случаев использованияfilter, которые не работают с функциями V2. Настоятельно не рекомендуется применять его в новом коде; существующий код следует перевести наfilter, поскольку этот метод будет удален в V2.
| Аргументы | |
|---|---|
predicate | Функция, преобразующая (вложенную) структуру тензоров (с формами и типами, заданными параметрами self.output_shapes и self.output_types) в скалярный тензор tf.bool. |
| Возвращает | |
|---|---|
Dataset | predicate равно True для элементов этого набора данных, содержащихся в Dataset. |
fingerprint
fingerprint()
Вычисляет отпечаток этого Dataset.
Если два набора данных имеют одинаковый отпечаток, гарантируется, что они будут генерировать идентичные элементы, пока содержимое входных файлов вышестоящего уровня не изменится и данные будут генерироваться детерминированно.
Однако одинаковые значения, генерируемые двумя наборами данных, не всегда означают, что у них будет одинаковый отпечаток: это зависит от различий в структуре графа.
Иными словами, два набора данных с разными отпечатками всё ещё могут генерировать одинаковые значения.
| Возвращает | |
|---|---|
Скалярный tf.Tensor типа tf.uint64. |
flat_map
flat_map(
map_func, name=None
) -> 'DatasetV2'
Применяет map_func к элементам этого набора данных и уплощает результат.
Сигнатура типа:
def flat_map( self: Dataset[T], map_func: Callable[[T], Dataset[S]] ) -> Dataset[S]
Используйте flat_map, если хотите убедиться, что порядок элементов в наборе данных не меняется. Например, чтобы преобразовать набор данных из пакетов в набор данных, состоящий из их элементов:
dataset = tf.data.Dataset.from_tensor_slices(
[[1, 2, 3], [4, 5, 6], [7, 8, 9]])
dataset = dataset.flat_map(tf.data.Dataset.from_tensor_slices)
list(dataset.as_numpy_iterator())
[1, 2, 3, 4, 5, 6, 7, 8, 9]tf.data.Dataset.interleave() является обобщением flat_map, поскольку flat_map выдаёт тот же результат, что и tf.data.Dataset.interleave(cycle_length=1)
| Аргументы | |
|---|---|
map_func | Функция, преобразующая элемент набора данных в набор данных. |
name | (Необязательно.) Имя операции tf.data. |
| Возвращает | |
|---|---|
Новый Dataset с применённым описанным выше преобразованием. |
from_generator
@staticmethod
from_generator(
generator,
output_types=None,
output_shapes=None,
args=None,
output_signature=None,
name=None
) -> 'DatasetV2'
Создаёт Dataset, элементы которого генерируются с помощью generator. (Устаревшие аргументы)
Примечание: Текущая реализацияDataset.from_generator()используетtf.numpy_functionи наследует те же ограничения. В частности, операции, связанные с набором данных и итератором, должны выполняться на устройстве в том же процессе, что и программа Python, вызвавшаяDataset.from_generator(). В частности, использованиеfrom_generatorисключает возможность использовать сервис tf.data для масштабирования обработки наборов данных. Телоgeneratorне будет сериализовано вGraphDef, поэтому не следует использовать этот метод, если требуется сериализовать модель и восстановить её в другой среде.
Аргумент generator должен быть вызываемым объектом, возвращающим объект, который поддерживает протокол iter() (например, функцию-генератор).
Элементы, генерируемые generator, должны быть совместимы либо с заданным аргументом output_signature, либо с заданными аргументами output_types и (необязательно) output_shapes — в зависимости от того, какие из них указаны.
Рекомендуемый способ вызова from_generator — использовать аргумент output_signature. В этом случае предполагается, что результат состоит из объектов с классами, формами и типами, заданными объектами tf.TypeSpec из аргумента output_signature:
def gen():
ragged_tensor = tf.ragged.constant([[1, 2], [3]])
yield 42, ragged_tensor
dataset = tf.data.Dataset.from_generator(
gen,
output_signature=(
tf.TensorSpec(shape=(), dtype=tf.int32),
tf.RaggedTensorSpec(shape=(2, None), dtype=tf.int32)))
list(dataset.take(1))
[(<tf.Tensor: shape=(), dtype=int32, numpy=42>,
<tf.RaggedTensor [[1, 2], [3]]>)]Также существует устаревший способ вызова from_generator — с одним аргументом output_types или вместе с аргументом output_shapes. В этом случае предполагается, что результат функции состоит из объектов tf.Tensor с типами, заданными в output_types, и формами, которые либо неизвестны, либо заданы в output_shapes.
Примечание: Еслиgeneratorзависит от изменяемых глобальных переменных или другого внешнего состояния, имейте в виду, что среда выполнения может вызватьgeneratorнесколько раз (например, для поддержки повторенияDataset) и в любой момент между вызовомDataset.from_generator()и выдачей генератором первого элемента. Изменение глобальных переменных или внешнего состояния может привести к неопределённому поведению. Рекомендуем явно кэшировать любое внешнее состояние вgeneratorперед вызовомDataset.from_generator().
Примечание: Хотя параметрoutput_signatureпозволяет выдавать элементыDataset, использованиеDataset.from_generator()следует ограничить логикой, которую нельзя выразить с помощью операций tf.data. Использование операций tf.data внутри функции-генератора — антипаттерн, который может привести к постепенному увеличению потребления памяти.
| Аргументы | |
|---|---|
generator | Вызываемый объект, возвращающий объект, который поддерживает протокол iter(). Если args не указан, generator не должен принимать аргументы; в противном случае он должен принимать столько аргументов, сколько значений содержится в args. |
output_types | (Необязательно.) (Вложенная) структура объектов tf.DType, соответствующих компонентам элемента, выдаваемого generator. |
output_shapes | (Необязательно.) (Вложенная) структура объектов tf.TensorShape, соответствующих компонентам элемента, выдаваемого generator. |
args | (Необязательно.) Кортеж объектов tf.Tensor, которые будут вычислены и переданы в generator в качестве аргументов-массивов NumPy. |
output_signature | (Необязательно.) (Вложенная) структура объектов tf.TypeSpec, соответствующих компонентам элемента, выдаваемого generator. |
name | (Необязательно.) Имя операций tf.data, используемых from_generator. |
| Возвращает | |
|---|---|
Dataset | Dataset. |
from_sparse_tensor_slices
@staticmethod
from_sparse_tensor_slices(
sparse_tensor
)
Разбивает каждый разреженный 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 в выражении без состояния «тензор на входе — тензор на выходе», не создавая итератор. Благодаря этому можно легко преобразовывать тензоры с помощью оптимизированной абстракции tf.data.Dataset.
Например, рассмотрим preprocessing_fn, которая принимает необработанные признаки и возвращает обработанный признак вместе с его меткой.
def preprocessing_fn(raw_feature):
# ... the raw_feature is preprocessed as per the use-case
return feature
raw_features = ... # input batch of BATCH_SIZE elements.
dataset = (tf.data.Dataset.from_tensor_slices(raw_features)
.map(preprocessing_fn, num_parallel_calls=BATCH_SIZE)
.batch(BATCH_SIZE))
processed_features = dataset.get_single_element()
В приведённом выше примере тензор raw_features длины BATCH_SIZE был преобразован в tf.data.Dataset. Затем к каждому raw_feature применили preprocessing_fn, а обработанные признаки объединили в один пакет. Итоговый dataset содержит только один элемент — пакет со всеми обработанными признаками.
Примечание: dataset должен содержать только один элемент.
Теперь вместо создания итератора для dataset и извлечения пакета признаков используется функция tf.data.get_single_element(), которая пропускает этап создания итератора и сразу выдаёт пакет признаков.
Это может быть особенно полезно, когда преобразования тензоров выражены в виде операций tf.data.Dataset и вы хотите использовать эти преобразования при обслуживании модели.
Keras
model = ... # A pre-built or custom model
class PreprocessingModel(tf.keras.Model):
def __init__(self, model):
super().__init__(self)
self.model = model
@tf.function(input_signature=[...])
def serving_fn(self, data):
ds = tf.data.Dataset.from_tensor_slices(data)
ds = ds.map(preprocessing_fn, num_parallel_calls=BATCH_SIZE)
ds = ds.batch(batch_size=BATCH_SIZE)
return tf.argmax(self.model(ds.get_single_element()), axis=-1)
preprocessing_model = PreprocessingModel(model)
your_exported_model_dir = ... # save the model to this path.
tf.saved_model.save(preprocessing_model, your_exported_model_dir,
signatures={'serving_default': preprocessing_model.serving_fn}
)
| Аргументы | |
|---|---|
name | (Необязательно.) Имя операции tf.data. |
| Возвращает | |
|---|---|
Вложенную структуру объектов tf.Tensor, соответствующую единственному элементу dataset. |
| Вызывает исключение | |
|---|---|
InvalidArgumentError | (во время выполнения), если dataset содержит не ровно один элемент. |
group_by_window
group_by_window(
key_func, reduce_func, window_size=None, window_size_func=None, name=None
) -> 'DatasetV2'
Группирует окна элементов по ключу и сокращает их.
Это преобразование сопоставляет каждому последовательному элементу набора данных ключ с помощью key_func и группирует элементы по ключам. Затем оно применяет reduce_func не более чем к window_size_func(key) элементам с одинаковым ключом. Все окна, кроме последнего для каждого ключа, будут содержать window_size_func(key) элементов; последнее окно может быть меньше.
Можно задать постоянный window_size или размер окна, определяемый ключом с помощью window_size_func.
dataset = tf.data.Dataset.range(10)
window_size = 5
key_func = lambda x: x%2
reduce_func = lambda key, dataset: dataset.batch(window_size)
dataset = dataset.group_by_window(
key_func=key_func,
reduce_func=reduce_func,
window_size=window_size)
for elem in dataset.as_numpy_iterator():
print(elem)
[0 2 4 6 8]
[1 3 5 7 9]| Аргументы | |
|---|---|
key_func | Функция, преобразующая вложенную структуру тензоров (с формами и типами, заданными в self.output_shapes и self.output_types) в скалярный тензор tf.int64. |
reduce_func | Функция, преобразующая ключ и набор данных размером до window_size последовательных элементов с этим ключом в другой набор данных. |
window_size | Скалярный tf.Tensor типа tf.int64, задающий количество последовательных элементов с одинаковым ключом, объединяемых в один пакет, который будет передан в reduce_func. Взаимоисключающий с window_size_func. |
window_size_func | Функция, преобразующая ключ в скалярный tf.Tensor типа tf.int64, задающий количество последовательных элементов с одинаковым ключом, объединяемых в один пакет, который будет передан в reduce_func. Взаимоисключающая с window_size. |
name | (Необязательно.) Имя операции tf.data. |
| Возвращает | |
|---|---|
Новый Dataset с применённым описанным выше преобразованием. |
| Вызывает исключение | |
|---|---|
ValueError | если переданы оба аргумента из {window_size, window_size_func} или не передан ни один из них. |
ignore_errors
ignore_errors(
log_warning=False, name=None
) -> 'DatasetV2'
Отбрасывает элементы, вызывающие ошибки.
dataset = tf.data.Dataset.from_tensor_slices([1., 2., 0., 4.]) dataset = dataset.map(lambda x: tf.debugging.check_numerics(1. / x, "")) list(dataset.as_numpy_iterator()) Traceback (most recent call last): InvalidArgumentError: ... Tensor had Inf values dataset = dataset.ignore_errors() list(dataset.as_numpy_iterator()) [1.0, 0.5, 0.25]
| Аргументы | |
|---|---|
log_warning | (Необязательно.) Булево значение, указывающее, следует ли записывать игнорируемые ошибки в stderr. По умолчанию — False. |
name | (Необязательно.) Строка с именем операции tf.data. |
| Возвращает | |
|---|---|
Новый Dataset с применённым описанным выше преобразованием. |
interleave
interleave(
map_func,
cycle_length=None,
block_length=None,
num_parallel_calls=None,
deterministic=None,
name=None
) -> 'DatasetV2'
Применяет map_func к элементам этого набора данных и чередует результаты.
Сигнатура типа:
def interleave( self: Dataset[T], map_func: Callable[[T], Dataset[S]] ) -> Dataset[S]
Например, можно использовать Dataset.interleave() для параллельной обработки множества входных файлов:
# Preprocess 4 files concurrently, and interleave blocks of 16 records
# from each file.
filenames = ["/var/data/file1.txt", "/var/data/file2.txt",
"/var/data/file3.txt", "/var/data/file4.txt"]
dataset = tf.data.Dataset.from_tensor_slices(filenames)
def parse_fn(filename):
return tf.data.Dataset.range(10)
dataset = dataset.interleave(lambda x:
tf.data.TextLineDataset(x).map(parse_fn, num_parallel_calls=1),
cycle_length=4, block_length=16)Аргументы cycle_length и block_length управляют порядком выдачи элементов. cycle_length определяет количество одновременно обрабатываемых входных элементов. Если задать cycle_length равным 1, это преобразование будет обрабатывать по одному входному элементу за раз и выдаст те же результаты, что и tf.data.Dataset.flat_map. В общем случае это преобразование применяет map_func к cycle_length входным элементам, открывает итераторы для возвращённых объектов Dataset и циклически извлекает из каждого итератора block_length последовательных элементов, используя следующий входной элемент при достижении конца итератора.
Например:
dataset = Dataset.range(1, 6) # ==> [ 1, 2, 3, 4, 5 ]
# NOTE: New lines indicate "block" boundaries.
dataset = dataset.interleave(
lambda x: Dataset.from_tensors(x).repeat(6),
cycle_length=2, block_length=4)
list(dataset.as_numpy_iterator())
[1, 1, 1, 1,
2, 2, 2, 2,
1, 1,
2, 2,
3, 3, 3, 3,
4, 4, 4, 4,
3, 3,
4, 4,
5, 5, 5, 5,
5, 5]Примечание: Порядок элементов, выдаваемых этим преобразованием, детерминирован, еслиmap_funcявляется чистой функцией иdeterministic=True. Еслиmap_funcсодержит операции с состоянием, порядок доступа к этому состоянию не определён.
Часто производительность можно повысить, задав num_parallel_calls, чтобы interleave извлекал элементы с помощью нескольких потоков. Если детерминированность не требуется, производительность также можно повысить, задав deterministic=False.
filenames = ["/var/data/file1.txt", "/var/data/file2.txt",
"/var/data/file3.txt", "/var/data/file4.txt"]
dataset = tf.data.Dataset.from_tensor_slices(filenames)
dataset = dataset.interleave(lambda x: tf.data.TFRecordDataset(x),
cycle_length=4, num_parallel_calls=tf.data.AUTOTUNE,
deterministic=False)| Аргументы | |
|---|---|
map_func | Функция, принимающая элемент набора данных и возвращающая tf.data.Dataset. |
cycle_length | (Необязательно.) Количество входных элементов, обрабатываемых параллельно. Если значение не задано, среда выполнения tf.data определяет его на основе доступных ресурсов 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), поскольку повторное применение glob к каждому имени файла с помощью list_files может снизить производительность при работе с удалёнными системами хранения.
Примечание: По умолчанию этот метод возвращает имена файлов в недетерминированном случайном порядке. Передайтеseedилиshuffle=False, чтобы получить результат в детерминированном порядке.
| Пример | |
|---|---|
Допустим, в файловой системе есть следующие файлы:
Если передать в качестве каталога "/path/to/dir/*.py", набор данных выдаст:
|
| Аргументы | |
|---|---|
file_pattern | Строка, список строк или tf.Tensor строкового типа (скаляр или вектор), задающий шаблон(ы) glob для имени файла (то есть шаблон(ы) подстановочных знаков оболочки), по которому будут отбираться файлы. |
shuffle | (Необязательно.) Если задано True, имена файлов будут перемешаны случайным образом. По умолчанию — True. |
seed | (Необязательно.) Скалярный tf.Tensor типа tf.int64, задающий случайное начальное значение для создания распределения. Описание поведения см. в разделе tf.random.set_seed. |
name | Необязательно. Имя операций tf.data, используемых list_files. |
| Возвращает | |
|---|---|
Dataset | Dataset строк с именами файлов. |
load
@staticmethod
load(
path, element_spec=None, compression=None, reader_func=None
) -> 'DatasetV2'
Загружает ранее сохранённый набор данных.
Пример использования:
import tempfile path = os.path.join(tempfile.gettempdir(), "saved_data") # Save a dataset dataset = tf.data.Dataset.range(2) tf.data.Dataset.save(dataset, path) new_dataset = tf.data.Dataset.load(path) for elem in new_dataset: print(elem) tf.Tensor(0, shape=(), dtype=int64) tf.Tensor(1, shape=(), dtype=int64)
Если при сохранении набора данных использовалось разбиение на шарды по умолчанию, порядок элементов сохранённого набора данных будет сохранён и при загрузке.
Аргумент reader_func позволяет задать порядок загрузки элементов из отдельных шардов. Ожидается, что reader_func принимает один аргумент — набор наборов данных, каждый из которых содержит элементы одного из шардов, — и возвращает набор элементов. Например, при загрузке порядок шардов можно перемешать следующим образом:
def custom_reader_func(datasets):
datasets = datasets.shuffle(NUM_SHARDS)
return datasets.interleave(lambda x: x, num_parallel_calls=AUTOTUNE)
dataset = tf.data.Dataset.load(
path="/path/to/data", ..., reader_func=custom_reader_func)
| Аргументы | |
|---|---|
path | Обязательный. Путь к ранее сохранённому набору данных. |
element_spec | Необязательный. Вложенная структура объектов tf.TypeSpec, соответствующая структуре элемента сохранённого набора данных и задающая тип отдельных компонентов элемента. Если не указана, используется вложенная структура tf.TypeSpec, сохранённая вместе с набором данных. Обратите внимание: этот аргумент обязателен в режиме графа. |
compression | Необязательный. Алгоритм распаковки данных при чтении. Поддерживаются параметры GZIP и NONE. По умолчанию — NONE. |
reader_func | Необязательный. Функция, управляющая чтением данных из шардов. Если она задана, функция будет трассирована и выполнена как вычисление графа. |
| Возвращает | |
|---|---|
Экземпляр tf.data.Dataset. |
| Исключения | |
|---|---|
FileNotFoundError | Если element_spec не указано и сохраненную вложенную структуру tf.TypeSpec не удается найти в сохраненном наборе данных. |
ValueError | Если element_spec не указано и метод выполняется в режиме графов. |
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]
Создает итератор для элементов этого набора данных. (устарел)
Примечание: Возвращенный итератор будет инициализирован автоматически. Итератор типа «one-shot» в настоящее время не поддерживает повторную инициализацию. Для этого см. 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, число параллельных вызовов задается динамически в зависимости от доступных ресурсов CPU. |
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, число параллельных вызовов задается динамически в зависимости от доступных ресурсов CPU. |
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, метод prefetch работает с элементами входного набора данных. Он не различает примеры и пакеты.examples.prefetch(2)предварительно загрузит два элемента (2 примера), аexamples.batch(20).prefetch(2)предварительно загрузит 2 элемента (2 пакета по 20 примеров в каждом).
dataset = tf.data.Dataset.range(3) dataset = dataset.prefetch(2) list(dataset.as_numpy_iterator()) [0, 1, 2]
| Аргументы | |
|---|---|
buffer_size | Скалярный объект tf.int64 типа tf.Tensor, задающий максимальное количество элементов, буферизуемых при предварительной загрузке. Если используется значение tf.data.AUTOTUNE, размер буфера настраивается динамически. |
name | Необязательно. Имя преобразования tf.data. |
| Возвращает | |
|---|---|
Новый объект Dataset с примененным описанным выше преобразованием. |
ragged_batch
ragged_batch(
batch_size,
drop_remainder=False,
row_splits_dtype=tf.dtypes.int64,
name=None
) -> 'DatasetV2'
Объединяет последовательные элементы этого набора данных в объекты tf.RaggedTensor.
Как и в случае с tf.data.Dataset.batch, компоненты результирующего элемента получат дополнительное внешнее измерение, размер которого будет равен batch_size (или N % batch_size для последнего элемента, если batch_size не делит количество входных элементов N без остатка и drop_remainder равно False). Если ваша программа предполагает одинаковый размер внешнего измерения во всех пакетах, задайте аргумент drop_remainder равным True, чтобы предотвратить создание меньшего пакета.
В отличие от tf.data.Dataset.batch, входные элементы, объединяемые в пакет, могут иметь разные формы:
- Если входной элемент — это объект
tf.Tensor, статическаяtf.TensorShapeкоторого полностью определена, он пакетируется обычным способом. - Если входной элемент — это объект
tf.Tensor, статическаяtf.TensorShapeкоторого содержит одну или несколько осей с неизвестным размером (то естьshape[i]=None), выходные данные будут содержать объектtf.RaggedTensorс переменной структурой по таким измерениям. - Если входной элемент — это объект
tf.RaggedTensorили объект любого другого типа, он пакетируется обычным способом.
Пример:
dataset = tf.data.Dataset.range(6) dataset = dataset.map(lambda x: tf.range(x)) dataset.element_spec.shape TensorShape([None]) dataset = dataset.ragged_batch(2) for batch in dataset: print(batch) <tf.RaggedTensor [[], [0]]> <tf.RaggedTensor [[0, 1], [0, 1, 2]]> <tf.RaggedTensor [[0, 1, 2, 3], [0, 1, 2, 3, 4]]>
| Аргументы | |
|---|---|
batch_size | Скалярный объект tf.int64 типа tf.Tensor, задающий количество последовательных элементов этого набора данных, объединяемых в один пакет. |
drop_remainder | (Необязательно.) Скалярный объект tf.bool типа tf.Tensor, указывающий, следует ли отбрасывать последний пакет, если в нем меньше batch_size элементов; по умолчанию меньший пакет не отбрасывается. |
row_splits_dtype | Тип данных, используемый для row_splits любых новых тензоров с переменной структурой. Тип row_splits существующих элементов tf.RaggedTensor не изменяется. |
name | (Необязательно.) Строка с именем операции tf.data. |
| Возвращает | |
|---|---|
Новый объект Dataset с примененным описанным выше преобразованием. |
random
@staticmethod
random(
seed=None, rerandomize_each_iteration=None, name=None
) -> 'DatasetV2'
Создает Dataset псевдослучайных значений.
Набор данных генерирует последовательность равномерно распределенных целочисленных значений.
Параметр rerandomize_each_iteration определяет, следует ли генерировать новую последовательность случайных чисел для каждой эпохи. По умолчанию задано значение False, поэтому для каждой эпохи набор данных генерирует одну и ту же последовательность случайных чисел.
ds1 = tf.data.Dataset.random(seed=4).take(10) ds2 = tf.data.Dataset.random(seed=4).take(10) print(list(ds1.as_numpy_iterator())==list(ds2.as_numpy_iterator())) True
ds3 = tf.data.Dataset.random(seed=4).take(10) ds3_first_epoch = list(ds3.as_numpy_iterator()) ds3_second_epoch = list(ds3.as_numpy_iterator()) print(ds3_first_epoch == ds3_second_epoch) True
ds4 = tf.data.Dataset.random(
seed=4, rerandomize_each_iteration=True).take(10)
ds4_first_epoch = list(ds4.as_numpy_iterator())
ds4_second_epoch = list(ds4.as_numpy_iterator())
print(ds4_first_epoch == ds4_second_epoch)
False| Аргументы | |
|---|---|
seed | (Необязательно.) Если задано, набор данных генерирует детерминированную последовательность значений. |
rerandomize_each_iteration | (Необязательно.) Если задано значение False, набор данных генерирует одну и ту же последовательность случайных чисел для каждой эпохи. Если задано значение True, для каждой эпохи генерируется своя детерминированная последовательность случайных чисел. Если параметр не указан, по умолчанию используется значение False. |
name | (Необязательно.) Имя операции tf.data. |
| Возвращает | |
|---|---|
Dataset | Объект Dataset. |
range
@staticmethod
range(
*args, **kwargs
) -> 'DatasetV2'
Создает Dataset значений диапазона с заданным шагом.
list(Dataset.range(5).as_numpy_iterator()) [0, 1, 2, 3, 4] list(Dataset.range(2, 5).as_numpy_iterator()) [2, 3, 4] list(Dataset.range(1, 5, 2).as_numpy_iterator()) [1, 3] list(Dataset.range(1, 5, -2).as_numpy_iterator()) [] list(Dataset.range(5, 1).as_numpy_iterator()) [] list(Dataset.range(5, 1, -2).as_numpy_iterator()) [5, 3] list(Dataset.range(2, 5, output_type=tf.int32).as_numpy_iterator()) [2, 3, 4] list(Dataset.range(1, 5, 2, output_type=tf.float32).as_numpy_iterator()) [1.0, 3.0]
| Аргументы | |
|---|---|
*args | Семантика соответствует функции range в Python. len(args) == 1 -> start = 0, stop = args[0], step = 1. len(args) == 2 -> start = args[0], stop = args[1], step = 1. len(args) == 3 -> start = args[0], stop = args[1], step = args[2]. |
**kwargs |
|
| Возвращает | |
|---|---|
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)
Предположим, что мы выбираем элементы из этих двух наборов данных со следующими весами:
sample_dataset = tf.data.Dataset.sample_from_datasets(
[dataset1, dataset2], weights=[0.5, 0.5])
Один из возможных вариантов элементов в sample_dataset:
print(list(sample_dataset.as_numpy_iterator())) # [100, 0, 1, 101, 2, 102]
| Аргументы | |
|---|---|
datasets | Непустой список объектов tf.data.Dataset с совместимой структурой. |
weights | (Необязательно.) Список или тензор из len(datasets) значений с плавающей точкой, где weights[i] задаёт вероятность выбора элемента из datasets[i], либо объект tf.data.Dataset, каждый элемент которого представляет собой такой список. По умолчанию используется равномерное распределение по datasets. |
seed | (Необязательно.) Скалярный тензор tf.int64 типа tf.Tensor, задающий начальное значение генератора случайных чисел, используемое для создания распределения. Описание поведения см. в разделе tf.random.set_seed. |
stop_on_empty_dataset | Если True, выборка прекращается при обнаружении пустого набора данных. Если False, выборка продолжается, пропуская пустые наборы данных. Рекомендуется задать значение True. В противном случае распределение выборок изначально будет соответствовать заданному пользователем, но может измениться, когда входные наборы данных опустеют. Это может быть трудно заметить, поскольку сначала набор данных выглядит корректно. Для обратной совместимости по умолчанию используется False. |
rerandomize_each_iteration | Необязательный bool. Логический аргумент определяет, будет ли последовательность случайных чисел, используемая для выбора набора данных, генерироваться заново в каждой эпохе. То есть он определяет, будут ли наборы данных выбираться в одинаковом порядке в разных эпохах (поведение по умолчанию). |
| Возвращает | |
|---|---|
Набор данных, который случайным образом чередует элементы из datasets согласно weights, если оно задано, или с равномерной вероятностью в противном случае. |
| Вызывает исключения | |
|---|---|
TypeError | Если аргументы datasets или weights имеют неверный тип. |
ValueError |
|
save
save(
path, compression=None, shard_func=None, checkpoint_args=None
)
Сохраняет содержимое заданного набора данных.
Пример использования:
import tempfile path = os.path.join(tempfile.gettempdir(), "saved_data") # Save a dataset dataset = tf.data.Dataset.range(2) dataset.save(path) new_dataset = tf.data.Dataset.load(path) for elem in new_dataset: print(elem) tf.Tensor(0, shape=(), dtype=int64) tf.Tensor(1, shape=(), dtype=int64)
Сохранённый набор данных записывается в несколько файловых «сегментов». По умолчанию выходные данные набора данных делятся на сегменты по принципу кругового распределения, однако можно задать пользовательское распределение сегментов с помощью функции shard_func. Например, набор данных можно сохранить в одном сегменте следующим образом:
dataset = make_dataset()
def custom_shard_func(element):
return np.int64(0)
dataset.save(
path="/path/to/data", ..., shard_func=custom_shard_func)
Чтобы включить контрольные точки, передайте checkpoint_args методу save следующим образом:
dataset = tf.data.Dataset.range(100)
save_dir = "..."
checkpoint_prefix = "..."
step_counter = tf.Variable(0, trainable=False)
checkpoint_args = {
"checkpoint_interval": 50,
"step_counter": step_counter,
"directory": checkpoint_prefix,
"max_to_keep": 20,
}
dataset.save(dataset, save_dir, checkpoint_args=checkpoint_args)
Примечание: Структура каталогов и формат файлов, используемые для сохранения набора данных, являются деталями реализации и могут измениться. Поэтому наборы данных, сохранённые с помощьюtf.data.Dataset.save, следует загружать только с помощьюtf.data.Dataset.load, для которого гарантирована обратная совместимость.
| Аргументы | |
|---|---|
path | Обязательный аргумент. Каталог для сохранения набора данных. |
compression | Необязательный аргумент. Алгоритм сжатия данных при записи. Поддерживаются варианты GZIP и NONE. По умолчанию используется NONE. |
shard_func | Необязательный аргумент. Функция, задающая распределение элементов набора данных по файловым сегментам. Функция должна сопоставлять элементы входного набора данных идентификаторам сегментов int64. Если функция задана, она будет трассирована и выполнена как вычисление графа. |
checkpoint_args | Необязательные аргументы для контрольных точек, передаваемые в tf.train.CheckpointManager. Если checkpoint_args не заданы, контрольные точки создаваться не будут. Реализация save() внутри создаёт объект tf.train.Checkpoint, поэтому пользователям не следует задавать аргумент checkpoint в checkpoint_args. |
| Возвращает | |
|---|---|
| Операцию, выполнение которой сохраняет данные. При записи контрольных точек возвращает None. Возвращаемое значение полезно для модульных тестов. |
| Вызывает исключения | |
|---|---|
ValueError, если checkpoint передан в checkpoint_args. |
scan
scan(
initial_state, scan_func, name=None
) -> 'DatasetV2'
Преобразование, выполняющее сканирование входного набора данных с помощью функции.
Это преобразование является версией tf.data.Dataset.map с сохранением состояния. Помимо применения scan_func к элементам входного набора данных, scan() накапливает один или несколько тензоров состояния, начальные значения которых равны initial_state.
dataset = tf.data.Dataset.range(10) initial_state = tf.constant(0, dtype=tf.int64) scan_func = lambda state, i: (state + i, state + i) dataset = dataset.scan(initial_state=initial_state, scan_func=scan_func) list(dataset.as_numpy_iterator()) [0, 1, 3, 6, 10, 15, 21, 28, 36, 45]
| Аргументы | |
|---|---|
initial_state | Вложенная структура тензоров, представляющая исходное состояние аккумулятора. |
scan_func | Функция, отображающая (old_state, input_element) в (new_state, output_element). Она должна принимать два аргумента и возвращать пару вложенных структур тензоров. Структура new_state должна совпадать со структурой initial_state. |
name | (Необязательно.) Имя операции tf.data. |
| Возвращает | |
|---|---|
Новый Dataset с преобразованием, применённым, как описано выше. |
shard
shard(
num_shards, index, name=None
) -> 'DatasetV2'
Создаёт Dataset, содержащий только 1/num_shards элементов этого набора данных.
shard является детерминированным. Набор данных, созданный A.shard(n, i), будет содержать все элементы A, для которых индекс mod n = i.
A = tf.data.Dataset.range(10) B = A.shard(num_shards=3, index=0) list(B.as_numpy_iterator()) [0, 3, 6, 9] C = A.shard(num_shards=3, index=1) list(C.as_numpy_iterator()) [1, 4, 7] D = A.shard(num_shards=3, index=2) list(D.as_numpy_iterator()) [2, 5, 8]
Этот оператор набора данных очень полезен при распределённом обучении, поскольку позволяет каждому рабочему узлу считывать уникальное подмножество данных.
При чтении одного входного файла элементы можно распределить по сегментам следующим образом:
d = tf.data.TFRecordDataset(input_file) d = d.shard(num_workers, worker_index) d = d.repeat(num_epochs) d = d.shuffle(shuffle_buffer_size) d = d.map(parser_fn, num_parallel_calls=num_map_threads)
Важные замечания:
- Обязательно выполняйте распределение по сегментам до использования любого оператора рандомизации (например, перемешивания).
- Как правило, оператор распределения по сегментам лучше размещать в начале конвейера обработки набора данных. Например, при чтении набора файлов TFRecord распределяйте данные по сегментам до преобразования набора данных во входные образцы. Это позволяет не считывать каждый файл на каждом рабочем узле. Ниже приведён пример эффективной стратегии распределения по сегментам в полном конвейере:
d = Dataset.list_files(pattern, shuffle=False)
d = d.shard(num_workers, worker_index)
d = d.repeat(num_epochs)
d = d.shuffle(shuffle_buffer_size)
d = d.interleave(tf.data.TFRecordDataset,
cycle_length=num_readers, block_length=1)
d = d.map(parser_fn, num_parallel_calls=num_map_threads)
| Аргументы | |
|---|---|
num_shards | Скалярный тензор tf.int64 типа tf.Tensor, задающий количество параллельно работающих сегментов. |
index | Скалярный тензор tf.int64 типа tf.Tensor, задающий индекс рабочего узла. |
name | (Необязательно.) Имя операции tf.data. |
| Возвращает | |
|---|---|
Новый Dataset с преобразованием, применённым, как описано выше. |
| Вызывает исключения | |
|---|---|
InvalidArgumentError | если num_shards или index имеют недопустимые значения. Примечание: проверка ошибок выполняется по возможности, и нет гарантии, что ошибки будут обнаружены при создании набора данных. (Например, передача тензора-заполнителя обходит раннюю проверку и вместо этого приводит к ошибке при вызове session.run.) |
shuffle
shuffle(
buffer_size, seed=None, reshuffle_each_iteration=None, name=None
) -> 'DatasetV2'
Случайным образом перемешивает элементы этого набора данных.
Этот оператор заполняет буфер из buffer_size элементов, а затем случайным образом выбирает из него элементы, заменяя выбранные элементы новыми. Для идеального перемешивания размер буфера должен быть не меньше полного размера набора данных.
Например, если набор данных содержит 10 000 элементов, но для buffer_size задано значение 1 000, то сначала shuffle выберет случайный элемент только из первых 1 000 элементов в буфере. После выбора элемента его место в буфере займёт следующий элемент (то есть элемент 1 001), поддерживая размер буфера в 1 000 элементов.
Параметр reshuffle_each_iteration определяет, должен ли порядок перемешивания меняться в каждой эпохе. В TF 1.X идиоматическим способом создания эпох было преобразование repeat:
dataset = tf.data.Dataset.range(3) dataset = dataset.shuffle(3, reshuffle_each_iteration=True) dataset = dataset.repeat(2) # [1, 0, 2, 1, 2, 0] dataset = tf.data.Dataset.range(3) dataset = dataset.shuffle(3, reshuffle_each_iteration=False) dataset = dataset.repeat(2) # [1, 0, 2, 1, 0, 2]
В TF 2.0 объекты tf.data.Dataset являются итерируемыми объектами Python, поэтому эпохи можно также создавать с помощью итерации Python:
dataset = tf.data.Dataset.range(3) dataset = dataset.shuffle(3, reshuffle_each_iteration=True) list(dataset.as_numpy_iterator()) # [1, 0, 2] list(dataset.as_numpy_iterator()) # [1, 2, 0]
dataset = tf.data.Dataset.range(3) dataset = dataset.shuffle(3, reshuffle_each_iteration=False) list(dataset.as_numpy_iterator()) # [1, 0, 2] list(dataset.as_numpy_iterator()) # [1, 0, 2]
Полное перемешивание всех данных
Чтобы перемешать весь набор данных, задайте buffer_size=dataset.cardinality(). Это эквивалентно установке buffer_size в значение, равное количеству элементов набора данных, что обеспечивает равномерное перемешивание.
Примечание: shuffle(dataset.cardinality()) загружает весь набор данных в память для перемешивания. Если набор данных слишком велик, это приведёт к ошибке нехватки памяти (OOM), поэтому полное перемешивание следует использовать только для наборов данных, которые заведомо помещаются в память, например наборов имён файлов или других небольших наборов данных.
dataset = tf.data.Dataset.range(20) dataset = dataset.shuffle(dataset.cardinality()) # [18, 4, 9, 2, 17, 8, 5, 10, 0, 6, 16, 3, 19, 7, 14, 11, 15, 13, 12, 1]
| Аргументы | |
|---|---|
buffer_size | Скалярный тензор tf.int64 типа tf.Tensor, задающий количество элементов этого набора данных, из которых будет выполняться выборка для нового набора данных. Чтобы равномерно перемешать весь набор данных, используйте buffer_size=dataset.cardinality(). |
seed | (Необязательно.) Скалярный тензор tf.int64 типа tf.Tensor, задающий начальное значение генератора случайных чисел, используемое для создания распределения. Описание поведения см. в разделе tf.random.set_seed. |
reshuffle_each_iteration | (Необязательно.) Логическое значение, указывающее, следует ли псевдослучайно перемешивать набор данных при каждой итерации. (По умолчанию равно True.) |
name | (Необязательно.) Имя операции tf.data. |
| Возвращает | |
|---|---|
Новый Dataset с преобразованием, применённым, как описано выше. |
skip
skip(
count, name=None
) -> 'DatasetV2'
Создаёт Dataset, пропускающий count элементов этого набора данных.
dataset = tf.data.Dataset.range(10) dataset = dataset.skip(7) list(dataset.as_numpy_iterator()) [7, 8, 9]
| Аргументы | |
|---|---|
count | Скалярный тензор tf.int64 типа tf.Tensor, задающий количество элементов этого набора данных, которые следует пропустить при формировании нового набора данных. Если count превышает размер этого набора данных, новый набор данных не будет содержать элементов. Если count равно -1, пропускается весь набор данных. |
name | (Необязательно.) Имя операции tf.data. |
| Возвращает | |
|---|---|
Новый Dataset с преобразованием, применённым, как описано выше. |
snapshot
snapshot(
path,
compression='AUTO',
reader_func=None,
shard_func=None,
name=None
) -> 'DatasetV2'
API для сохранения результатов обработки входного набора данных.
API snapshot позволяет прозрачно сохранять на диск результаты конвейера предварительной обработки, а затем использовать предварительно обработанные данные при другом запуске обучения.
Этот API позволяет объединять повторяющиеся этапы предварительной обработки и повторно использовать уже обработанные данные, обменивая дисковое пространство и пропускную способность сети на высвобождение более ценных ресурсов CPU и времени вычислений на ускорителе.
Подробная документация по проектированию этой функции доступна по адресу https://github.com/tensorflow/community/blob/master/rfcs/20200107-tf-data-snapshot.md.
Пользователи могут задавать различные параметры управления поведением snapshot, в том числе способом чтения и записи снимков, передавая пользовательские функции в параметры reader_func и shard_func.
shard_func — это функция, заданная пользователем, которая сопоставляет входные элементы сегментам снимка.
Эту функцию можно задать, чтобы управлять записью файлов снимка на диск. Ниже приведён пример возможной реализации shard_func.
dataset = ...
dataset = dataset.enumerate()
dataset = dataset.snapshot("/path/to/snapshot/dir",
shard_func=lambda x, y: x % NUM_SHARDS, ...)
dataset = dataset.map(lambda x, y: y)
reader_func — это функция, заданная пользователем, которая принимает один аргумент: (1) Dataset, состоящий из наборов 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 может различаться для каждого входного элемента, то для каждого элемента набора данных результат разбиения на отдельные элементы будет содержать B последовательных элементов формы [a0, a1, ...].
elements = [ [1, 2, 3], [1, 2], [1, 2, 3, 4] ] dataset = tf.data.Dataset.from_generator(lambda: elements, tf.int64) dataset = dataset.unbatch() list(dataset.as_numpy_iterator()) [1, 2, 3, 1, 2, 1, 2, 3, 4]
Примечание:unbatchтребует копирования данных для разделения пакетного тензора на более мелкие тензоры, не объединённые в пакет. При оптимизации производительности старайтесь избегать ненужного использованияunbatch.
| Аргументы | |
|---|---|
name | (Необязательно.) Имя операции tf.data. |
| Возвращает | |
|---|---|
Новый Dataset с преобразованием, применённым, как описано выше. |
unique
unique(
name=None
) -> 'DatasetV2'
Преобразование, удаляющее дублирующиеся элементы из Dataset.
Используйте это преобразование, чтобы создать набор данных, содержащий по одному экземпляру каждого уникального элемента входных данных. Например:
dataset = tf.data.Dataset.from_tensor_slices([1, 37, 2, 37, 2, 1]) dataset = dataset.unique() sorted(list(dataset.as_numpy_iterator())) [1, 2, 37]
Примечание: Это преобразование поддерживает только наборы данных, которые помещаются в память и содержат элементы типаtf.int32,tf.int64илиtf.string.
| Аргументы | |
|---|---|
name | (Необязательно.) Имя операции tf.data. |
| Возвращает | |
|---|---|
Новый Dataset с преобразованием, применённым, как описано выше. |
window
window(
size, shift=None, stride=1, drop_remainder=False, name=None
) -> 'DatasetV2'
Возвращает набор данных из «окон».
Каждое «окно» — это набор данных, содержащий подмножество элементов входного набора данных. Это конечные наборы данных размера size (или, возможно, меньшего размера, если входных элементов недостаточно для заполнения окна и drop_remainder имеет значение False).
Например:
dataset = tf.data.Dataset.range(7).window(3) for window in dataset: print(window) <...Dataset element_spec=TensorSpec(shape=(), dtype=tf.int64, name=None)> <...Dataset element_spec=TensorSpec(shape=(), dtype=tf.int64, name=None)> <...Dataset element_spec=TensorSpec(shape=(), dtype=tf.int64, name=None)>
Поскольку окна являются наборами данных, их можно перебирать:
for window in dataset: print(list(window.as_numpy_iterator())) [0, 1, 2] [3, 4, 5] [6]
Смещение
Аргумент shift определяет количество входных элементов, на которое нужно сместиться между началом каждого окна. Если нумерация окон и элементов начинается с 0, первый элемент в окне k будет элементом k * shift входного набора данных. В частности, первым элементом первого окна всегда будет первый элемент входного набора данных.
dataset = tf.data.Dataset.range(7).window(3, shift=1,
drop_remainder=True)
for window in dataset:
print(list(window.as_numpy_iterator()))
[0, 1, 2]
[1, 2, 3]
[2, 3, 4]
[3, 4, 5]
[4, 5, 6]Шаг
Аргумент stride определяет шаг между входными элементами внутри окна.
dataset = tf.data.Dataset.range(7).window(3, shift=1, stride=2,
drop_remainder=True)
for window in dataset:
print(list(window.as_numpy_iterator()))
[0, 2, 4]
[1, 3, 5]
[2, 4, 6]Вложенные элементы
При применении преобразования window к набору данных, элементы которого представляют собой вложенные структуры, создаётся набор данных с такой же вложенной структурой элементов, но каждый лист заменяется окном. Иными словами, вложенность применяется снаружи окон, а не внутри них.
Сигнатура типа:
def window(
self: Dataset[Nest[T]], ...
) -> Dataset[Nest[Dataset[T]]]
Применение window к Dataset кортежей создаёт кортеж окон:
dataset = tf.data.Dataset.from_tensor_slices(([1, 2, 3, 4, 5],
[6, 7, 8, 9, 10]))
dataset = dataset.window(2)
windows = next(iter(dataset))
windows
(<...Dataset element_spec=TensorSpec(shape=(), dtype=tf.int32, name=None)>,
<...Dataset element_spec=TensorSpec(shape=(), dtype=tf.int32, name=None)>)def to_numpy(ds): return list(ds.as_numpy_iterator()) for windows in dataset: print(to_numpy(windows[0]), to_numpy(windows[1])) [1, 2] [6, 7] [3, 4] [8, 9] [5] [10]
Применение window к Dataset словарей создаёт словарь Datasets:
dataset = tf.data.Dataset.from_tensor_slices({'a': [1, 2, 3],
'b': [4, 5, 6],
'c': [7, 8, 9]})
dataset = dataset.window(2)
def to_numpy(ds):
return list(ds.as_numpy_iterator())
for windows in dataset:
print(tf.nest.map_structure(to_numpy, windows))
{'a': [1, 2], 'b': [4, 5], 'c': [7, 8]}
{'a': [3], 'b': [6], 'c': [9]}Преобразование набора данных из окон в плоский набор
Методы Dataset.flat_map и Dataset.interleave позволяют объединить набор данных из окон в один набор данных.
Аргумент flat_map — это функция, которая принимает элемент из набора данных и возвращает Dataset. Метод flat_map последовательно объединяет полученные наборы данных.
Например, чтобы преобразовать каждое окно в плотный тензор:
dataset = tf.data.Dataset.range(7).window(3, shift=1,
drop_remainder=True)
batched = dataset.flat_map(lambda x:x.batch(3))
for batch in batched:
print(batch.numpy())
[0 1 2]
[1 2 3]
[2 3 4]
[3 4 5]
[4 5 6]| Аргументы | |
|---|---|
size | Скалярный tf.int64 tf.Tensor, представляющий количество элементов входного набора данных, объединяемых в окно. Значение должно быть положительным. |
shift | (Необязательно.) Скалярный tf.int64 tf.Tensor, представляющий количество входных элементов, на которое перемещается окно при каждой итерации. По умолчанию равно size. Значение должно быть положительным. |
stride | (Необязательно.) Скалярный tf.int64 tf.Tensor, представляющий шаг входных элементов в скользящем окне. Значение должно быть положительным. Значение по умолчанию 1 означает «сохранять каждый входной элемент». |
drop_remainder | (Необязательно.) Скалярный tf.bool tf.Tensor, указывающий, следует ли отбрасывать последние окна, если их размер меньше size. |
name | (Необязательно.) Имя операции tf.data. |
| Возвращает | |
|---|---|
Новый Dataset с преобразованием, применённым, как описано выше. |
with_options
with_options(
options, name=None
) -> 'DatasetV2'
Возвращает новый tf.data.Dataset с заданными параметрами.
Параметры являются «глобальными» в том смысле, что применяются ко всему набору данных. Если параметры задаются несколько раз, они объединяются при условии, что для разных параметров не указаны различные значения, отличные от значений по умолчанию.
ds = tf.data.Dataset.range(5)
ds = ds.interleave(lambda x: tf.data.Dataset.range(5),
cycle_length=3,
num_parallel_calls=3)
options = tf.data.Options()
# This will make the interleave order non-deterministic.
options.deterministic = False
ds = ds.with_options(options)| Аргументы | |
|---|---|
options | Объект tf.data.Options, определяющий используемые параметры. |
name | (Необязательно.) Имя операции tf.data. |
| Возвращает | |
|---|---|
Новый Dataset с преобразованием, применённым, как описано выше. |
| Вызывает исключение | |
|---|---|
ValueError | если для параметра более одного раза задано значение, отличное от значения по умолчанию |
zip
@staticmethod
zip(
*args, datasets=None, name=None
) -> 'DatasetV2'
Создаёт Dataset, объединяя указанные наборы данных с помощью zip.
Семантика этого метода аналогична встроенной функции zip() в Python, за исключением того, что аргумент datasets может быть (вложенной) структурой объектов Dataset. Поддерживаемые механизмы вложенности описаны здесь.
# The datasets or nested structure of datasets `*args` argument
# determines the structure of elements in the resulting dataset.
a = tf.data.Dataset.range(1, 4) # ==> [ 1, 2, 3 ]
b = tf.data.Dataset.range(4, 7) # ==> [ 4, 5, 6 ]
ds = tf.data.Dataset.zip(a, b)
list(ds.as_numpy_iterator())
[(1, 4), (2, 5), (3, 6)]
ds = tf.data.Dataset.zip(b, a)
list(ds.as_numpy_iterator())
[(4, 1), (5, 2), (6, 3)]
# The `datasets` argument may contain an arbitrary number of datasets.
c = tf.data.Dataset.range(7, 13).batch(2) # ==> [ [7, 8],
# [9, 10],
# [11, 12] ]
ds = tf.data.Dataset.zip(a, b, c)
for element in ds.as_numpy_iterator():
print(element)
(1, 4, array([7, 8]))
(2, 5, array([ 9, 10]))
(3, 6, array([11, 12]))
# The number of elements in the resulting dataset is the same as
# the size of the smallest dataset in `datasets`.
d = tf.data.Dataset.range(13, 15) # ==> [ 13, 14 ]
ds = tf.data.Dataset.zip(a, d)
list(ds.as_numpy_iterator())
[(1, 13), (2, 14)]| Аргументы | |
|---|---|
*args | Наборы данных или вложенные структуры наборов данных, которые нужно объединить с помощью zip. Нельзя задавать, если задан datasets. |
datasets | (Вложенная) структура наборов данных. Нельзя задавать, если задан *args. Обратите внимание, что этот аргумент существует только для обратной совместимости; предпочтительно использовать *args. |
name | (Необязательно.) Имя операции tf.data. |
| Возвращает | |
|---|---|
Новый Dataset с преобразованием, применённым, как описано выше. |
__bool__
__bool__()
__iter__
__iter__()
Создаёт итератор для элементов этого набора данных.
Возвращаемый итератор реализует протокол итератора Python.
| Возвращает | |
|---|---|
tf.data.Iterator для элементов этого набора данных. |
| Вызывает исключение | |
|---|---|
RuntimeError | Если выполнение происходит не внутри tf.function и не в режиме eager. |
__len__
__len__()
Возвращает длину набора данных, если она известна и конечна.
Для использования этого метода необходимо запустить код в режиме eager, а длина набора данных должна быть известной и конечной. Если длина может быть неизвестной или бесконечной либо код выполняется в режиме графа, вместо этого используйте tf.data.Dataset.cardinality.
| Возвращает | |
|---|---|
| Целое число, представляющее длину набора данных. |
| Вызывает исключение | |
|---|---|
RuntimeError | Если длина набора данных неизвестна или бесконечна либо выполнение в режиме eager не включено. |
__nonzero__
__nonzero__()
© 2022 The TensorFlow Authors. All rights reserved.
Licensed under the Creative Commons Attribution License 4.0.
Code samples licensed under the Apache 2.0 License.
https://www.tensorflow.org/api_docs/python/tf/compat/v1/data/experimental/CsvDataset