Pre-trained Networks for Grayscale Images

Hello everyone.
I’m trying to use EfficientNet B0 as a transfer learning approach so I want the weights of pre trained network. Now the problem is I want to use grayscale images (single channel) and a 28x28 size for the images. I have tried different techniques like the below : #Transfer Learning for a 28x28x1
import tensorflow as tf
from tensorflow.keras.applications import EfficientNetB0
from tensorflow.keras.layers import GlobalAveragePooling2D, Dense, Resizing
from tensorflow.keras.models import Model

NUM_CLASSES = 6

Load the pre-trained EfficientNet B0 model

base_model = EfficientNetB0(include_top=False, weights=‘imagenet’, input_shape=None)

Add new layers for your classification task

x = base_model.output
x = GlobalAveragePooling2D()(x)
x = Dense(6, activation=‘softmax’)(x)

Create the new model

inputs = tf.keras.layers.Input(shape=(28, 28, 1))
y = Resizing(224, 224)(inputs)
y = tf.keras.applications.efficientnet.preprocess_input(y)
y = base_model(y)
y = GlobalAveragePooling2D()(y)
outputs = Dense(6, activation=‘softmax’)(y)
model = tf.keras.models.Model(inputs, outputs)

Freeze the weights of the pre-trained layers

for layer in base_model.layers:
layer.trainable = False

But this gave me a warning : WARNING:tensorflow:Model was constructed with shape (None, None, None, 3) for input KerasTensor(type_spec=TensorSpec(shape=(None, None, None, 3), dtype=tf.float32, name=‘input_10’), name=‘input_10’, description=“created by layer ‘input_10’”), but it was called on an input with incompatible shape (None, 224, 224, 1).

I tried moving around with the above snippet but all in vain.
Note my goal is to later go for hardware so I need only grayscale and 28x28 to work how can I make it work for that???

1 Like

@arianagrenade,

Welcome to the Tensorflow Forum!

Here the input shape of the model does not match the input shape of the data you are feeding it. You can modify the input layer of the model to accept gray scale images as shown below

# Load the pre-trained EfficientNet B0 model
base_model = EfficientNetB0(include_top=False, weights='imagenet', input_shape=(28, 28, 1))

Thank you!

1 Like

it does not work. The pre trained model expect 3 channels . This can work by changing ist layer of the network

I saw this but cant replicate for Tensorflow.

@arianagrenade,

If you would like to use pre-trained weights then we need to provide the input has to be three channels as the pre-trained weights are static and calculated based upon the dataset trained.

So if you want to use the architecture with just grey scale input please set weights to None.

base_model = EfficientNetB0(include_top=False, weights=None, input_shape=(32, 32, 1))

However if you are interested in using pre-trained weights convert the gray scale images to rgb images using tf.image.grayscale_to_rgb and reshape the image size according to the input size expected by architecture.

Thank you!

I think in the end what you mean is

base_model = EfficientNetB0(include_top=False, weights=None, input_shape=(32, 32, 3))

And before passing an image to fit or predict make it coloured

newImg = tf.image.grayscale_to_rgb(img) 

I presume you wrote 32 instead of 28 because that is the minimum size?
In that case OP needs to resize 28 to 32 as well.

Is this correct @chunduriv

@Mah_Neh,

Is this correct @chunduriv

Yes.

Thank you!

1 Like