Как использовать окна, созданные методом Dataset.window() в TensorFlow 2.0?

#python #tensorflow2.0

#python #tensorflow2.0

Вопрос:

Я пытаюсь создать набор данных, который будет возвращать случайные окна из временного ряда вместе со следующим значением в качестве целевого, используя TensorFlow 2.0.

Я использую Dataset.window() , который выглядит многообещающим:

 import tensorflow as tf

dataset = tf.data.Dataset.from_tensor_slices(tf.range(10))
dataset = dataset.window(5, shift=1, drop_remainder=True)
for window in dataset:
    print([elem.numpy() for elem in window])
  

Выводит:

 [0, 1, 2, 3, 4]
[1, 2, 3, 4, 5]
[2, 3, 4, 5, 6]
[3, 4, 5, 6, 7]
[4, 5, 6, 7, 8]
[5, 6, 7, 8, 9]
  

Однако я хотел бы использовать последнее значение в качестве целевого. Если бы каждое окно было тензором, я бы использовал:

 dataset = dataset.map(lambda window: (window[:-1], window[-1:]))
  

Однако, если я попробую это, я получу исключение:

 TypeError: '_VariantDataset' object is not subscriptable
  

Ответ №1:

Решение заключается в вызове flat_map() следующим образом:

 dataset = dataset.flat_map(lambda window: window.batch(5))
  

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

 dataset = dataset.map(lambda window: (window[:-1], window[-1:]))
  

Итак, полный код:

 import tensorflow as tf

dataset = tf.data.Dataset.from_tensor_slices(tf.range(10))
dataset = dataset.window(5, shift=1, drop_remainder=True)
dataset = dataset.flat_map(lambda window: window.batch(5))
dataset = dataset.map(lambda window: (window[:-1], window[-1:]))

for X, y in dataset:
    print("Input:", X.numpy(), "Target:", y.numpy())
  

Какие результаты:

 Input: [0 1 2 3] Target: [4]
Input: [1 2 3 4] Target: [5]
Input: [2 3 4 5] Target: [6]
Input: [3 4 5 6] Target: [7]
Input: [4 5 6 7] Target: [8]
Input: [5 6 7 8] Target: [9]
  

Комментарии:

1. Хотя это и не обязательно для ответа на вопрос, не могли бы вы пояснить, зачем нам нужен этот шаг flat_map? Я все еще пытаюсь это понять.

2. Метод window() возвращает набор данных, содержащий окна, где каждое окно само по себе представлено в виде набора данных. Что-то вроде {{1,2,3,4,5},{6,7,8,9,10},…}, где {…} представляет набор данных. Но нам просто нужен обычный набор данных, содержащий тензоры: {[1,2,3,4,5],[6,7,8,9,10],…}, где […] представляет тензор. Метод flat_map() возвращает все тензоры во вложенном наборе данных после преобразования каждого вложенного набора данных. Если бы мы не выполняли пакетную обработку, мы бы получили: {1,2,3,4,5,6,7,8,9,10, …}. Путем пакетной обработки каждого окна до его полного размера мы получаем {[1,2,3,4,5],[6,7,8,9,10],…} как мы и хотели. Очистить?

3. Есть ли способ затем создавать мини-пакеты из этих образцов? У нас уже есть измерение None из window.batch (5), поэтому при добавлении, например, dataset.batch(3), мы получаем другое измерение None

4. Хорошо, это действительно работает, поскольку измерение None, вызываемое window.batch, конечно, необходимо.

5. вы потеряете возможность len() использования flat_map , но вместо этого вы можете использовать медленную версию len(list(dataset))