2017-04-13 8 views
14

J'ai essayé de construire un CNN avec une couche, mais j'ai un problème avec cela. En effet, le dit que compilator meDimension de la forme dans conv1D

ValueError: Error when checking model input: expected conv1d_1_input to have 3 dimensions, but got array with shape (569, 30)

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

Répondre

35

td; lr vous devez vous remodeler les données pour avoir une dimension spatiale pour Conv1d 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)) 

remodelant essentiellement un ensemble de données qui ressemble à ceci:

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

Pour:

[[.8 
.1 
.3], 

[.2, 
.4, 
.6 
], 

[.3, 
.6 
.1]] 

Explication et exemples

Normalement, la convolution agit sur les dimensions spatiales. Le noyau est "convolu" sur la dimension produisant un tenseur. Dans le cas de Conv1D, le noyau est passé de la dimension 'steps' de chaque exemple.

Vous verrez Conv1D utilisé en NLP où steps est le nombre de mots dans la phrase (rembourré à une longueur maximale fixe). Les mots seraient peut-être codées en tant que vecteurs de longueur 4.

Voici une phrase d'exemple:

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 mettrions l'entrée du 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 allez traiter les entités comme une dimension spatiale avec 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 l'exemple Conv1D comme:

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 ensemble de données doit être remodelé pour (569, 30, 1) utilisation:

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

si j'ai des données avec la dimension 1x690, et j'implémente un Conv1D couche avec 40 filtres de taille 3 du noyau, quand je regarde les poids de cette couche, il dit que j'ai 40 * 690 * 3 poids. Je ne suis pas sûr de comprendre pourquoi, je pensais que je n'aurais que 40 * 3 poids? Comment sort-il une forme 1x40? – jerpint

1

Sans être en mesure de voir plus en détail vos données ne sont pas la bonne forme après traitement préalable.
Reshape X pour avoir 3 dimensions:

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

Mon jeu de données est formé de 30 attributs, 2 classes et 569 valeur. Je ne comprends pas où je dois remodeler mon X – protti

+0

Ainsi sont les valeurs de votre tableau '0's et' 1's? –

+0

Dans le tableau X j'ai les valeurs des attributs, dans YI ont seulement 0 et 1. La forme de X est (569, 30) tandis que Y est (569,) – protti