我想使用1D CONV层跟随LSTM层分类16通道400的时间步长信号。
输入形状由以下部分组成:
X = (n_samples, n_timesteps, n_features),其中n_samples=476n_timesteps=400n_features=16是信号的样本数量、时间步长和特征(或通道)。
y = (n_samples, n_timesteps, 1)每一个标记都被标记为0或1(二进制分类)。
我使用1d conv提取时间信息,如下图所示。F=32K=8是过滤器和内核大小。在1D-CONV之后使用1D最大池。32单元LSTM用于信号分类。模型应该返回一个y_pred = (n_samples, n_timesteps, 1)
python - 如何在Keras中设置1D卷积和LSTM-LMLPHP
代码段如下所示:

input_layer = Input(shape=(dataset.n_timestep, dataset.n_feature))
conv1 = Conv1D(filters=32,
               kernel_size=8,
               strides=1,
               activation='relu')(input_layer)
pool1 = MaxPooling1D(pool_size=4)(conv1)
lstm1 = LSTM(32)(pool1)
output_layer = Dense(1, activation='sigmoid')(lstm1)
model = Model(inputs=input_layer, outputs=output_layer)

模型概要如下:
python - 如何在Keras中设置1D卷积和LSTM-LMLPHP
但是,我得到了以下错误:
ValueError: Error when checking target: expected dense_15 to have 2 dimensions, but got array with shape (476, 400, 1).

我想问题是形状不对。请告诉我怎么修理它。
另一个问题是时间步长。因为在1D CONV中分配了input_shape,如何让LSTM知道时间步长必须是400?
我想根据@today的建议添加模型图。在这种情况下,LSTM的时间步长为98。在这种情况下,我们需要使用时间分布吗?我没能应用在conv1d中分配的时间。
python - 如何在Keras中设置1D卷积和LSTM-LMLPHP
不管怎样,都要执行通道之间的卷积,而不是时间步长吗?例如,滤波器(2, 1)遍历每个时间步长,如下图所示。
python - 如何在Keras中设置1D卷积和LSTM-LMLPHP
谢谢。

最佳答案

如果你想为每一个时间步预测一个值,我会想到两个稍微不同的解决方案:
1)删除MaxPooling1D层,将padding='same'参数添加到Conv1D层,并将return_sequence=True参数添加到LSTM,使LSTM返回每一个时间步的输出:

from keras.layers import Input, Dense, LSTM, MaxPooling1D, Conv1D
from keras.models import Model

input_layer = Input(shape=(400, 16))
conv1 = Conv1D(filters=32,
               kernel_size=8,
               strides=1,
               activation='relu',
               padding='same')(input_layer)
lstm1 = LSTM(32, return_sequences=True)(conv1)
output_layer = Dense(1, activation='sigmoid')(lstm1)
model = Model(inputs=input_layer, outputs=output_layer)

model.summary()

模型总结将是:
Layer (type)                 Output Shape              Param #
=================================================================
input_4 (InputLayer)         (None, 400, 16)           0
_________________________________________________________________
conv1d_4 (Conv1D)            (None, 400, 32)           4128
_________________________________________________________________
lstm_4 (LSTM)                (None, 400, 32)           8320
_________________________________________________________________
dense_4 (Dense)              (None, 400, 1)            33
=================================================================
Total params: 12,481
Trainable params: 12,481
Non-trainable params: 0
_________________________________________________________________

2)只需将密集层中的单元数更改为400,然后将y重新形状为(n_samples, n_timesteps)
from keras.layers import Input, Dense, LSTM, MaxPooling1D, Conv1D
from keras.models import Model

input_layer = Input(shape=(400, 16))
conv1 = Conv1D(filters=32,
               kernel_size=8,
               strides=1,
               activation='relu')(input_layer)
pool1 = MaxPooling1D(pool_size=4)(conv1)
lstm1 = LSTM(32)(pool1)
output_layer = Dense(400, activation='sigmoid')(lstm1)
model = Model(inputs=input_layer, outputs=output_layer)

model.summary()

模型总结将是:
_________________________________________________________________
Layer (type)                 Output Shape              Param #
=================================================================
input_6 (InputLayer)         (None, 400, 16)           0
_________________________________________________________________
conv1d_6 (Conv1D)            (None, 393, 32)           4128
_________________________________________________________________
max_pooling1d_5 (MaxPooling1 (None, 98, 32)            0
_________________________________________________________________
lstm_6 (LSTM)                (None, 32)                8320
_________________________________________________________________
dense_6 (Dense)              (None, 400)               13200
=================================================================
Total params: 25,648
Trainable params: 25,648
Non-trainable params: 0
_________________________________________________________________

不要忘记,在这两种情况下,必须使用'binary_crossentropy'(而不是'categorical_crossentropy')作为损失函数。我希望这个解决方案的精度比解1的精度要低,但是你必须同时试验这两个参数并尝试改变参数,因为它完全取决于你要解决的具体问题和你所拥有的数据的性质。
更新:
你需要一个卷积层,它只覆盖一个时间步长和k个相邻特征。是的,您可以使用conv2d层:
# first add an axis to your data
X = np.expand_dims(X)   # now X has a shape of (n_samples, n_timesteps, n_feats, 1)

# adjust input layer shape ...
conv2 = Conv2D(n_filters, (1, k), ...)   # covers one timestep and k features
# adjust other layers according to the output of convolution layer...

虽然我不知道为什么要这样做,但是要使用卷积层(即(?, n_timesteps, n_features, n_filters))的输出,一个解决方案是使用一个封装在时间分布层中的lstm层。或者另一个解决方案是使最后两个轴变平。

关于python - 如何在Keras中设置1D卷积和LSTM,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51344610/

10-10 15:57