apikerasfunctional-programminglstmmultiple-input

Keras Functional API Input shape Errors


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??


Solution

  • 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).