如何重塑我的输入以将其输入一维卷积层以进行序列分类?

Posted

技术标签:

【中文标题】如何重塑我的输入以将其输入一维卷积层以进行序列分类?【英文标题】:How to reshape my input to feed it into 1D Convolutional layer for sequence classification? 【发布时间】:2017-11-26 02:47:57 【问题描述】:

我有一个包含 339732 行和两列的 csv 文件:

第一个是 29 个特征值,即 X

第二个是二进制标签值,即 Y

dataframe = pd.read_csv("features.csv", header = None) 数据集 = dataframe.values

X = dataset[:, 0:29].astype(float)
Y = dataset[:,29]
X_train, y_train, X_test, y_test = train_test_split(X,Y, random_state = 42)

我正在尝试在一维卷积层上对其进行训练:

model = Sequential()
model.add(Conv1D(64, 3, activation='relu', input_shape=(X_train.shape[0], 29)))
model.add(Conv1D(64, 3, activation='relu'))
model.add(MaxPooling1D(3))
model.add(Conv1D(128, 3, activation='relu'))
model.add(Conv1D(128, 3, activation='relu'))
model.add(GlobalAveragePooling1D())
model.add(Dropout(0.5))
model.add(Dense(1, activation='sigmoid'))

model.compile(loss='binary_crossentropy',
              optimizer='rmsprop',
              metrics=['accuracy'])

model.fit(X_train, y_train, batch_size=16, epochs=2)
score = model.evaluate(X_test, y_test, batch_size=16)

由于 Conv1D 层需要 3-D 输入,我将输入转换如下:

X_train = np.reshape(X_train, (1, X_train.shape[0], X_train.shape[1]))
X_test = np.reshape(X_test, (1, X_test.shape[0], X_test.shape[1]))

但是,这仍然会引发错误:

ValueError: 负维度大小是由 1 减去 3 导致的 'conv1d_1/convolution/Conv2D' (op: 'Conv2D') 输入形状:[?,1,1,29], [1,3,29, 64]。

有什么方法可以正确输入我的输入吗?

【问题讨论】:

【参考方案1】:

据我所知,一维卷积层接受 Batchsize x Width x Channels 形式的输入。你正在重塑

X_train = np.reshape(X_train, (1, X_train.shape[0], X_train.shape[1]))

X_train.shape[0] 是您的batchsize 我猜。我认为问题出在此处。能否请您告诉 X_train 在 reshape 之前的形状是什么?

【讨论】:

reshape 之前,X_train 的形状是 (339732, 29)。此外,在序列的情况下,通道的可能值是多少? (这对图像没有意义吗?) 好的,所以您要做的是将长度为 29 的向量提供给 CNN。有 339732 个这样的向量。您可以将它们中的每一个想象成一个高度为 1、宽度为 29 和通道为 1 的图像。CNN2D 输入形状将是 (1,29,1) 为 (rows,cols,channels)。 CNN1D 输入形状应为 (29,1)。请将 CNN1D 的 X_Train 重塑为 (339732 x 29 x 1),如果您使用的是 CNN2D,则将其重塑为 (339732 x 1 x 29 x 1)。那应该可以。 做了,报错:ValueError: Error when checking model input: expected conv1d_1_input to have shape (None, 339732, 29) but got array with shape (339732, 29, 1) 我的错。将 input_shape 调整为 (29,1) 即可!【参考方案2】:

您必须考虑您的数据在 339732 个条目或 29 个特征之间是否存在某种递进关系,这意味着顺序是否重要。如果不是,我认为 CNN 不适合这种情况。

如果这 29 个特征“表明某事的进展”:

X_train = X_train.reshape((X_train.shape[0], X_train.shape[1],1))

如果 29 个特征是独立的,那么就像图像上的通道,但只有 1 个卷积没有意义。

X_train = X_train.reshape((X_train.shape[0],1, X_train.shape[1]))

如果您想在顺序重要的块中选择 339732 条目(剪切 339732 或添加零填充以便被时间步长整除):

X_train = X_train.reshape((int(X_train.shape[0]/timesteps),timesteps, X_train.shape[1],1))

【讨论】:

以上是关于如何重塑我的输入以将其输入一维卷积层以进行序列分类?的主要内容,如果未能解决你的问题,请参考以下文章

如何将 numpy 数组重塑为 3 维以输入到卷积层?

设置密集层以从一维数组中学习

如何使用 Keras 将一维输入提供给卷积神经网络(CNN)?

卷积模型分类图片

向量化文本作为 RNN 的输入

python 在Keras中重塑卷积的输入数据