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.
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.
The above answer is correct: for posterity, my problem was solved by a simple:
im_list = im_list.transpose((0,3,1,2))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With