I am using Keras Functional API for a time series prediction with multivariate input and single output: (x_1, x_2, y)
.
Therefore I have two network branches with several layers, that I concatenate after processing.
The code looks like this:
# Define Model Input Sets
inputA = Input(shape=(4, 1))
inputB = Input(shape=(4, 1))
# Build Model Branch 1
branch_1 = layers.LSTM(8, activation='tanh', dropout=0.2, return_sequences=True)(inputA)
branch_1 = layers.Dense(8, activation='tanh')(branch_1)
branch_1 = layers.Dropout(0.2)(branch_1)
branch_1 = layers.LSTM(6, activation='tanh', dropout=0.2, return_sequences=True)(branch_1)
branch_1 = layers.Dense(6, activation='tanh')(branch_1)
branch_1 = layers.Dropout(0.2)(branch_1)
branch_1 = Model(inputs=inputA, outputs=branch_1)
# Build Model Branch 2
branch_2 = layers.LSTM(8, activation='tanh', dropout=0.2, return_sequences=True)(inputB)
branch_2 = layers.Dense(8, activation='tanh')(branch_2)
branch_2 = layers.Dropout(0.2)(branch_2)
branch_2 = layers.LSTM(6, activation='tanh', dropout=0.2, return_sequences=True)(branch_2)
branch_2 = layers.Dense(6, activation='tanh')(branch_2)
branch_2 = layers.Dropout(0.2)(branch_2)
branch_2 = Model(inputs=inputB, outputs=branch_2)
# Combine Model Branches
combined = layers.concatenate([branch_1.output, branch_2.output])
# apply a FC layer and then a regression prediction on the combined outputs
comb = layers.Dense(2, activation='tanh')(combined)
comb = layers.Dense(1, activation="linear")(comb)
# Accept the inputs of the two branches and then output a single value
model = Model(inputs=[branch_1.input, branch_2.input], outputs=comb)
model.compile(loss='mae', optimizer='adam', metrics=['accuracy'])
# Training
model.fit([x_1_train, x_2_train], y_train, epochs=ep, batch_size=bs)
Now, as the LSTM layer expects a 3D numpy array, I reshape my input data accordingly:
# Data
x_1 = data[['Temp']].values
x_2 = data[['Precip']].values
y = data[['GWL']].values
# Reshape Data
x_1 = np.reshape(x_1, (len(x_1), x_1.shape[1], 1)) # 3D tensor with shape (batch_size, timesteps, input_dim)
x_2 = np.reshape(x_2, (len(x_2), x_2.shape[1], 1))
y = np.reshape(y, (len(y), 1, 1))
Now my input data is of shape:
x_1: (4000, 4, 1)
x_2: (4000, 4, 1)
y: (4000, 1, 1)
as I also use a moving window/lookback of 4 timesteps on my input data.
And here is the problem. Because the moving window/lookback
does not apply to my output, of course.
So I assume that's why I get this error when running the network:
"Error when checking target: expected dense_6 to have shape (4, 1) but got array with shape (1, 1) "
Because it works when I dont apply the moving window. But I need it, so I don't know what to do.
Can anyone help??
You should use model.summary()
to see the output shapes of your layers and model, and then adjust the model and/or the targets accordingly, the problem is that there is a mismatch between the output of the model and the targets.
For example, if you use an LSTM
with return_sequences=True
, then the output of that LSTM is 3D, which is fed into a Dense
that only operates in the last dimension, also outputting a 3D shape. Maybe that is not what you want. You could just set return_sequences=False
to the LSTM layers that are closer to the output, or just flatten if you really need them to output a sequence, so the Dense
layers output 2D shapes, in which case you should reshape the targets as (4000, 1)
.