Объединить или добавить несколько объектов Keras TimeseriesGenerator в один - PullRequest
1 голос
/ 11 апреля 2020

Я пытаюсь сделать модель LSTM. Данные поступают из файла CSV, который содержит значения для нескольких акций.

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

У меня есть что-то вроде этого:

for stock in stocks:

    stock_df = df.loc[(df['symbol'] == stock)].copy()
    target = stock_df.pop('price')

    x = np.array(stock_df.values)
    y = np.array(target.values)

    sequence = TimeseriesGenerator(x, y, length = 4, sampling_rate = 1, batch_size = 1)

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

Невозможно использовать добавление или объединение, потому что функция возвращает объект-генератор, а не numpy массив.

Ответы [ 2 ]

0 голосов
/ 13 апреля 2020

РЕДАКТИРОВАТЬ: Новый ответ:


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

class seq_generator():

  def __init__(self, list_of_filepaths):
    self.usedDict = dict()
    for path in list_of_filepaths:
      self.usedDict[path] = []

  def generate(self):
    while True: 
      path = np.random.choice(list(self.usedDict.keys()))
      stock_array = np.load(path) 
      random_sequence = np.random.randint(stock_array.shape[0])
      if random_sequence not in self.usedDict[path]:
        self.usedDict[path].append(random_sequence)
        yield stock_array[random_sequence, :, :]

train_generator = seq_generator(list_of_filepaths)

train_dataset = tf.data.Dataset.from_generator(seq_generator.generate(),
                                               output_types=(tf.float32, tf.float32), 
                                               output_shapes=(n_timesteps, n_features)) 

train_dataset = train_dataset.batch(batch_size)

Где list_of_filepaths - это просто список путей к предварительно обработанным данным .npy.


Это будет :

  • Загрузка предварительно обработанных данных .npy случайного запаса
  • Произвольно выбрать последовательность
  • Проверить, был ли индекс последовательности уже использован в usedDict
  • Если нет:
    • Добавьте индекс этой последовательности к usedDict, чтобы отслеживать, чтобы не передавать одни и те же данные дважды в модель
    • Получите последовательность

Это означает, что генератор будет подавать одну уникальную последовательность из случайного запаса при каждом вызове, что позволяет мне использовать методы .from_generator() и .batch() из Tensorflows Набор данных тип.


Оригинальный ответ: * 1 041 *

Я думаю, что ответ от @TF_Support немного упускает суть. Если я понимаю ваш вопрос Это не так, как будто вы хотите тренировать одну модель пр. stock, вам нужна одна модель, обученная для всего набора данных .

Если у вас достаточно памяти, вы можете вручную создать последовательности и сохранить весь набор данных в памяти. Проблема, с которой я сталкиваюсь, похожа, я просто не могу держать все в памяти: Создание TimeseriesGenerator с несколькими входами .

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

0 голосов
/ 13 апреля 2020

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

Вы можете добавление созданных TimeSeriesGenerators в Python список .

stock_timegenerators = []
for stock in stocks:
    stock_df = stock.copy()
    features = stock_df.pop('symbol')
    target = stock_df.pop('price')

    x = np.array(stock_df.values)
    y = np.array(target.values)

    # sequence = TimeseriesGenerator(x, y, length = 4, sampling_rate = 1, batch_size = 1)
    stock_timegenerators.append(TimeseriesGenerator(x, y, length = 4, sampling_rate = 1, batch_size = 1))

Результатом этого будет добавленный TimeSeriesGenerator , который вы можете использовать по итерации список или ссылка по index .

[<tensorflow.python.keras.preprocessing.sequence.TimeseriesGenerator at 0x7eff62c699b0>,
 <tensorflow.python.keras.preprocessing.sequence.TimeseriesGenerator at 0x7eff62c6eba8>,
 <tensorflow.python.keras.preprocessing.sequence.TimeseriesGenerator at 0x7eff62c782e8>]

Также с несколькими сериями Keras Timeseries означает, что вы тренируетесь Несколько моделей LSTM для каждой акции.
Вы также можете использовать этот подход для эффективной работы с несколькими моделями.

lstm_models = []
for time_series_gen in stock_timegenerators:

    # lstm_models.append(create_model()) : You could create everything using functions

    # Or in the loop like this.
    model = Sequential()
    model.add(LSTM(32, input_shape = (n_input, n_features)))
    model.add(Dense(1))

    model.compile(loss ='mse', optimizer = 'adam')

    model.fit(time_series_gen, steps_per_epoch= 1, epochs = 5)

    lstm_models.append(model)

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

[<tensorflow.python.keras.engine.sequential.Sequential at 0x7eff62c7b748>,
 <tensorflow.python.keras.engine.sequential.Sequential at 0x7eff6100e160>,
 <tensorflow.python.keras.engine.sequential.Sequential at 0x7eff63dc94a8>]

This способ создания нескольких моделей LSTM с различными генераторами временных рядов для различных акций .

Надеюсь, это поможет вам.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...