I'm new to Keras and to CNN and I don't understand how to correctly structure the CNN network.
Context: I use a time series of 39 features and I want to use 3 lags of data. Also, my problem is a multistep outputs, and so I want to predict 48 outputs. I use TimeseriesGenerator to create model inputs (using this article for reference ).
Here is my code:
generator = TimeseriesGenerator(
inputs,
outputs,
length=6,
batch_size=1,
)
Here is my model construction:
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,
)
Problem: I understood that kernel size (with valid padding) cannot be higher than the number of lags specified in the ts generator. But I have a dimensional error when setting the kernel size=5 < nb_lags=6:
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].
I've found that my CNN structure is correct only when kernel_size is set to 2, don't get why it's working but not when I increase the value...
Can anyone explain me the inputs and outputs of TimeseriesGenerator and Conv1D layers?
This is due to the fact that you too aggressively reduce dimensions. Since your input dimension is (6, 39)
, then after first Conv1D
it has dimension (2, 64)
, and then after first MaxPooling1D
it reduces to (1, 64)
. Thus after second Conv1D
with kernel_size=5
and padding='valid'
you would get (1-5, 64)
dimensions what the error actually trying say to you.
Instead of Conv1D
and Maxpooling1D
you may use Conv2D
and Maxpooling2D
respectively and set 1s at the time dimension. Here is the example how to do so:
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,
)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.