首页 文章

如何在Keras中设置1D-Convolution和LSTM

提问于
浏览
0

我想使用LSTM层之后的1D-Conv层来对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 是过滤器和kernel_size . 在1D-Conv之后使用1D-MaxPooling . 32单元LSTM用于信号分类 . 该模型应返回 y_pred = (n_samples, n_timesteps, 1) .

enter image description here

代码段如下所示:

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)

模型摘要如下所示:

enter image description here

但是,我收到以下错误:

ValueError: Error when checking target: expected dense_15 to have 2 dimensions, but got array with shape (476, 400, 1).

我猜问题是形状不正确 . 请让我知道如何解决它 .

另一个问题是时间步数 . 因为 input_shape 是在1D-Conv中分配的,我们怎么能让LSTM知道时间步长必须是400?


我想根据@today的建议添加模型图 . 在这种情况下,LSTM的时间步长将为98.在这种情况下我们是否需要使用TimeDistributed?我未能在Conv1D中应用TimeDistributed .

enter image description here

无论如何,在 Channels 之间进行卷积而不是时间步长?例如,过滤器(2,1)遍历每个时间步,如下图所示 .
enter image description here

谢谢 .

2 回答

  • 2

    如果你想为每个时间步长预测一个值,我会想到两个略有不同的解决方案:

    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) 只需将Dense图层中的单位数更改为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;但您必须尝试两者并尝试更改参数,因为它完全取决于您尝试解决的具体问题以及您拥有的数据的性质 .


    Update:

    您要求的卷积层仅覆盖一个时间步长和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) ,一种解决方案是使用包裹在TimeDistributed层内的LSTM层 . 或者另一种解决方案是将最后两个轴展平 .

  • 0

    输入和输出形状是(476,400,16)和(476,1) - 这意味着它只是每个完整序列输出一个值 .

    你的LSTM没有撤回序列(return_sequences = False) . 但即使你在LSTM之前进行Conv1D和MaxPooling也会挤压输入 . 所以LSTM本身将获得(98,32)的样本 .

    我假设你想为每个输入步骤输出一个输出 .

    假设Conv1D和MaxPooling对于输入数据是相关的,您可以尝试seq到seq方法,其中您将第一个N / W的输出提供给另一个网络以获得400个输出 .

    我建议你看一下像编码器解码器seq2seq网络这样的模型,如下所示

    https://blog.keras.io/a-ten-minute-introduction-to-sequence-to-sequence-learning-in-keras.html

    https://machinelearningmastery.com/define-encoder-decoder-sequence-sequence-model-neural-machine-translation-keras/

相关问题