将 1D CNN 层连接到 keras 中的 LSTM 层

问题描述 投票:0回答:1

我有一个模型构建,如下所示:

def og_build_model_5layer(n_rows,n_cols):
  input = Input(shape=(n_cols,n_rows),NAME='INP')
  print('model_input shape:' , input.shape)

  c1 = Conv1D(50, 3,name = 'conv_1',padding='same',kernel_initializer="glorot_uniform")(INP)
  b1 = BatchNormalization(name = 'BN_1')(c1)       
  a1 = Activation('relu')(b1)

  c2 = Conv1D(50,3,name = 'conv_2',padding='same',kernel_initializer="glorot_uniform")(a1)
  b2 = BatchNormalization(name = 'BN_2')(c2)
  a2 = Activation('relu')(b2)

  c3 = Conv1D(50, 3,name = 'conv_3',padding='same',kernel_initializer="glorot_uniform")(a2)
  b3 = BatchNormalization(name = 'BN_3')(c3)
  a3 = Activation('relu')(b3)

  c4 = Conv1D(50, 3,name = 'conv_4',padding='same',kernel_initializer="glorot_uniform")(a3)
  b4 = BatchNormalization(name = 'BN_4')(c4)
  a4 = Activation('relu')(b4)

  c5 = Conv1D(50, 3,name = 'conv_5',padding='same',kernel_initializer="glorot_uniform")(a4)
  b5 = BatchNormalization(name = 'BN_5')(c5)
  a5 = Activation('relu')(b5)
  ######## ADD one LSTM layer HERE ##################
  
  fl = Flatten(name='fl')(LSTM_OUTPUT)
  den = Dense(30,name='dense_1')(fl)
  drp = Dropout(0.5)(den)
  output = Dense(1, activation='sigmoid')(drp)    
  opt = Adam(learning_rate=1e-4)
  model = Model(inputs=INP, outputs=output, name='model')
  extractor = Model(inputs=ecg_input,outputs = model.get_layer('fl').output)
  model.compile(optimizer=opt, loss='binary_crossentropy', metrics=['accuracy'])
  print(model.summary)
  return model,extractor

这里我有 5 个 Conv1D 层(每个层接受一张图像),我想添加一个 LSTM 层,它将一起处理 200 张图像的序列,并且我想端到端地训练这个 CNN+LSTM 模型。我对如何添加 LSTM 层感到困惑,因为它需要一个序列(200 个已处理的输入),而前面的 5 层一次只能接受一个输入。感谢这里的任何帮助。我知道时间分布式 conv1D 的概念,但我不想使用它。这种端到端的训练可以完成吗?

tensorflow keras deep-learning lstm conv1d
1个回答
0
投票

现在可能为时已晚,但如果以后有人偶然发现这个问题,这就是我解决它的方法。

我有一个和你类似的问题需要解决。老实说,我并不完全理解您希望使用的架构。就我而言,我有两个独立的 CNN,它们需要通过 LSTM 并在全连接层之前连接输出。

我犯的错误是在扁平化 CNN 的输出后使用 LSTM。 LSTM 采用 3 维输入,而扁平化 CNN 输出为 2 维。我通过在展平 LSTM 数据之前传递它来解决这个问题。这是部分代码。

from tensorflow.keras import layers
x1 = layers.Conv1D(
            filters=16,
            kernel_size=2,
            activation="relu",
            strides=1,
            input_shape=(24, 1),
        )(input_data1)
        x1 = layers.MaxPooling1D(pool_size=3, strides=1, padding="valid")(x1)
        x1 = layers.LSTM(64)(x1)
        x1 = layers.Flatten()(x1)

你的情况看起来很简单,你可以简单地在后面添加:

######## ADD one LSTM layer HERE ##################
layers.LSTM(64)(a5)

请注意,LSTM 的输入是 3D 张量。对 CNN 的输出进行扁平化后,您将得到一个 2D 张量。那根本不行。否则,我上面的建议应该有效!

© www.soinside.com 2019 - 2024. All rights reserved.