Получить длину набора данных в Tensorflow

source_dataset = tf.data.TextLineDataset('primary.csv')
target_dataset = tf.data.TextLineDataset('secondary.csv')
dataset = tf.data.Dataset.zip((source_dataset, target_dataset))
dataset = dataset.shard(10000, 0)
dataset = dataset.map(lambda source, target: (tf.string_to_number(tf.string_split([source], delimiter=',').values, tf.int32),
                                              tf.string_to_number(tf.string_split([target], delimiter=',').values, tf.int32)))
dataset = dataset.map(lambda source, target: (source, tf.concat(([start_token], target), axis=0), tf.concat((target, [end_token]), axis=0)))
dataset = dataset.map(lambda source, target_in, target_out: (source, tf.size(source), target_in, target_out, tf.size(target_in)))

dataset = dataset.shuffle(NUM_SAMPLES)  #This is the important line of code

Я хотел бы полностью перетасовать весь свой набор данных, но shuffle() требуется извлечь несколько образцов, а tf.Size() не работает с tf.data.Dataset.

Как правильно перемешать?


person Evan Weissburg    schedule 10.12.2017    source источник
comment
Он должен быть размером с ваш меньший CSV-файл. Мне неизвестна функция или свойство в Tensorflow, которое возвращает длину набора данных.   -  person Lescurel    schedule 10.12.2017
comment
Это кажется глупым. В любом случае - почему это CSV меньшего размера? Каково поведение при использовании zip () при увеличении длины?   -  person Evan Weissburg    schedule 10.12.2017
comment
Из документации: Количество элементов в результирующий набор данных будет таким же, как размер наименьшего набора данных   -  person Lescurel    schedule 12.12.2017
comment
zip () работает точно так же; итерация заканчивается, когда вызывается StopIteration (самым коротким объектом).   -  person markemus    schedule 30.05.2019


Ответы (2)


Я работал с tf.data.FixedLengthRecordDataset () и столкнулся с аналогичной проблемой. В моем случае я пытался взять только определенный процент необработанных данных. Поскольку я знал, что все записи имеют фиксированную длину, обходной путь для меня был:

totalBytes = sum([os.path.getsize(os.path.join(filepath, filename)) for filename in os.listdir(filepath)])
numRecordsToTake = tf.cast(0.01 * percentage * totalBytes / bytesPerRecord, tf.int64)
dataset = tf.data.FixedLengthRecordDataset(filenames, recordBytes).take(numRecordsToTake)

В вашем случае я предлагаю посчитать непосредственно в python количество записей в primary.csv и secondary.csv. В качестве альтернативы, я думаю, для вашей цели установка аргумента buffer_size на самом деле не требует подсчета файлов. Согласно принятый ответ о значении of buffer_size, число, превышающее количество элементов в наборе данных, обеспечит равномерное перемешивание по всему набору данных. Так что просто введите действительно большое число (которое, как вы думаете, превзойдет размер набора данных), должно работать.

person Ringo    schedule 09.02.2018

Начиная с TensorFlow 2, длину набора данных можно легко получить с помощью функции cardinality().

dataset = tf.data.Dataset.range(42)
#both print 42 
dataset_length_v1 = tf.data.experimental.cardinality(dataset).numpy())
dataset_length_v2 = dataset.cardinality().numpy()

ПРИМЕЧАНИЕ. При использовании предикатов, таких как фильтр, длина может быть равна -2. Можно проконсультироваться с объяснением здесь, в противном случае просто прочтите следующий абзац:

Если вы используете предикат фильтра, количество элементов может возвращать значение -2, следовательно, неизвестно; Если вы действительно используете предикаты фильтра в своем наборе данных, убедитесь, что вы вычислили другим способом длину вашего набора данных (например, длину фрейма данных pandas, прежде чем применять к нему .from_tensor_slices().

person Timbus Calin    schedule 19.08.2020
comment
Это дает -2 для обоих наборов данных, которые я пробовал. - person Toby; 25.11.2020
comment
Да, и вот объяснение, почему - person Timbus Calin; 25.11.2020