First, you have a problem in your implementation of encoder using Common LSTM, the LSTM layer of keras take inputs with shape (batch, timesteps, channel) by default, so if you set your input_shape=(32, 15360) then the model will read as timesteps=32 and channel=15360 which is opposite of what you intend to.
Because first layer of encoder using Common LSTM described as:
At each time step t, the first layer takes the input s(·, t)(in this
sense, “common” means that all EEG channels are initially fed8 into
the same LSTM layer)
So the correct implementation of encoder using Common LSTM would be:
import tensorflow as tf
from tensorflow.keras import layers, models
timesteps = 15360
channels_num = 32
model = models.Sequential()
model.add(layers.LSTM(256,input_shape=(timesteps, channels_num), return_sequences=True))
model.add(layers.LSTM(128, return_sequences=True))
model.add(layers.LSTM(64, return_sequences=False))
model.add(layers.Dense(6, activation='softmax'))
model.summary()
Which outputs (PS: you could summarize your original implementation and you will see the Total params is way bigger):
Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
lstm (LSTM) (None, 15360, 256) 295936
_________________________________________________________________
lstm_1 (LSTM) (None, 15360, 128) 197120
_________________________________________________________________
lstm_2 (LSTM) (None, 64) 49408
_________________________________________________________________
dense (Dense) (None, 6) 390
=================================================================
Total params: 542,854
Trainable params: 542,854
Non-trainable params: 0
_________________________________________________________________
Second, because encoder using Channel LSTM and Common LSTM described as:
The first encoding layer consists of several LSTMs, each connected to
only one input channel: for example, the first LSTM processes input
datas(1,·), the second LSTM processess(2,·), and so on. In this way,
the output of each “channel LSTM”is a summary of a single channel’s
data. The second encoding layer then performs inter-channel analysis,
by receiving as input the concatenated output vectors of all channel
LSTMs. As above, the output of the deepest LSTM at the last time step
is used as the encoder’s output vector.
Since each LSTM in the first layer only deal with one channel, so we need the number of LSTM equal to number of channel in the first layer, following code show you how to build one encoder using Channel LSTM and Common LSTM:
import tensorflow as tf
from tensorflow.keras import layers, models
timesteps = 15360
channels_num = 32
first_layer_inputs = []
second_layer_inputs = []
for i in range(channels_num):
l_input = layers.Input(shape=(timesteps, 1))
first_layer_inputs.append(l_input)
l_output = layers.LSTM(1, return_sequences=True)(l_input)
second_layer_inputs.append(l_output)
x = layers.Concatenate()(second_layer_inputs)
x = layers.LSTM(128, return_sequences=True)(x)
x = layers.LSTM(64, return_sequences=False)(x)
outputs = layers.Dense(6, activation='softmax')(x)
model = models.Model(inputs=first_layer_inputs, outputs=outputs)
model.summary()
Outputs:
Model: "functional_1"
__________________________________________________________________________________________________
Layer (type) Output Shape Param # Connected to
==================================================================================================
input_1 (InputLayer) [(None, 15360, 1)] 0
__________________________________________________________________________________________________
input_2 (InputLayer) [(None, 15360, 1)] 0
__________________________________________________________________________________________________
input_3 (InputLayer) [(None, 15360, 1)] 0
__________________________________________________________________________________________________
input_4 (InputLayer) [(None, 15360, 1)] 0
__________________________________________________________________________________________________
input_5 (InputLayer) [(None, 15360, 1)] 0
__________________________________________________________________________________________________
input_6 (InputLayer) [(None, 15360, 1)] 0
__________________________________________________________________________________________________
input_7 (InputLayer) [(None, 15360, 1)] 0
__________________________________________________________________________________________________
input_8 (InputLayer) [(None, 15360, 1)] 0
__________________________________________________________________________________________________
input_9 (InputLayer) [(None, 15360, 1)] 0
__________________________________________________________________________________________________
input_10 (InputLayer) [(None, 15360, 1)] 0
__________________________________________________________________________________________________
input_11 (InputLayer) [(None, 15360, 1)] 0
__________________________________________________________________________________________________
input_12 (InputLayer) [(None, 15360, 1)] 0
__________________________________________________________________________________________________
input_13 (InputLayer) [(None, 15360, 1)] 0
__________________________________________________________________________________________________
input_14 (InputLayer) [(None, 15360, 1)] 0
__________________________________________________________________________________________________
input_15 (InputLayer) [(None, 15360, 1)] 0
__________________________________________________________________________________________________
input_16 (InputLayer) [(None, 15360, 1)] 0
__________________________________________________________________________________________________
input_17 (InputLayer) [(None, 15360, 1)] 0
__________________________________________________________________________________________________
input_18 (InputLayer) [(None, 15360, 1)] 0
__________________________________________________________________________________________________
input_19 (InputLayer) [(None, 15360, 1)] 0
__________________________________________________________________________________________________
input_20 (InputLayer) [(None, 15360, 1)] 0
__________________________________________________________________________________________________
input_21 (InputLayer) [(None, 15360, 1)] 0
__________________________________________________________________________________________________
input_22 (InputLayer) [(None, 15360, 1)] 0
__________________________________________________________________________________________________
input_23 (InputLayer) [(None, 15360, 1)] 0
__________________________________________________________________________________________________
input_24 (InputLayer) [(None, 15360, 1)] 0
__________________________________________________________________________________________________
input_25 (InputLayer) [(None, 15360, 1)] 0
__________________________________________________________________________________________________
input_26 (InputLayer) [(None, 15360, 1)] 0
__________________________________________________________________________________________________
input_27 (InputLayer) [(None, 15360, 1)] 0
__________________________________________________________________________________________________
input_28 (InputLayer) [(None, 15360, 1)] 0
__________________________________________________________________________________________________
input_29 (InputLayer) [(None, 15360, 1)] 0
__________________________________________________________________________________________________
input_30 (InputLayer) [(None, 15360, 1)] 0
__________________________________________________________________________________________________
input_31 (InputLayer) [(None, 15360, 1)] 0
__________________________________________________________________________________________________
input_32 (InputLayer) [(None, 15360, 1)] 0
__________________________________________________________________________________________________
lstm (LSTM) (None, 15360, 1) 12 input_1[0][0]
__________________________________________________________________________________________________
lstm_1 (LSTM) (None, 15360, 1) 12 input_2[0][0]
__________________________________________________________________________________________________
lstm_2 (LSTM) (None, 15360, 1) 12 input_3[0][0]
__________________________________________________________________________________________________
lstm_3 (LSTM) (None, 15360, 1) 12 input_4[0][0]
__________________________________________________________________________________________________
lstm_4 (LSTM) (None, 15360, 1) 12 input_5[0][0]
__________________________________________________________________________________________________
lstm_5 (LSTM) (None, 15360, 1) 12 input_6[0][0]
__________________________________________________________________________________________________
lstm_6 (LSTM) (None, 15360, 1) 12 input_7[0][0]
__________________________________________________________________________________________________
lstm_7 (LSTM) (None, 15360, 1) 12 input_8[0][0]
__________________________________________________________________________________________________
lstm_8 (LSTM) (None, 15360, 1) 12 input_9[0][0]
__________________________________________________________________________________________________
lstm_9 (LSTM) (None, 15360, 1) 12 input_10[0][0]
__________________________________________________________________________________________________
lstm_10 (LSTM) (None, 15360, 1) 12 input_11[0][0]
__________________________________________________________________________________________________
lstm_11 (LSTM) (None, 15360, 1) 12 input_12[0][0]
__________________________________________________________________________________________________
lstm_12 (LSTM) (None, 15360, 1) 12 input_13[0][0]
__________________________________________________________________________________________________
lstm_13 (LSTM) (None, 15360, 1) 12 input_14[0][0]
__________________________________________________________________________________________________
lstm_14 (LSTM) (None, 15360, 1) 12 input_15[0][0]
__________________________________________________________________________________________________
lstm_15 (LSTM) (None, 15360, 1) 12 input_16[0][0]
__________________________________________________________________________________________________
lstm_16 (LSTM) (None, 15360, 1) 12 input_17[0][0]
__________________________________________________________________________________________________
lstm_17 (LSTM) (None, 15360, 1) 12 input_18[0][0]
__________________________________________________________________________________________________
lstm_18 (LSTM) (None, 15360, 1) 12 input_19[0][0]
__________________________________________________________________________________________________
lstm_19 (LSTM) (None, 15360, 1) 12 input_20[0][0]
__________________________________________________________________________________________________
lstm_20 (LSTM) (None, 15360, 1) 12 input_21[0][0]
__________________________________________________________________________________________________
lstm_21 (LSTM) (None, 15360, 1) 12 input_22[0][0]
__________________________________________________________________________________________________
lstm_22 (LSTM) (None, 15360, 1) 12 input_23[0][0]
__________________________________________________________________________________________________
lstm_23 (LSTM) (None, 15360, 1) 12 input_24[0][0]
__________________________________________________________________________________________________
lstm_24 (LSTM) (None, 15360, 1) 12 input_25[0][0]
__________________________________________________________________________________________________
lstm_25 (LSTM) (None, 15360, 1) 12 input_26[0][0]
__________________________________________________________________________________________________
lstm_26 (LSTM) (None, 15360, 1) 12 input_27[0][0]
__________________________________________________________________________________________________
lstm_27 (LSTM) (None, 15360, 1) 12 input_28[0][0]
__________________________________________________________________________________________________
lstm_28 (LSTM) (None, 15360, 1) 12 input_29[0][0]
__________________________________________________________________________________________________
lstm_29 (LSTM) (None, 15360, 1) 12 input_30[0][0]
__________________________________________________________________________________________________
lstm_30 (LSTM) (None, 15360, 1) 12 input_31[0][0]
__________________________________________________________________________________________________
lstm_31 (LSTM) (None, 15360, 1) 12 input_32[0][0]
__________________________________________________________________________________________________
concatenate (Concatenate) (None, 15360, 32) 0 lstm[0][0]
lstm_1[0][0]
lstm_2[0][0]
lstm_3[0][0]
lstm_4[0][0]
lstm_5[0][0]
lstm_6[0][0]
lstm_7[0][0]
lstm_8[0][0]
lstm_9[0][0]
lstm_10[0][0]
lstm_11[0][0]
lstm_12[0][0]
lstm_13[0][0]
lstm_14[0][0]
lstm_15[0][0]
lstm_16[0][0]
lstm_17[0][0]
lstm_18[0][0]
lstm_19[0][0]
lstm_20[0][0]
lstm_21[0][0]
lstm_22[0][0]
lstm_23[0][0]
lstm_24[0][0]
lstm_25[0][0]
lstm_26[0][0]
lstm_27[0][0]
lstm_28[0][0]
lstm_29[0][0]
lstm_30[0][0]
lstm_31[0][0]
__________________________________________________________________________________________________
lstm_32 (LSTM) (None, 15360, 128) 82432 concatenate[0][0]
__________________________________________________________________________________________________
lstm_33 (LSTM) (None, 64) 49408 lstm_32[0][0]
__________________________________________________________________________________________________
dense (Dense) (None, 6) 390 lstm_33[0][0]
==================================================================================================
Total params: 132,614
Trainable params: 132,614
Non-trainable params: 0
__________________________________________________________________________________________________
Now because the model expect inputs with shape (channel, batch, timesteps, 1), so we have to reorder the axis of dataset before feed into model, Following example code show you how to reorder the axis from (batch, timesteps, channel) to (channel, batch, timesteps, 1):
import numpy as np
batch_size = 64
timesteps = 15360
channels_num = 32
x = np.random.rand(batch_size, timesteps, channels_num)
print(x.shape)
x = np.moveaxis(x, -1, 0)[..., np.newaxis]
print(x.shape)
x = [i for i in x]
print(x[0].shape)
Outputs:
(64, 15360, 32)
(32, 64, 15360, 1)
(64, 15360, 1)