简体   繁体   English

如何安装时序多头 model?

[英]how do I fit a time-series multi head model?

I try to create a model by concatenating 2 models together.我尝试通过将 2 个模型连接在一起来创建 model。 The models I want to use, shall handle time series, and I'm experimenting with Conv1D layers.我想使用的模型应处理时间序列,并且我正在尝试使用 Conv1D 层。 As these have an 3D input shape batch_shape + (steps, input_dim) and the Keras TimeseriesGenerator is providing such, I'm happy being able to make use of it when handling single head models.由于它们有一个 3D 输入形状 batch_shape + (steps, input_dim) 和 Keras TimeseriesGenerator 提供这样的,我很高兴能够在处理单头模型时使用它。

import pandas as pd
import numpy as np
import random
from sklearn.model_selection import train_test_split
from tensorflow.keras.models import Sequential, Model
from tensorflow.keras.layers import (Input, Dense, Conv1D, BatchNormalization, 
                                     Flatten, Dropout, MaxPooling1D,
                                     concatenate)
from tensorflow.keras.preprocessing.sequence import TimeseriesGenerator
from tensorflow.keras.utils import plot_model

data = pd.DataFrame(index=pd.date_range(start='2020-01-01', periods=300, freq='D'))
data['featureA'] = [random.random() for _ in range(len(data))]
data['featureB'] = [random.random() for _ in range(len(data))]
data['featureC'] = [random.random() for _ in range(len(data))]
data['featureD'] = [random.random() for _ in range(len(data))]
data['target']   = [random.random() for _ in range(len(data))]

Xtrain_AB, Xtest_AB, yTrain_AB, yTest_AB = train_test_split(data[['featureA', 'featureB']], 
                                                            data['target'], test_size=0.2,
                                                            shuffle=False)
Xtrain_CD, Xtest_CD, yTrain_CD, yTest_CD = train_test_split(data[['featureC', 'featureD']], 
                                                            data['target'], test_size=0.2,
                                                            shuffle=False)

n_steps = 5 

train_gen_AB = TimeseriesGenerator(Xtrain_AB, yTrain_AB,
                                length=n_steps, 
                                sampling_rate=1,
                                batch_size=64,
                                shuffle=False)
test_gen_AB = TimeseriesGenerator(Xtest_AB, yTest_AB,
                                length=n_steps, 
                                sampling_rate=1,
                                batch_size=64,
                                shuffle=False)

n_features_AB = len(Xtrain_AB.columns)
input_AB      = Input(shape=(n_steps, n_features_AB))
layer_AB      = Conv1D(filters=128, kernel_size=3, activation='relu', input_shape=(n_steps, n_features_AB))(input_AB)
layer_AB      = MaxPooling1D(pool_size=2)(layer_AB)
layer_AB      = Flatten()(layer_AB)
dense_AB      = Dense(50, activation='relu')(layer_AB)
output_AB     = Dense(1)(dense_AB)
model_AB      = Model(inputs=input_AB, outputs=output_AB)
model_AB.compile(optimizer='adam', loss='mse')
model_AB.summary()
model_AB.fit(train_gen_AB, epochs=1, verbose=1)
print(f'evaluation: {model_AB.evaluate(test_gen_AB)}')

#plot_model(model_AB)

train_gen_CD = TimeseriesGenerator(Xtrain_CD, yTrain_CD,
                                length=n_steps, 
                                sampling_rate=1,
                                batch_size=64,
                                shuffle=False)
test_gen_CD = TimeseriesGenerator(Xtest_CD, yTest_CD,
                                length=n_steps, 
                                sampling_rate=1,
                                batch_size=64,
                                shuffle=False)

n_features_CD = len(Xtrain_CD.columns)
input_CD      = Input(shape=(n_steps, n_features_CD))
layer_CD      = Conv1D(filters=128, kernel_size=3, activation='relu', input_shape=(n_steps, n_features_CD))(input_CD)
layer_CD      = MaxPooling1D(pool_size=2)(layer_CD)
layer_CD      = Flatten()(layer_CD)
dense_CD      = Dense(50, activation='relu')(layer_CD)
output_CD     = Dense(1)(dense_CD)
model_CD      = Model(inputs=input_CD, outputs=output_CD)
model_CD.compile(optimizer='adam', loss='mse')
model_CD.summary()
model_CD.fit(train_gen_CD, epochs=1, verbose=1)
print(f'evaluation: {model_CD.evaluate(test_gen_CD)}')

