Dimensión de forma en conv1D

He intentado construir una CNN con una capa, pero tengo algún problema con ella. De hecho, el comstackdor me dice que

ValueError: error al verificar la entrada del modelo: se esperaba que conv1d_1_input tuviera 3 dimensiones, pero tenía una matriz con forma (569, 30)

Este es el codigo

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 lr necesita remodelar sus datos para tener una dimensión espacial para que Conv1d tenga sentido:

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

Esencialmente remodelando un conjunto de datos que se ve así:

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

A:

 [[.8 .1 .3], [.2, .4, .6 ], [.3, .6 .1]] 

Explicación y ejemplos.

Normalmente la convolución funciona sobre dimensiones espaciales. El núcleo está “convuelto” sobre la dimensión produciendo un tensor. En el caso de Conv1D, el kernel se pasa sobre la dimensión ‘pasos’ de cada ejemplo.

Verá que se usa Conv1D en NLP, donde los steps son el número de palabras en la oración (rellenado hasta cierta longitud máxima fija). Las palabras podrían estar codificadas como vectores de longitud 4.

Aquí hay una oración de ejemplo:

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

Y la forma en que estableceríamos la entrada al conv en este caso:

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

En su caso, tratará las características como una dimensión espacial, ya que cada característica tiene la longitud 1. (ver más abajo)

Aquí sería un ejemplo de su conjunto de datos

 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. 

Y estableceríamos el ejemplo de Conv1D como:

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

Como usted ve, su conjunto de datos tiene que ser remodelado para (569, 30, 1) uso:

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

Aquí hay un ejemplo completo que puede ejecutar (usaré la API funcional )

 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) 

Sin poder ver más detalles, sus datos no están en la forma correcta después del preprocesamiento.
Remodelar X para tener 3 dimensiones:

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

También he mencionado esto en otros mensajes:

Para ingresar una tabla de características habituales de forma (nrows, ncols) a Conv1d de Keras, se necesitan los siguientes 2 pasos:

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

Por ejemplo, tomando las primeras 4 características del conjunto de datos del iris:

Para ver el formato habitual y su forma:

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

La salida muestra el formato habitual y su forma:

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

El siguiente código altera el formato:

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

Salida del formato de datos del código anterior y su forma:

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

Esto funciona bien para Conv1d de Keras. Para input_shape (4,1) es necesario.