python - keras cnn_lstm 输入层不接受一维输入

标签 python machine-learning keras conv-neural-network lstm

我有我要分类的长一维向量序列(3000 位)。我之前实现了一个简单的 CNN 来对它们进行分类并取得了相对成功:

def create_shallow_model(shape,repeat_length,stride):
    model = Sequential()
    model.add(Conv1D(75,repeat_length,strides=stride,padding='same', input_shape=shape, activation='relu'))
    model.add(MaxPooling1D(repeat_length))
    model.add(Flatten())
    model.add(Dense(1, activation='sigmoid'))
    model.compile(loss='binary_crossentropy', optimizer='rmsprop', metrics=['accuracy'])
    return model

不过,我希望通过在网络末端堆叠 LSTM/RNN 来提高性能。

我在这方面遇到了困难,因为我似乎无法找到网络接受数据的方法。

def cnn_lstm(shape,repeat_length,stride):
    model = Sequential()
    model.add(TimeDistributed(Conv1D(75,repeat_length,strides=stride,padding='same', activation='relu'),input_shape=(None,)+shape))
    model.add(TimeDistributed(MaxPooling1D(repeat_length)))
    model.add(TimeDistributed(Flatten()))
    model.add(LSTM(6,return_sequences=True))
    model.add(Dense(1,activation='sigmoid'))
    model.compile(loss='sparse_categorical_crossentropy', optimizer='rmsprop', metrics=['accuracy'])
    return model

model=cnn_lstm(X.shape[1:],1000,1)
tprs,aucs=calculate_roc(model,3,100,train_X,train_y,test_X,test_y,tprs,aucs)

但是我得到以下错误:

ValueError: Error when checking input: expected time_distributed_4_input to have 4 dimensions, but got array with shape (50598, 3000, 1)

我的问题是:

  1. 这是分析这些数据的正确方法吗?

  2. 如果是这样,我如何让网络接受输入序列并对其进行分类?

最佳答案

无需添加那些 TimeDistributed 包装器。目前,在添加 LSTM 层之前,您的模型如下所示(我假设 repeat_length=5stride=1):

Layer (type)                 Output Shape              Param #   
=================================================================
conv1d_2 (Conv1D)            (None, 3000, 75)          450       
_________________________________________________________________
max_pooling1d_1 (MaxPooling1 (None, 600, 75)           0         
_________________________________________________________________
flatten_2 (Flatten)          (None, 45000)             0         
_________________________________________________________________
dense_4 (Dense)              (None, 1)                 45001     
=================================================================
Total params: 45,451
Trainable params: 45,451
Non-trainable params: 0
_________________________________________________________________

所以如果你想添加一个 LSTM 层,你可以把它放在 MaxPooling1D 层之后,比如 model.add(LSTM(16, activation='relu')) 并删除 Flatten 层。现在模型看起来像这样:

_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv1d_4 (Conv1D)            (None, 3000, 75)          450       
_________________________________________________________________
max_pooling1d_3 (MaxPooling1 (None, 600, 75)           0         
_________________________________________________________________
lstm_1 (LSTM)                (None, 16)                5888      
_________________________________________________________________
dense_5 (Dense)              (None, 1)                 17        
=================================================================
Total params: 6,355
Trainable params: 6,355
Non-trainable params: 0
_________________________________________________________________

如果您愿意,可以将 return_sequences=True 参数传递给 LSTM 层并保留 Flatten 层。但是,只有在尝试了第一种方法并且结果很差之后才做这样的事情,因为添加 return_sequences=True 可能根本没有必要,它只会增加模型大小并降低模型性能。


附带说明:为什么在第二个模型中将损失函数更改为 sparse_categorical_crossentropy?没有必要这样做,因为 binary_crossentropy 可以正常工作。

关于python - keras cnn_lstm 输入层不接受一维输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51992336/

相关文章:

Python - 保存除大属性之外的整个类对象

python - 从 Raspberry Pi 上的麦克风读取频率

machine-learning - 欧氏距离

machine-learning - IBM Watson API 是否从我的数据中学习?

python - 使用函数式 API 进行迁移学习和量化感知训练

python - 向 Pygame 应用程序添加 GUI 的最佳方式是什么?

amazon-web-services - 如何在 Spark MLLib 中为支持向量机配置内核选择和损失函数

python - 我无法在 gridsearch 中添加优化器参数

python - 如何将 `tf.scatter_nd` 与多维张量一起使用

python - Numpy 或 pandas : test whether upper or lower bound is reached in array/series, 哪个先到达