#plot_model(model_CD)

This works fine for each of the models:)这适用于每个模型:)

Now I would like to experiment with concatenating both models to one (as I think it might enable me later when adding additional 'heads' to train them in parallel, and I guess using such models might be easier as handling a lot of separated once) and get a dual-head model, which can easily be created like this现在我想尝试将两个模型连接到一个模型(因为我认为它可以让我稍后添加额外的“头”来并行训练它们,我猜使用这样的模型可能更容易处理很多分离一次)并得到一个双头 model,可以像这样轻松创建

merge=concatenate(inputs=[layer_AB, layer_CD])
dense_merge     = Dense(50, activation='relu')(merge)
output_merge    = Dense(1)(dense_merge)
model_dual_head = Model(inputs=[input_AB, input_CD], outputs=output_merge)
model_dual_head.compile(optimizer='adam', loss='mse')
model_dual_head.summary()
print(f'dual head model input_shape:{model_dual_head.input_shape}')
plot_model(model_dual_head) 

This dual_head_model has an input_shape of 2 time 3D [(None, 5, 2), (None, 5, 2)] and looks finally this way这个 dual_head_model 的 input_shape 为 2 倍 3D [(None, 5, 2), (None, 5, 2)]最终看起来是这样在此处输入图像描述

Unfortunately I don't know how to fit it:( and hope you will be able to provide me a solution on how to generate the needed shape of data. I tried to provide the previously used generators as list model_dual_head.fit([train_gen_AB, train_gen_CD], epochs=1, verbose=1) , and also lists of the raw input data frames model_dual_head.fit(x=[Xtrain_AB, Xtrain_CD], y=[yTrain_AB, yTrain_CD], epochs=1, verbose=1) , but it seems not to be in the right shape.不幸的是,我不知道如何适应它:(并希望您能够为我提供有关如何生成所需数据形状的解决方案。我尝试将以前使用的生成器提供为列表model_dual_head.fit([train_gen_AB, train_gen_CD], epochs=1, verbose=1) ,以及原始输入数据帧model_dual_head.fit(x=[Xtrain_AB, Xtrain_CD], y=[yTrain_AB, yTrain_CD], epochs=1, verbose=1)的列表,但它似乎不是正确的形状。

Thanks in advance提前致谢

Wasili瓦西里


based on Jacks comment I tried the using following code根据 Jacks 评论,我尝试使用以下代码

def doubleGen(gen1, gen2):
  assert(len(gen1) == len(gen2))
  for feature1, label1, feature2, label2 in (train_gen_AB, train_gen_CD):
    yield (feature1, feature2), label1 

gen = doubleGen(train_gen_AB, train_gen_CD)
model_dual_head.fit(gen, epochs=1, verbose=1)

but unfortunatelly it does not work, as the input_shape is not the same但不幸的是它不起作用,因为 input_shape 不一样

ValueError: Layer model_2 expects 2 input(s), but it received 4 input tensors. Inputs received: [<tf.Tensor 'IteratorGetNext:0' shape=(None, None, None) dtype=float32>, <tf.Tensor 'ExpandDims:0' shape=(None, 1) dtype=float32>, <tf.Tensor 'IteratorGetNext:2' shape=(None, None, None) dtype=float32>, <tf.Tensor 'ExpandDims_1:0' shape=(None, 1) dtype=float32>]

I adapted the parenthesis in the generator based on Jacks note and get a different error now.我根据 Jacks note 调整了生成器中的括号,现在得到了不同的错误。

def doubleGen(gen1, gen2):
  assert(len(gen1) == len(gen2))
  for (feature1, label1), (feature2, label2) in train_gen_AB, train_gen_CD:
    assert label1 == label2
    yield (feature1, feature2), label1 

gen = doubleGen(train_gen_AB, train_gen_CD)
model_dual_head.fit(gen, epochs=1, verbose=1)
<ipython-input-8-e8971cd0f287> in doubleGen(gen1, gen2)
      1 def doubleGen(gen1, gen2):
      2   assert(len(gen1) == len(gen2))
