【问题标题】:Understanding TimeseriesGenerator with CNN Conv1D使用 CNN Conv1D 了解 TimeseriesGenerator
【发布时间】:2020-12-06 19:21:56
【问题描述】:

我是 Keras 和 CNN 的新手,我不明白如何正确构建 CNN 网络。

上下文: 我使用 39 个特征的时间序列,我想使用 3 个滞后数据。另外,我的问题是多步输出,所以我想预测 48 个输出。 我使用 TimeseriesGenerator 创建模型输入(使用 this article for reference)。

这是我的代码:

generator = TimeseriesGenerator(
        inputs,
        outputs,
        length=6,
        batch_size=1,
)

这是我的模型构建:

model = Sequential()
model.add(
    Conv1D(
        filters=64,
        kernel_size=5,
        strides=1,
        activation="relu",
        padding="valid",
        input_shape=(6, 39),
        use_bias=True,
    )
)
model.add(MaxPooling1D(pool_size=2))
model.add(
    Conv1D(
        filters=64,
        kernel_size=5,
        strides=1,
        activation="relu",
        padding="valid",
        use_bias=True,
    )
)
model.add(MaxPooling1D(pool_size=2))
model.add(Flatten())
model.add(Dense(units=100, activation="relu",))
model.add(Dense(units=self.__n_steps_out, activation="softmax",))


model.compile(
    optimizer="adam", loss="categorical_crossentropy", metrics=["accuracy"]
)


model.fit_generator(
    generator, steps_per_epoch=1, epochs=100,
)

问题: 我知道内核大小(具有有效填充)不能高于 ts 生成器中指定的滞后数。 但是在设置内核大小=5 时出现尺寸错误

ValueError: Negative dimension size caused by subtracting 5 from 1 for '{{node conv1d_1/conv1d}} = Conv2D[T=DT_FLOAT, data_format="NHWC", dilations=[1, 1, 1, 1], explicit_paddings=[], padding="VALID", strides=[1, 1, 1, 1], use_cudnn_on_gpu=true](conv1d_1/conv1d/ExpandDims, conv1d_1/conv1d/ExpandDims_1)' with input shapes: [?,1,1,64], [1,5,64,64].

我发现我的 CNN 结构只有在 kernel_size 设置为 2 时才是正确的,不明白为什么它在工作,但当我增加值时却不是......

谁能解释一下 TimeseriesGenerator 和 Conv1D 层的输入和输出?

【问题讨论】:

    标签: python tensorflow keras time-series


    【解决方案1】:

    这是因为您过于激进地缩减尺寸。由于您的输入维度是(6, 39),那么在第一个Conv1D 之后它的维度为(2, 64),然后在第一个MaxPooling1D 之后它减少到(1, 64)。因此,在第二个 Conv1Dkernel_size=5padding='valid' 之后,您将得到 (1-5, 64) 维度,错误实际上试图对您说什么。

    您可以分别使用Conv2DMaxpooling2D 而不是Conv1DMaxpooling1D,并将时间维度设置为1。以下是如何执行此操作的示例:

    from tensorflow.keras import Sequential
    from tensorflow.keras.layers import Conv2D, MaxPooling2D, Dense, Flatten
    from tensorflow.keras.preprocessing.sequence import TimeseriesGenerator
    import numpy as np
    
    if __name__ == '__main__':
    
        inputs = np.random.rand(1000, 39, 1)
        outputs = np.random.rand(1000, 1, 1)
    
        generator = TimeseriesGenerator(
            inputs,
            outputs,
            length=6,
            batch_size=10,
        )
    
        model = Sequential()
        model.add(
            Conv2D(
                filters=64,
                kernel_size=(1, 5),
                strides=1,
                activation="relu",
                padding="valid",
                input_shape=(6, 39, 1),
                use_bias=True,
            )
        )
        model.add(MaxPooling2D(pool_size=(1, 2)))
        model.add(
            Conv2D(
                filters=64,
                kernel_size=(1, 5),
                strides=1,
                activation="relu",
                padding="valid",
                use_bias=True,
            )
        )
        model.add(MaxPooling2D(pool_size=(1, 2)))
        model.add(Flatten())
        model.add(Dense(units=100, activation="relu", ))
        model.add(Dense(units=1, activation="softmax", ))
    
        model.summary()
    
        model.compile(
            optimizer="adam", loss="categorical_crossentropy", metrics=["accuracy"]
        )
    
        model.fit_generator(
            generator, steps_per_epoch=1, epochs=100,
        )
    
    

    【讨论】:

    • 感谢您的回答,我更明白出了什么问题。再问一个问题,因为我真的不明白我们怎么能做到这一点。当您说使用以时间为维度的 2D 卷积时,您是什么意思?我是否需要将数据的时间戳作为附加列?这对网络意味着什么?
    • @hotuagia 您有多值时间序列,您将其拆分为较小的窗口,为您提供形状 (T,S) 的输入,其中 T 是时间维度,S 是一些值。因此,您可以将其视为 2D 图像并仅在第二维(对应于 S)中应用 2D Convs 和 Maxpooling。我猜这是你最初的想法。
    • 我有一个包含多个特征的时间序列。根据我的统计分析,我认为过去的 6 个值有助于预测下一个值。所以我使用了一个包含 6 个值的窗口,并将其传递给网络。我还是不明白时间的第二维度能代表什么。
    • @hotuagia 好的,所以如果你想在时间维度上进行 1D Conv 和 Maxpooling,只需将 Conv 层中的代码 padding="valid" 更改为 padding="same"
    • 谢谢,现在终于可以使用了!感谢您的所有回答
    猜你喜欢
    • 2020-11-07
    • 2021-01-19
    • 2020-10-03
    • 1970-01-01
    • 2020-04-25
    • 2018-08-27
    • 2020-08-21
    • 2020-06-25
    • 2020-12-03
    相关资源
    最近更新 更多