Будет ли Tensorflow Dataset перемешиваться между эпохами с помощью преобразований Dataset после перемешивания? - PullRequest
1 голос
/ 10 июля 2019

Я работаю над конвейером TensorFlow, где я загружаю кучу сигналов в набор данных, я перетасовываю эти сигналы, затем выполняю управление окнами для сигналов, а затем пакетирую и повторяю. Этот набор данных используется для обучения модели tf.keras с помощью вызова функции model.fit. Очень важно, чтобы окна сигнала не были перетасованы, поэтому это порядок преобразований набора данных.

Мне интересно, будет ли порядок сигналов перетасовываться между эпохами? Я обнаружил, что dataset.shuffle().batch().repeat() заставит перетасовать набор данных между эпохами, но это не будет работать для моего приложения, так как мне нужно делать оконные и другие преобразования после перетасовки.

Я использую TensorFlow версии 1.13.1.

#... some pre-processing on the signals 
signalList = [...] # a list of tuples (data, label)
dataset = tf.data.Dataset.from_generator(lambda: signalList)
dataset = dataset.shuffle(buffer_size=self.buffer_size)  ## will this shuffle be repeated??
dataset = dataset.map(...) # windowing and other transforms
dataset = dataset.batch()
dataset = dataset.repeat()

model.fit(dataset, ...)

Редактировать: интересующее меня поведение заключается в том, что я хотел бы, чтобы порядок сигналов менялся с каждой эпохой. Итак, если у меня есть 3 сигнала

signal0=[window0_0,window0_1]
signal1=[window1_0,window1_1,window1_2]
signal2=[window2_0]

тогда результат будет выглядеть примерно так:

tf.Tensor([signal0,signal2,signal1],...) # equivalent to tf.Tensor([window0_0,window0_1,window2_0,window1_0,window1_1,window1_2])
tf.Tensor([signal1,signal0,signal2],...) # equivalent to tf.Tensor([window1_0,window1_1,window1_2,window0_0,window0_1,window2_0]) 

где transform datset.map (windowing) .shuffle (). Batch (). Repeat () выдаст что-то подобное (что меня не интересует)

tf.Tensor([window0_1,window1_1,window2_0,window1_0,window0_0,window1_2])
tf.Tensor([window0_0,window1_2,window0_1,window2_0,window1_1,window1_0]) 

Ответы [ 2 ]

0 голосов
/ 15 июля 2019

После небольшого исследования я понял, что да, shuffle вызывается после каждой эпохи, даже если есть другие преобразования после тасования и перед партией. Я не уверен, что это означает для конвейера (например, я не уверен, что оконное управление также вызывается в каждую эпоху и замедляет обработку), но я создал блокнот Jupyter, где я создал маленькую версию трубопровод

signalList = [...] # a list of tuples (data, label)
dataset = tf.data.Dataset.from_generator(lambda: signalList)
dataset = dataset.shuffle(buffer_size=self.buffer_size)  
dataset = dataset.map(...) # windowing and other transforms
dataset = dataset.batch()
dataset = dataset.repeat()

создал итератор

iterator = dataset.make_one_shot_iterator()

и нанесены сигналы на несколько эпох

next_ = iterator.get_next()
for i in range(10):  # 10 epochs
    full_signal = []
    for j in range(29):  # 29 events for this epoch
        next_ = iterator.get_next()
        full_signal = np.concatenate((full_signal, next_[0][0]), axis=None)

    fig = plt.figure(figsize=(18, 5))
    plt.plot(full_signal)

и увидел, что сигналы выглядели так, как будто они всегда были в другом порядке, что означало бы, что они перетасовываются после каждой эпохи.

Если у кого-нибудь есть более подробный ответ, где он может объяснить, как это работает с компиляцией DatasetAPI, или если они могут уточнить, если порядок этих преобразований замедляет конвейер, я был бы очень признателен!

0 голосов
/ 10 июля 2019

Вы можете передать необязательный аргумент .shuffle() для предотвращения перестановок в каждой эпохе.

Итак, если у меня есть такой набор данных:

def gen():
  yield 1
  yield 2
  yield 3

ds = tf.data.Dataset.from_generator(gen, output_shapes=(), output_types=tf.int32)

затем делает:

shuffled_and_batched = ds.shuffle(3).batch(3).repeat()

дает вывод:

tf.Tensor([3 2 1], shape=(3,), dtype=int32)
tf.Tensor([1 3 2], shape=(3,), dtype=int32)
tf.Tensor([2 1 3], shape=(3,), dtype=int32)
tf.Tensor([3 1 2], shape=(3,), dtype=int32)
tf.Tensor([2 3 1], shape=(3,), dtype=int32)

где каждая эпоха меняет мои 3 элемента. Это поведение, которое, как я понимаю, вы хотите избежать.

Если вместо этого я сделаю:

shuffled_and_batched = ds.shuffle(3, <b>reshuffle_each_iteration=False</b>).batch(3).repeat()

тогда я получаю вывод:

tf.Tensor([1 3 2], shape=(3,), dtype=int32)
tf.Tensor([1 3 2], shape=(3,), dtype=int32)
tf.Tensor([1 3 2], shape=(3,), dtype=int32)
tf.Tensor([1 3 2], shape=(3,), dtype=int32)
tf.Tensor([1 3 2], shape=(3,), dtype=int32)

с заказом, перетасованным один раз и затем использованным каждую эпоху.

...