----> 3   for (feature1, label1), (feature2, label2) in train_gen_AB, train_gen_CD:
      4     assert label1 == label2
      5     yield (feature1, feature2), label1

ValueError: too many values to unpack (expected 2)

I thought about using a plain index iterating the generators which does fix the shape topic, but this results in a NonType error我考虑过使用一个普通索引迭代生成器来修复形状主题,但这会导致 NonType 错误

def doubleGen(gen1, gen2):
  assert(len(gen1) == len(gen2))
  for i in range(len(gen1)):
    feature1, label1 = gen1[i]
    feature2, label2 = gen2[i]
    #assert label1.all() == label2.all()
    yield (feature1, feature2), label1 

gen = doubleGen(train_gen_AB, train_gen_CD)
model_dual_head.fit(gen, epochs=1, verbose=1)
TypeError                                 Traceback (most recent call last)
<ipython-input-24-6abda48a58c7> in <module>()
      8 
      9 gen = doubleGen(train_gen_AB, train_gen_CD)
---> 10 model_dual_head.fit(gen, epochs=1, verbose=1)

2 frames
/usr/local/lib/python3.7/dist-packages/tensorflow/python/eager/def_function.py in _call(self, *args, **kwds)
    853       # In this case we have created variables on the first call, so we run the
    854       # defunned version which is guaranteed to never create variables.
--> 855       return self._stateless_fn(*args, **kwds)  # pylint: disable=not-callable
    856     elif self._stateful_fn is not None:
    857       # Release the lock early so that multiple threads can perform the call

TypeError: 'NoneType' object is not callable

The Notebook can be reached here可以在此处访问笔记本


Finally Jacks input helped to find the solution.最后,杰克斯的意见帮助找到了解决方案。 There was just missing to zip both generators to be able to iterated through them:) zip 只是缺少两个生成器,以便能够迭代它们:)

def doubleGen(gen1, gen2):
  assert(len(gen1) == len(gen2))
  for (feature1, label1), (feature2, label2) in zip(train_gen_AB, train_gen_CD):
    assert label1.all() == label2.all()
    yield (feature1, feature2), label1 

gen = doubleGen(train_gen_AB, train_gen_CD)
model_dual_head.fit(gen, epochs=1, verbose=1)
4/4 [==============================] - 0s 14ms/step - loss: 0.1119
<tensorflow.python.keras.callbacks.History at 0x7f0dfd4de5d0>

I do not know if this already exists, but I believe you can create a new Generator that merges the two datasets.我不知道这是否已经存在,但我相信您可以创建一个新的生成器来合并两个数据集。 Assuming the two Generators are in lockstep, this should work:假设两个生成器步调一致,这应该可以工作:

for (input1, label1), (input2, label2) in generator1, generator2:
    assert label1 == label2
    yield (input1, input2), label1

This now gives a generator that yields both inputs as a tuple, and the common label as one data item.现在,这给出了一个生成器,该生成器将两个输入作为一个元组生成,并将公共 label 作为一个数据项。 This could be a lambda, which would save the trouble of creating an entire Generator class.这可能是 lambda,这样可以省去创建整个发电机 class 的麻烦。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何转换 R 中的日期时间格式以读取时间序列预测 model? - How can I convert datetime format in R to be read for a Time-Series prediction model? 如何在python中建立LSTM时间序列预测模型? - How to build an LSTM time-series forecasting model in python? 如何构建django-mongodb-engine中的时间序列模型 - How to Structure Time-Series model in django-mongodb-engine 如何在 python 中构建不规则时间序列预测 model? - How to build an irregular time-series prediction model in python? 如何在 Python/Pandas 中使我的时间序列数据连续? - How do I make my time-series data continuous in Python/Pandas? 如何找到映射 f: X -&gt; Y 来表征 2 个时间序列 X 和 Y 之间的关系? - How do I find a mapping f : X -> Y to characterize the relationship between 2 time-series X and Y? 如何从时间序列 dataframe 中识别和提取事件? - How do I identify and extract events from a time-series dataframe? 使用多个时间序列训练 model - Use multiple time-series to train model 拟合回归 Model 到时间序列数据 - Fitting Regression Model to Time-Series Data 如何调整python上的时间序列数据的大小 - How can I resize on time-series data on python
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM