Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Keras CNN images and kernel size mismatch even after image transformation to fit

I'm trying to run a CNN similar to the one in the Keras documantation "VGG-like convnet" but for a custom set of images and binary classification instead of a 10-class output.

When I try to fit the CNN, i get this longwinded error that I assume is telling me my input image size is not the right size for the CNN input.

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

The thing is I thought I reshaped all my images to fit. My input is a stack of 4000 232x300 px RBG images and the output is an array of 4000 boolean values.

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

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

This is the function to build the 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

I've been banging my head against the wall with this long enough that I thought maybe someone else has had this problem. Any thoughts? Thanks in advance.

like image 730
marko Avatar asked Apr 04 '16 00:04

marko


2 Answers

You specified input as (depth,width,height). So the array you must must have dimensions (N,depth,width,height), where N is the number of training examples.

The input you are actually passing, (4000, 232, 300, 3), doesn't match. It should be reshaped to be (4000, depth, width, height). This means you'll have to resize each image, and reorder the axes.

like image 183
yhenon Avatar answered Sep 18 '22 06:09

yhenon


The above answer is correct: for posterity, my problem was solved by a simple:

im_list = im_list.transpose((0,3,1,2))
like image 33
marko Avatar answered Sep 22 '22 06:09

marko