web-dev-qa-db-fra.com

Dimension de la forme dans conv1D

J'ai essayé de construire un CNN avec une couche, mais cela me pose problème. En effet, le compilateur me dit que

ValueError: erreur lors de la vérification de l'entrée du modèle: conv1d_1_input devrait avoir 3 dimensions, mais un tableau avec une forme (569, 30)

C'est le 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))
48
protti

td; lr vous devez redéfinir vos données afin d’avoir une dimension spatiale pour Conv1d afin de donner un sens:

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

Remodelage d'un jeu de données qui ressemble à ceci:

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

À:

[[.8
.1
.3],

[.2,
 .4,
 .6
 ],

[.3,
 .6
 .1]]

Explication et exemples

Normalement, la convolution fonctionne sur des dimensions spatiales. Le noyau est "convolu" sur la dimension produisant un tenseur. Dans le cas de Conv1D, le noyau est transmis sur la dimension 'steps' de chaque exemple.

Vous verrez que Conv1D est utilisé dans la PNL où steps est le nombre de mots de la phrase (complété à une longueur maximale déterminée). Les mots pourraient être codés en tant que vecteurs de longueur 4.

Voici un exemple de phrase:

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

Et la façon dont nous définirions l'entrée à la conv dans ce cas:

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

Dans votre cas, vous traiterez les entités comme une dimension spatiale, chaque entité ayant une longueur de 1. (voir ci-dessous).

Voici un exemple de votre jeu de données

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.

Et nous définirions l'exemple Conv1D comme suit:

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

Comme vous le voyez, votre jeu de données doit être reconfiguré pour (569, 30, 1) utiliser:

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

Voici un exemple à part entière que vous pouvez exécuter (je vais utiliser le API fonctionnelle )

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

J'ai déjà mentionné cela dans d'autres articles:

Pour saisir les données de table de caractéristiques habituelles de forme (nrows, ncols) dans Conv1d de Keras, vous devez suivre les deux étapes suivantes:

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

Par exemple, en prenant les 4 premières caractéristiques du jeu de données iris:

Pour voir le format habituel et sa forme:

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

La sortie montre le format habituel et sa forme:

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

Le code suivant modifie le format:

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

Sortie du format de données de code ci-dessus et de sa forme:

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

Cela fonctionne bien pour Conv1d de Keras. Pour input_shape (4,1) est nécessaire.

3
rnso

Sans pouvoir voir plus de détails, vos données ne sont pas dans la bonne forme après le prétraitement.
Reshape X doit avoir 3 dimensions:

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

J'avais une matrice clairsemée en entrée, donc je ne pouvais pas la remodeler sans avoir recours au tableau habituel

La solution consistait à utiliser la couche 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'))
...
0
Vladimir Smirnov