Reputation: 374
I've been trying to solve this for about 24 hours so far but couldn't come up with something unfortunately.
The question is simple: I have 2 categories in 2 sub-directories, the images in the sub-directories are in RGB format but I'm only interested in the Green channel. I read the batches of images using flow_from_directory function (the images @ size (3,224,224) ) then I'm trying to extract the green channel using Lambda layer as follows:
def get_model_bw(input_shape=(3,224,224), classes = 2, lr=1e-4):
model = Sequential([
Lambda(lambda x: x[:,1,:,:], input_shape=input_shape, output_shape=(1,224,224)),
BatchNormalization(axis=1),
Conv2D(32,(3,3), activation='relu',padding='same'),
BatchNormalization(axis=1),
Conv2D(32,(3,3), activation='relu',padding='same'),
BatchNormalization(axis=1),
Conv2D(32,(3,3), activation='relu',padding='same'),
BatchNormalization(axis=1),
MaxPooling2D(),
Conv2D(64,(3,3), activation='relu',padding='same'),
BatchNormalization(axis=1),
Conv2D(64,(3,3), activation='relu',padding='same'),
BatchNormalization(axis=1),
Conv2D(64,(3,3), activation='relu',padding='same'),
BatchNormalization(axis=1),
MaxPooling2D(),
Conv2D(128,(3,3), activation='relu',padding='same'),
BatchNormalization(axis=1),
Conv2D(128,(3,3), activation='relu',padding='same'),
BatchNormalization(axis=1),
MaxPooling2D(),
Conv2D(256,(3,3), activation='relu',padding='same'),
BatchNormalization(axis=1),
Conv2D(256,(3,3), activation='relu',padding='same'),
BatchNormalization(axis=1),
MaxPooling2D(),
Conv2D(512,(3,3), activation='relu',padding='same'),
BatchNormalization(axis=1),
Conv2D(512,(3,3), activation='relu',padding='same'),
BatchNormalization(axis=1),
MaxPooling2D(),
Flatten(),
Dense(1000, activation='relu'),
BatchNormalization(),
Dense(1000, activation='relu'),
BatchNormalization(),
Dense(classes, activation='softmax')
])
model.compile(Adam(lr=lr), loss='categorical_crossentropy', metrics=['accuracy'])
return model
model_bw = get_model_bw(input_shape=(3,224,224), classes=2)
But it just refuses to work... The error that it's throwing is:
ValueError Traceback (most recent call last) ValueError: Input 0 is incompatible with layer batch_normalization_181: expected ndim=4, found ndim=3
any suggestions? P.S. I'm using Theano backend and the newest keras version.
Any help would be greatly appreciated.
Upvotes: 0
Views: 614
Reputation: 374
I can't believe but I found the solution:
The lambda layer:
from keras import backend as K
Lambda(lambda x: K.expand_dims(x[:,1,:,:],1), input_shape=input_shape, output_shape=(1,224,224)),
Upvotes: 0
Reputation: 86640
First you must check if you're using the data format channels_first
or channels_last
. (It seems you're using channels first, by your input shape)
Keras' default is channels_last
. You can see that in the keras.json
file in your user folder: <user>\.keras\keras.json
. And this can also be set individually for each layer.
The lambda layer
When you work with shapes outside layers, such as input_shape=(3,224,224)
, you don't specify the batch size (the number of images).
But inside the lambda layer (whenever you're working directly on tensors), the batch size will appear as the first dimension, so, your channels are not in the first dimension, but in the second:
Lambda(lambda x: x[:,1,:,:], input_shape=input_shape, output_shape=outputshape)
Of course, your output shape cannot be the same as the input shape, it must be (1,224,224)
The following layers:
Don't add input_shape
to other layers, only to the first layer (which is the lambda layer)
Show the error messages if anything goes wrong.
Upvotes: 0