Conv1D中形状的维度

68

我尝试使用一个卷积神经网络层来构建模型,但是遇到了一些问题。

实际上,编译器告诉我:

ValueError: 检查模型输入时出错:预计 conv1d_1_input 具有3个维度,但得到的数组形状为 (569, 30)

这是我的代码:

import numpy
from keras.models import Sequential
from keras.layers.convolutional import Conv1D

numpy.random.seed(7)

datasetTraining = numpy.loadtxt("CancerAdapter.csv",delimiter=",")
X = datasetTraining[:,1:31]
Y = datasetTraining[:,0]
datasetTesting = numpy.loadtxt("CancereEvaluation.csv",delimiter=",")
X_test = datasetTraining[:,1:31]
Y_test = datasetTraining[:,0]

model = Sequential()
model.add(Conv1D(2,2,activation='relu',input_shape=X.shape))
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
model.fit(X, Y, epochs=150, batch_size=5)
scores = model.evaluate(X_test, Y_test)

print("\n%s: %.2f%%" % (model.metrics_names[1], scores[1]*100))
5个回答

136

td; lr 你需要重新塑造你的数据,加上一个空间维度,让Conv1d有意义:

X = np.expand_dims(X, axis=2) # reshape (569, 30) to (569, 30, 1) 
# now input can be set as 
model.add(Conv1D(2,2,activation='relu',input_shape=(30, 1))

本质上是重新塑造像这样的数据集:

features    
.8, .1, .3  
.2, .4, .6  
.7, .2, .1  

致:

[[.8.1.3],

[.2, .4, .6 ],

[.7, .2, .1]]
 

解释和示例

通常情况下,卷积操作是在空间维度上执行的。核函数被“卷积”在该维度上并产生一个张量。对于Conv1D来说,核函数会在每个样本的“步数”维度上传递。

在NLP中,你会看到Conv1D被用于处理句子,其中的steps代表填充到固定最大长度的单词数。这些单词将被编码为长度为4的向量。

这里是一个示例句子:

jack   .1   .3   -.52   |
is     .05  .8,  -.7    |<--- kernel is `convolving` along this dimension.
a      .5   .31  -.2    |
boy    .5   .8   -.4   \|/

在这种情况下,我们将输入设置为卷积的方法:

maxlen = 4
input_dim = 3
model.add(Conv1D(2,2,activation='relu',input_shape=(maxlen, input_dim))

在你的情况下,你将把特征视为具有长度1的空间维度。(见下方)

以下是你的数据集示例

att1   .04    |
att2   .05    |  < -- kernel convolving along this dimension
att3   .1     |       notice the features have length 1. each
att4   .5    \|/      example have these 4 featues.

我们将以Conv1D示例为例:

maxlen = num_features = 4 # this would be 30 in your case
input_dim = 1 # since this is the length of _each_ feature (as shown above)

model.add(Conv1D(2,2,activation='relu',input_shape=(maxlen, input_dim))

正如您所看到的,您的数据集需要被重新塑造成(569,30,1) 使用:

X = np.expand_dims(X, axis=2) # reshape (569, 30, 1) 
# now input can be set as 
model.add(Conv1D(2,2,activation='relu',input_shape=(30, 1))

以下是一个完整的示例,您可以运行它(我将使用Functional API

from keras.models import Model
from keras.layers import Conv1D, Dense, MaxPool1D, Flatten, Input
import numpy as np

inp =  Input(shape=(5, 1))
conv = Conv1D(filters=2, kernel_size=2)(inp)
pool = MaxPool1D(pool_size=2)(conv)
flat = Flatten()(pool)
dense = Dense(1)(flat)
model = Model(inp, dense)
model.compile(loss='mse', optimizer='adam')

print(model.summary())

# get some data
X = np.expand_dims(np.random.randn(10, 5), axis=2)
y = np.random.randn(10, 1)

# fit model
model.fit(X, y)

如果我有一个维度为1x690的数据,并且我实现了一个带有40个大小为3的卷积核的Conv1D层,当我查看该层的权重时,它说我有406903个权重。我不确定我理解这是为什么,我以为我只有40*3个权重?它如何输出一个1x40的形状? - jerpint
@parsethis,实际上,您的函数示例即使没有重塑X也可以正常工作。只有使用顺序方法,我才能够再现错误。 - revy

8

我在其他帖子中也提到过:

要将形状为(nrows, ncols)的常规特征表数据输入到Keras的Conv1d中,需要以下2个步骤:

xtrain.reshape(nrows, ncols, 1)
# For conv1d statement: 
input_shape = (ncols, 1)

例如,以鸢尾花数据集的前4个特征为例:
查看通常格式及其形状:
iris_array = np.array(irisdf.iloc[:,:4].values)
print(iris_array[:5])
print(iris_array.shape)

输出显示常规格式及其形状:
[[5.1 3.5 1.4 0.2]
 [4.9 3.  1.4 0.2]
 [4.7 3.2 1.3 0.2]
 [4.6 3.1 1.5 0.2]
 [5.  3.6 1.4 0.2]]

(150, 4)

以下代码改变了格式:
nrows, ncols = iris_array.shape
iris_array = iris_array.reshape(nrows, ncols, 1)
print(iris_array[:5])
print(iris_array.shape)

上述代码的输出数据格式及其形状如下:
[[[5.1]
  [3.5]
  [1.4]
  [0.2]]

 [[4.9]
  [3. ]
  [1.4]
  [0.2]]

 [[4.7]
  [3.2]
  [1.3]
  [0.2]]

 [[4.6]
  [3.1]
  [1.5]
  [0.2]]

 [[5. ]
  [3.6]
  [1.4]
  [0.2]]]

(150, 4, 1)

这对于Keras的Conv1d很有效。需要输入形状为(4,1)


3

我有一个稀疏矩阵作为输入,因此我无法在不将其转换为常规数组的情况下进行重塑

解决方法是使用keras的Reshape层:

from keras.layers.core import Reshape

...
model = Sequential()
model.add(Reshape((X.shape[1], 1), input_shape=(X.shape[1], )))
model.add(Conv1D(2,2,activation='relu'))
...

只有你的支持让我编译成功。其他所有答案仍然会导致我遇到原始错误:ValueError: 检查模型输入时出错:预期 conv1d_1_input 具有 3 个维度,但得到的数组形状为 (569, 30)。 - bobo32

2

在预处理后,如果无法查看更多细节,则您的数据形状不正确。
将X重塑为3个维度:

np.reshape(X, (1, X.shape[0], X.shape[1]))

我的数据集由30个属性、2个类别和569个值组成。 我不明白在哪里需要重新调整我的X。 - protti
你的数组的值是0和1吗? - Marcin Możejko
在X数组中,我有属性的值,在Y中我只有0和1。 X的形状为(569, 30),而Y的形状为(569,)。 - protti
如果您有预处理步骤,可以在此之后重新调整数组。X = np.array(X).reshape(1, X.shape[0], X.shape[1]) - emremrah

0
对于稀疏矩阵,在我的情况下,行数是73196,列数是101。我将稀疏矩阵转换成数组后,使用了numpy的reshape函数:array_ = sparse_matrix.A,然后使用以下代码:
x_train_all = np.reshape(array_ , (73196, 101,1))

在输入层,我使用了以下代码:

input2 = Input(shape=(101,1), dtype='float32', name='input2')

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接