如何使用TimeDsitributed层进行神经网络集成(特别是CNN + LSTM)?



所以这是我尝试的两种方法中的第一种:

inputs=Input(shape=(frames, 103*4, 1))
z=TimeDistributed(Conv2D(32, (5,25), padding='same', activation='relu'), input_shape=(frames, 103*4, 1))(inputs)
z=TimeDistributed(BatchNormalization())(z)
z=TimeDistributed(ReLU())(z)
z=TimeDistributed(Dropout(0.2))(z)
z=TimeDistributed(MaxPooling2D(pool_size=(1,2)))(z)
z=TimeDistributed(Conv2D(32, (3,5), padding='same', activation='relu'))(z)
z=TimeDistributed(BatchNormalization())(z)
z=TimeDistributed(ReLU())(z)
z=TimeDistributed(Dropout(0.2))(z)
z=TimeDistributed(MaxPooling2D(pool_size=(1,2)))(z)
z=TimeDistributed(Flatten())(z)
z=LSTM(1000, dropout=0.1, recurrent_dropout=0.2, return_sequences=True)(z)
z=LSTM(1000, dropout=0.1, recurrent_dropout=0.2, return_sequences=True)(z)
z=LSTM(1000, dropout=0.1, recurrent_dropout=0.2, return_sequences=True)(z)
z=Flatten()(z)
z=Dense(1000, activation='relu')(z)
z=Dropout(0.5)(z)
z=Dense(500, activation='relu')(z)
z=Dropout(0.5)(z)
z=Dense(200, activation='relu')(z)
z=Dropout(0.5)(z)
outputs=Dense(88, activation='sigmoid')(z)

我收到此错误(尽管我的代码中任何地方都没有 2 的步幅大小):

ValueError: strides should be of length 1, 1 or 3 but was 2

我已经看过这个问题,似乎我已经实现了代码中给出的建议。但是问题出在哪里呢?我无法掌握它。

最后,我设法通过Keras的FunctionalAPI将CNN和LSTM结合起来:

inputs=Input(shape=(frames, 103*4, 1))
z=Conv2D(32, (5,25), padding='same', activation='relu')(inputs)
z=BatchNormalization()(z)
z=ReLU()(z)
z=Dropout(0.2)(z)
z=MaxPooling2D(pool_size=(1,2))(z)
z=Conv2D(32, (3,5), padding='same', activation='relu')(z)
z=BatchNormalization()(z)
z=ReLU()(z)
z=Dropout(0.2)(z)
z=MaxPooling2D(pool_size=(1,2))(z)
z=TimeDistributed(Flatten())(z)
z=LSTM(1000, dropout=0.1, recurrent_dropout=0.2, return_sequences=True)(z)
z=LSTM(1000, dropout=0.1, recurrent_dropout=0.2, return_sequences=True)(z)
z=LSTM(1000, dropout=0.1, recurrent_dropout=0.2, return_sequences=True)(z)
z=Flatten()(z)
z=Dense(1000, activation='relu')(z)
z=Dropout(0.5)(z)
z=Dense(500, activation='relu')(z)
z=Dropout(0.5)(z)
z=Dense(200, activation='relu')(z)
z=Dropout(0.5)(z)
outputs=Dense(88, activation='sigmoid')(z)

model=Model(inputs=inputs, outputs=outputs)

它有效,但如果这是正确的方法,我仍然不知所措。我可以通过model.summary()看到我的 TimeDstributed 包装器具有输出形状(None, 7, 3296),并且所有 LSTM 层的输出形状(None, 7, 1000)。我应该改变什么才能给它中心框架而不是 7 个框架?

说到我的数据集,我给出了 7 帧频率值的振幅来预测中心帧的值。

我假设您想在帧维度上应用 TimeDistributed 层,这使得我们的输入是发送到卷积层的 2 维。 如果是这种情况,那么您应该使用 Conv1D 而不是 Conv2D。相应地更改内核大小。 同时相应地将 Maxpooling2D 更改为 Maxpooling1D。

例如。

z=TimeDistributed(Conv1D(32, 2, padding='same', activation='relu'))(inputs)

@priyach 你是对的,但正如我所看到的,我对我的数据集给出了一个有点糟糕的解释。我有 2d 数组,时间在 x 轴上,频率在 y 轴上(试图根据有关频率的信息预测正在播放的音符)

因此,如果我将2D阵列的列(每个列代表给定时间的所有频率)馈送到我的网络中,那么Conv1D和MaxPooling1D将是正确的选择

但是我没有将列作为输入,而是将每列作为输入,每列的左侧有 3 个列,右侧有3 个列(或者使用零填充,然后我无法获得列)。所以我的输入本质上是2d的,我把它当作图像。

我设法创建了另一个网络(CNN+DNN+LSTM+DNN),并在第一个LSTM层之前使用了Reshape层(而不是TimeDistributed)。

问题仍然存在(出于好奇和未来的编程)。我对TimeDistributed层的使用有什么问题?

最新更新