简体   繁体   English

conv1D 中的形状尺寸

[英]Dimension of shape in conv1D

I have tried to build a CNN with one layer, but I have some problem with it.我曾尝试用一层构建 CNN,但我遇到了一些问题。 Indeed, the compilator says me that确实,编译器说我

ValueError: Error when checking model input: expected conv1d_1_input to have 3 dimensions, but got array with shape (569, 30) ValueError:检查模型输入时出错:预期 conv1d_1_input 有 3 个维度,但得到了形状为 (569, 30) 的数组

This is the code这是代码

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))

td; td; lr you need to reshape you data to have a spatial dimension for Conv1d to make sense: 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))

Essentially reshaping a dataset that looks like this:本质上是重塑一个看起来像这样的数据集:

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

To:到:

[[.8
.1
.3],

[.2,
 .4,
 .6
 ],

[.3,
 .6
 .1]]

Explanation and examples解释和例子

Normally convolution works over spatial dimensions.通常卷积适用于空间维度。 Kernel is "convolved" over the dimension producing a tensor.内核在产生张量的维度上“卷积”。 In the case of Conv1D, the kernel is passed of over the 'steps' dimension of every example.在 Conv1D 的情况下,内核在每个示例的“步骤”维度上传递。

You will see Conv1D used in NLP where steps is number of words in the sentence (padded to some fixed maximum length).您将看到 NLP 中使用的 Conv1D,其中steps是句子中的单词数(填充到某个固定的最大长度)。 The words would might be encoded as vectors of length 4.这些词可能被编码为长度为 4 的向量。

Here is an example sentence:下面是一个例句:

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

And the way we would set the input to the conv in this case:在这种情况下,我们将输入设置为 conv 的方式:

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

In your case you will treat the features as spatial dimension with each feature having length 1. (see below)在您的情况下,您会将特征视为空间维度,每个特征的长度为 1。(见下文)

Here would be an example from your dataset这是您数据集中的一个示例

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.

And we would set the Conv1D example as:我们将 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))

As you see your dataset has to be reshaped in to (569, 30, 1) use:如您所见,您的数据集必须重新调整为 (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))

Here is a full-fledged example that you can run (I'll use the Functional API )这是您可以运行的完整示例(我将使用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)

I have mentioned this in other posts also:我在其他帖子中也提到过:

To input a usual feature table data of shape (nrows, ncols) to Conv1d of Keras, following 2 steps are needed:要将形状(nrows, ncols)的常用特征表数据输入到 Keras 的 Conv1d,需要执行以下 2 个步骤:

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

For example, taking first 4 features of iris dataset:例如,取 iris 数据集的前 4 个特征:

To see usual format and its shape:要查看通常的格式及其形状:

iris_array = np.array(irisdf.iloc[:,:4].values)
print(iris_array[:5])
print(iris_array.shape)

The output shows usual format and its 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)

Following code alters the format:以下代码更改格式:

nrows, ncols = iris_array.shape
iris_array = iris_array.reshape(nrows, ncols, 1)
print(iris_array[:5])
print(iris_array.shape)

Output of above code data format and its 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)

This works well for Conv1d of Keras.这适用于 Keras 的 Conv1d。 For input_shape (4,1) is needed.对于input_shape (4,1)是需要的。

I had a sparse matrix as input, so I couldn't reshape it without casting to usual array我有一个稀疏矩阵作为输入,所以我无法在不转换为通常的数组的情况下对其进行整形

The solution was to use the keras Reshape layer:解决方案是使用 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'))
...

Without being able to see more detail your data is not in the right shape after preprocessing.如果无法查看更多细节,您的数据在预处理后的形状不正确。
Reshape X to have 3 dimensions:将 X 整形为 3 个维度:

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

For sparse matrix, in my case, rows: 73196, column : 101 I used reshape function of numpy after converting my sparse matrix to array by array_ = sparse_matrix.A then I used below code对于稀疏矩阵,在我的情况下,行:73196,列:101 在通过array_ = sparse_matrix.A将我的稀疏矩阵转换为数组后,我使用了 numpy 的 reshape 函数,然后我使用了下面的代码

x_train_all = np.reshape(array_ , (73196, 101,1))

and in the input layer I used below code:在输入层中,我使用了以下代码:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM