keras cnn_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 modelmodel=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,451Trainable params: 45,451Non-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,355Trainable params: 6,355Non-trainable params: 0_________________________________________________________________

如果你愿意,可以向LSTM层传递return_sequences=True参数,并保留Flatten层。但只有在你尝试了第一种方法并且结果不理想之后才这样做,因为添加return_sequences=True可能完全没有必要,它只会增加模型大小并降低模型性能。


顺便提一下:为什么你在第二个模型中将损失函数改为sparse_categorical_crossentropy?没有必要这样做,因为binary_crossentropy可以很好地工作。

Related Posts

在使用k近邻算法时,有没有办法获取被使用的“邻居”?

我想找到一种方法来确定在我的knn算法中实际使用了哪些…

Theano在Google Colab上无法启用GPU支持

我在尝试使用Theano库训练一个模型。由于我的电脑内…

准确性评分似乎有误

这里是代码: from sklearn.metrics…

Keras Functional API: “错误检查输入时:期望input_1具有4个维度,但得到形状为(X, Y)的数组”

我在尝试使用Keras的fit_generator来训…

如何使用sklearn.datasets.make_classification在指定范围内生成合成数据?

我想为分类问题创建合成数据。我使用了sklearn.d…

如何处理预测时不在训练集中的标签

已关闭。 此问题与编程或软件开发无关。目前不接受回答。…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注