Train CNN on the "green" channel from RGB images
See original GitHub issueHello everyone, I’m trying to train my model just on the G channel from my images and to compare the results with training on the entire RGB.
My images are located in 2 sub-directories so I’m using the “flow_from_directory” function to read them.
I’ve also defined a preprocessing function that should have done this “Green extraction” for me:
def preprocess(x): return K.expand_dims(x[1,:,:],0)
and this is my model:
def get_model(input_shape=(3,256,256), classes = 2, lr=1e-4, channels=3):
model = Sequential([
Lambda(preprocess, input_shape=input_shape, output_shape=(channels,)+ input_shape[1:]),
BatchNormalization(axis=1),
Convolution2D(32,3,3, activation='relu',border_mode='same'),
BatchNormalization(axis=1), bla bla bla,...
BatchNormalization(),
Dense(1000, activation='relu'),
BatchNormalization(),
Dense(classes, activation='softmax')
])
model.compile(Adam(lr=lr), loss='categorical_crossentropy', metrics=['accuracy'])
return model
def get_batches(dirname, gen=image.ImageDataGenerator(), shuffle=True, batch_size=8, class_mode='categorical', target_size=(256,256),color='rgb'): return gen.flow_from_directory(dirname, target_size=target_size, class_mode=class_mode, shuffle=shuffle, batch_size=batch_size, color_mode=color)
this is my main code:
path = '/home/ubuntu/images/'
test_batches = get_batches(path+'valid', target_size=(224,224))
model = get_model(input_shape=(3,224,224),channels=1)
model.fit_generator(test_batches, samples_per_epoch=test_batches.nb_sample, nb_epoch=1)
when I run it I get the following error:
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=‘half’, subsample=(1, 1), conv_mode=‘conv’, precision=‘float32’}.0, Constant{1.0}, Constant{0.0}) Toposort index: 458 Inputs types: [CudaNdarrayType(float32, (True, False, False, False)), CudaNdarrayType(float32, 4D), CudaNdarrayType(float32, (True, False, False, False)), <theano.gof.type.CDataType object at 0x7f0b120ab090>, Scalar(float32), Scalar(float32)] Inputs shapes: [(1, 3, 224, 224), (32, 1, 3, 3), (1, 32, 224, 224), ‘No shapes’, (), ()] Inputs strides: [(0, 50176, 224, 1), (9, 0, 3, 1), (0, 50176, 224, 1), ‘No strides’, (), ()] Inputs values: [‘not shown’, ‘not shown’, ‘not shown’, <capsule object NULL at 0x7f0afa9d46c0>, 1.0, 0.0] Inputs name: (‘image’, ‘kernel’, ‘output’, ‘descriptor’, ‘alpha’, ‘beta’)
Outputs clients: [[GpuElemwise{add,no_inplace}(GpuDnnConv{algo=‘small’, inplace=True}.0, GpuDimShuffle{x,0,x,x}.0)]]
HINT: Re-running with most Theano optimization disabled could give you a back-trace of when this node was created. This can be done with by setting the Theano flag ‘optimizer=fast_compile’. If that does not work, Theano optimizations can be disabled with ‘optimizer=None’. HINT: Use the Theano flag ‘exception_verbosity=high’ for a debugprint and storage map footprint of this apply node.
How to fix it? Any help would be greatly appreciated.
Issue Analytics
- State:
- Created 6 years ago
- Comments:6 (1 by maintainers)
I found the solution to my problem -
the pre processing function should be as follows:
def preprocess(x): return K.expand_dims(x[:,1,:,:],1)
Knowing the channel order and which channel do you intent do use you can use the sub array access. To avoid losing dimension when filtering single channel, you just need to specify the range like:
In my case, as I’m using a RGB image, the “1:2” will ensure I get the green channel without losing any dimension
print(x[:,:,:,1:2] ) # -> print(x[:,:,:,1:2] -> Tensor("sequential/lambda/strided_slice:0", shape=(None, height, width, 1), dtype=float32)