2016-04-04 11 views
6

Ich versuche, ein CNN ähnlich dem in der Keras documantation "VGG-like convnet" aber für eine benutzerdefinierte Reihe von Bildern und binäre Klassifizierung statt einer 10-Klasse-Ausgabe.Keras CNN Bilder und Kernel-Größe stimmen nicht überein, auch nach der Bildumwandlung passen

Wenn ich versuche, das CNN zu passen, bekomme ich diesen langwierigen Fehler, der mir sagt, dass meine Eingangsbildgröße nicht die richtige Größe für den CNN-Eingang hat.

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

Die Sache ist, ich dachte, ich habe alle meine Bilder umgestaltet. Meine Eingabe ist ein Stapel von 4000 232x300 px RBG-Bildern und die Ausgabe ist ein Array von 4000 booleschen Werten.

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

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

Dies ist die Funktion die CNN zu bauen

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 

Ich habe mit diesem langen meinen Kopf gegen die Wand hämmern worden genug, dass ich dachte, dass vielleicht jemand anderes dieses Problem hatte. Irgendwelche Gedanken? Danke im Voraus.

Antwort

6

Sie haben den Eingang als (depth,width,height) eingegeben. Das Array muss also die Dimensionen (N,depth,width,height) haben, wobei N die Anzahl der Trainingsbeispiele ist.

Die Eingabe, die Sie gerade übergeben, (4000, 232, 300, 3), stimmt nicht überein. Es sollte so umgestaltet werden, dass es (4000, depth, width, height) ist. Das bedeutet, dass Sie die Größe jedes Bildes ändern und die Achsen neu anordnen müssen.

+0

Dank, dass es gelöst! – marko

6

Die obige Antwort ist richtig: für die Nachwelt, war mein Problem durch eine einfache gelöst:

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