2016-04-04 48 views
6

Sto tentando di eseguire una CNN simile a quella nello Keras documantation "VGG-like convnet" ma per un set personalizzato di immagini e classificazione binaria invece di un output di 10 classi.Keras Immagini CNN e mancata corrispondenza delle dimensioni del kernel anche dopo la trasformazione dell'immagine per adattarsi

Quando provo ad adattare la CNN, ottengo questo errore di lunga durata che presumo mi stia dicendo che la dimensione dell'immagine in ingresso non è delle dimensioni corrette per l'input CNN.

ValueError: GpuDnnConv images and kernel must have the same stack size 

Apply node that caused the error: GpuDnnConv{algo='small', inplace=True}(GpuContiguous.0, GpuContiguous.0, GpuAllocEmpty.0, GpuDnnConvDesc{border_mode='valid', subsample=(1, 1), conv_mode='conv', precision='float32'}.0, Constant{1.0}, Constant{0.0}) 
Toposort index: 130 
Inputs types: [CudaNdarrayType(float32, 4D), CudaNdarrayType(float32, 4D), CudaNdarrayType(float32, 4D), <theano.gof.type.CDataType object at 0x7f0eefc8d790>, Scalar(float32), Scalar(float32)] 
Inputs shapes: [(32, 232, 300, 3), (300, 1, 3, 3), (32, 300, 298, 1), 'No shapes',(),()] 
Inputs strides: [(208800, 900, 3, 1), (9, 0, 3, 1), (89400, 298, 1, 0), 'No strides',(),()] 
Inputs values: ['not shown', 'not shown', 'not shown', <PyCObject object at 0x7f0efaba8e68>, 1.0, 0.0] 
Inputs name: ('image', 'kernel', 'output', 'descriptor', 'alpha', 'beta') 

Il fatto è che ho pensato di rimodellare tutte le mie immagini per adattarle. Il mio input è una pila di 4000 immagini RBG da 232x300 px e l'output è una matrice di 4000 valori booleani.

ingresso: im_list.shape Out[49]: (4000, 232, 300, 3)

uscita: np.asarray(cls).shape Out[50]: (4000,)

Questa è la funzione di costruire la CNN

CNN = buildCNN(3, 232, 300, 2) 
CNN.fit(im_list, cls, batch_size=32, nb_epoch=1) 

    def buildCNN(depth,width,height,outputShape): 
    CNN = Sequential() 
     # input: 232x300 images with 3 channels -> (3, 100, 100) tensors. 
     # this applies 32 convolution filters of size 3x3 each. 
     CNN.add(Convolution2D(32, 3, 3, border_mode='valid', input_shape=(depth,width,height))) 
     CNN.add(Activation('relu')) 
     CNN.add(Convolution2D(32, 3, 3)) 
     CNN.add(Activation('relu')) 
     CNN.add(MaxPooling2D(pool_size=(2, 2))) 
     CNN.add(Dropout(0.25)) 
     # 
     CNN.add(Convolution2D(64, 3, 3, border_mode='valid')) 
     CNN.add(Activation('relu')) 
     CNN.add(Convolution2D(64, 3, 3)) 
     CNN.add(Activation('relu')) 
     CNN.add(MaxPooling2D(pool_size=(2, 2))) 
     CNN.add(Dropout(0.25)) 
     # 
     CNN.add(Flatten()) 
     # Note: Keras does automatic shape inference. 
     CNN.add(Dense(256)) 
     CNN.add(Activation('relu')) 
     CNN.add(Dropout(0.5)) 
     # 
     CNN.add(Dense(outputShape)) 
     CNN.add(Activation('softmax')) 
     # 
     sgd = SGD(lr=0.1, decay=1e-6, momentum=0.9, nesterov=True) 
     CNN.compile(loss='categorical_crossentropy', optimizer=sgd) 
     # 
    return CNN 

ho sbattere la testa contro il muro con questa lunga abbastanza da pensare che forse qualcun altro ha avuto questo problema. qualche idea? Grazie in anticipo.

risposta

6

L'input specificato è (depth,width,height). Quindi l'array deve avere dimensioni (N,depth,width,height), dove N è il numero di esempi di addestramento.

L'ingresso che si sta effettivamente passando, (4000, 232, 300, 3), non corrisponde. Dovrebbe essere rimodellato per essere (4000, depth, width, height). Ciò significa che dovrai ridimensionare ogni immagine e riordinare gli assi.

+0

grazie che risolto! – marko

6

La risposta di cui sopra è corretta: per i posteri, il mio problema è stato risolto con un semplice:

im_list = im_list.transpose((0,3,1,2))