grayscale input for keras InceptionV3 - keras

I have made this network which seems to work ok.
datagen = tf.keras.preprocessing.image.ImageDataGenerator(
#zoom_range=0.2,
#shear_range=0.2,
#rotation_range=10,
rescale=1/255,
validation_split=0.2,
# other things...
)
train_ds = datagen.flow_from_directory(
data_dir,
subset="training",
class_mode='binary',
target_size=target_size,
batch_size=batch_size,
)
val_ds = datagen.flow_from_directory(
data_dir,
subset="validation",
class_mode='binary',
target_size=target_size,
batch_size=batch_size,
)
pre_trained_model = InceptionV3(input_shape=(128,128,3),
include_top=False,
weights='imagenet')
for layer in pre_trained_model.layers:
layer.trainable = False
global_average_layer = tf.keras.layers.GlobalAveragePooling2D()
Dl_1 = tf.keras.layers.Dropout(rate = 0.2)
prediction_layer = tf.keras.layers.Dense(1,activation='sigmoid')
model_V3 = tf.keras.Sequential([
pre_trained_model,
global_average_layer,
Dl_1,
prediction_layer
])
model_V3.compile(optimizer='adam',
loss='binary_crossentropy',
metrics=['accuracy'])
lr_reduce = ReduceLROnPlateau(monitor='val_loss', factor=0.2, patience=3, verbose=2, mode='max')
hist = model_V3.fit(
train_ds,
epochs=5,
steps_per_epoch=len(train_ds),
validation_data=val_ds,
validation_steps=len(val_ds),
callbacks=[lr_reduce])
However the issue here is that the network is built for RGB images. My data is grayscale images. Right now I am just replicating channels so that R,G and B get same value for each pixel.
The problem is that this is extremely memory consuming and slow.
Is there a way to make the network use graylevel images instead of rgb?
Is there maybe another pretrained network which is better to classify grayscale images of elliptic cell-like structures?

When importing InceptionV3 try this:
pre_trained_model = InceptionV3(input_shape=(128,128,1),
include_top=False,
weights='imagenet')
128 and 128 are the physical dimensions of your image and the 3 (or 1 in my case) are the color channels.

Related

how to overfit a model on a single batch in keras?

I am trying to overfit my model on a single batch to check model integrity. I am using Keras and TensorFlow for the implementation of my model and coding style for this project.
I know how to get the single batch and overfit the model in PyTorch but don't have an idea in Keras.
to get a single batch in PyTorch I used:
images, labels = next(iter(train_dataset))
criterion = torch.nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr = 0.0001)
for epoch in range(epochs):
print(f"Epoch [{epoch}/{epochs}]")
# for batch_idx, (data, target) in enumerate(train_loader):
data, target = data.to(device), target.to(device)
data = data.reshape(data.shape[0], -1)
# forward
score = model(data)
loss = criterion(score, target)
print(f"Loss: {loss.item()}")
# backward
optimizer.zero_grad()
loss.backward()
optimizer.step()
How to do it in keras any helping matrial?
Thank you everyone for coming here. I found a solution and here it is:
datagen = ImageDataGenerator(rescale=1 / 255.0,
rotation_range=20,
zoom_range=0.2,
width_shift_range=0.05,
height_shift_range=0.05,
shear_range=0.2,
horizontal_flip=True,
fill_mode="nearest"
)
# preprocessing_function=preprocess_input,
# Declare an image generator for validation & testing without generation
test_datagen = ImageDataGenerator(rescale = 1./255,)#preprocessing_function=preprocess_input
# Declare generators for training, validation, and testing from DataFrames
train_gen = datagen.flow_from_directory(directory_train,
target_size=(512, 512),
color_mode='rgb',
batch_size=BATCH_SIZE,
class_mode='binary',
shuffle=True)
val_gen = test_datagen.flow_from_directory(directory_val,
target_size=(512, 512),
color_mode='rgb',
batch_size=BATCH_SIZE,
class_mode='binary',
shuffle=False)
test_gen = test_datagen.flow_from_directory(directory_test,
target_size=(512, 512),
color_mode='rgb',
batch_size=BATCH_SIZE,
class_mode='binary',
shuffle=False)
train_images, train_labels = next(iter(train_gen))
val_images, val_labels = next(iter(val_gen))
test_images, test_labels = next(iter(val_gen))
#check shape for selected Batch
print("Length of Train images : {}".format(len(train_images)))
print("shape of Train images : {}".format(train_images.shape))
print("shape of Train labels : {}".format(train_labels.shape))
Length of Train images : 32
shape of Train images : (32, 512, 512, 3)
shape of Train labels : (32,)
history = model.fit(train_images, train_labels,
use_multiprocessing=True,
workers=16,
epochs=100,
class_weight=class_weights,
validation_data=(val_images, val_labels),
shuffle=True,
callbacks=call_backs)

10% accuracy during training, however the prediction using same model on train data gives only 3.5% accuracy

I'm training the VGG16 block5 with code below over 100 iterations/epochs, adding up two dense and dropout layer after the output of block5.
seq = Sequential()
vgg_base = VGG16(weights='imagenet', input_shape=(224, 224, 3),include_top=False, pooling='avg')
seq.add(vgg_base)
for layer in vgg_base.layers:
layer.trainable = False
for layer in vgg_base.layers[:14]:
layer.trainable = False
for layer in vgg_base.layers[15:]:
layer.trainable = True
regularizer = tf.keras.regularizers.l2(1e-2)
for layer in vgg_base.layers[15:]:
for attr in ['kernel_regularizer']:
if hasattr(layer, attr):
setattr(layer, attr, regularizer)
vgg_base.summary()
#seq.add(Flatten())
input_a = Input(shape=(224, 224, 3))
out_a = seq(input_a)
hidden1 = Dense(128, activation='relu', name='dense_1', kernel_regularizer=tf.keras.regularizers.l2(0.001),
activity_regularizer=tf.keras.regularizers.l2(0.001))(out_a)
hidden_drp1 = Dropout(0.5)(hidden1)
hidden2 = Dense(32, activation='relu', name='dense_2',kernel_regularizer=tf.keras.regularizers.l2(0.001),
activity_regularizer=tf.keras.regularizers.l2(0.001))(hidden_drp1)
hidden_drp2 = Dropout(0.2)(hidden2)
out = Dense(1, activation='sigmoid', name='dense_3')(hidden_drp2)
model = Model(input_a, out)
Training settings:
if os.path.exists(filepath):
print('weights found... loading...')
model.load_weights(filepath)
train_datagen = ImageDataGenerator(rescale=1.0/255)
#,validation_split=0.4)
# validation_split=0.3) # set validation split
train_path = 'C:/fromtrainv4/'
train_set = train_datagen.flow_from_directory(
train_path,
target_size=(224,224),
shuffle=True,
color_mode='rgb',
batch_size=100,
class_mode='binary')
optim = Adam(lr=0.001)
loss = 'binary_crossentropy'
metrics = ['binary_accuracy', 'acc']
model.compile(loss=loss,
optimizer=optim,
metrics=metrics)
checkpoint = ModelCheckpoint(filepath,
monitor='loss',
verbose=1,
save_weights_only=False,
save_best_only=True,
mode='min')
my_callback = [tf.keras.callbacks.EarlyStopping(monitor='loss', patience=10),
checkpoint,tf.keras.callbacks.TensorBoard(log_dir='C:\\traning_logs\\')]
step_size_train = train_set.n//train_set.batch_size
history = model.fit_generator(train_set,
steps_per_epoch=step_size_train,
shuffle=False,
epochs=100,
callbacks=my_callback,
class_weight='balanced')
I have made sure that the data has same scaling as image_generator and everything else.
I load the model using code below:
from tensorflow.keras.models import load_model
model = load_model('C:/models/model.h5')
System Specs:
Processor: Intell Xeon
Ram: 16GB
GPU: NVIDIA RTX 2080 Super
Memory: M2. 256GB
Interpreter: Spyder Python 3.7.1
tensorflow version: 1.14.0
keras version: 2.3.1
Can someone guide me what I might be doing wrong. Please let me know if more information regarding this is required.
I would guess that your model is doing what is called "overfitting".
In short, by doing 100 train iterations of the same dataset, it kind of memorized by heart your train dataset and thus have a good result when tested on it. However it doesn't yet find a general answer to your problem which lead to lower results when testing with a new dataset with different inputs.

fit_generator issue using Neural Structured learning

I passed two days trying to use Neural Structured language to adapt into me CNN Model I use ImageDataGenerator and flow_from_directory when I use model.fit_generator I got an error message:
ValueError:
When passing input data as arrays, do not specify
steps_per_epoch/steps argument. Please use batch_size instead.
I use Keras 2.3.1 and TensorFlow 2.0 as backend
This is a snipped of my code:
num_classes = 4
img_rows, img_cols = 224, 224
batch_size = 16
train_datagen = ImageDataGenerator(
rescale=1./255,
rotation_range=30,
width_shift_range=0.3,
height_shift_range=0.3,
horizontal_flip=True,
fill_mode='nearest')
validation_datagen = ImageDataGenerator(rescale=1./255)
train_generator = train_datagen.flow_from_directory(
train_data_dir,
target_size=(img_rows, img_cols),
batch_size=batch_size, shuffle=True,
class_mode='categorical')
validation_generator = validation_datagen.flow_from_directory(
validation_data_dir,
target_size=(img_rows, img_cols),
batch_size=batch_size, shuffle=True,
class_mode='categorical')
def vgg():
model1 = Sequential([ ])
return model1
base_model = vgg()
I adapte Datagenerated from (x,y) format to a dictionary format
def convert_training_data_generator():
for x ,y in train_generator:
return {'feature': x, 'label':y}
def convert_testing_data_generator():
for x ,y in validation_generator:
return {'feature': x, 'label': y}
adv_config = nsl.configs.make_adv_reg_config(multiplier=0.2, adv_step_size=0.05)
model = nsl.keras.AdversarialRegularization(base_model, adv_config=adv_config)
train= convert_training_data_generator()
test= convert_testing_data_generator()
history = model.fit_generator(train,
steps_per_epoch= nb_train_samples // batch_size,
epochs = epochs,
callbacks = callbacks,
validation_data = test,
validation_steps = nb_validation_samples // batch_size)
I think here there is the same error. Maybe you should consider using instead model.fit() function. You should define in that case your train input your train labels and the batch_size. In order to figure out the difference between fit and fit_generator, you can follow that link.

Keras seed does not augment images and masks the same

I'm trying to transform my images and mask labels in sync, but the random augmentations are applied differently to both generators (proven when I save both images to a directory).
I've tried
seeding all generators in my library stack
disabling shuffle and multiprocessing
ensuring augmentation options are identical between images and masks
One thing that did work was setting batch size to 1, but then my training performance suffered.
seed_val=0
data_gen_args = dict(
rescale=1./255,
horizontal_flip=True,
validation_split=validation_split)
image_datagen = ImageDataGenerator(**data_gen_args)
mask_datagen = ImageDataGenerator(**data_gen_args)
image_generator = image_datagen.flow_from_directory(
'data/x/train_images/',
target_size=(224, 224),
color_mode='rgb',
class_mode=None,
batch_size=batch_size,
subset='training',
save_to_dir='tmp/img/',
seed=seed_val)
mask_generator = mask_datagen.flow_from_directory(
'data/x/train_annotations/',
target_size=(224, 224),
color_mode='grayscale',
class_mode=None,
batch_size=batch_size,
subset='training',
save_to_dir='tmp/mask/',
seed=seed_val)
train_generator = zip((image_generator), (mask_generator))
try setting shuffle to False to both image and mask
image_generator = image_datagen.flow_from_directory(
'data/x/train_images/',
target_size=(224, 224),
shuffle = False,
color_mode='rgb',
class_mode=None,
batch_size=batch_size,
subset='training',
save_to_dir='tmp/img/',
seed=seed_val)
mask_generator = mask_datagen.flow_from_directory(
'data/x/train_annotations/',
target_size=(224, 224),
shuffle = False,
color_mode='grayscale',
class_mode=None,
batch_size=batch_size,
subset='training',
save_to_dir='tmp/mask/',
seed=seed_val)
I had the problem that my augmentations for the images and masks weren't in the same order, e.g.
img: pan, increase brightness, transform, rgbshift
mask: pan, transform
With that, "increase brightness" changes the value from the seed. Should be
img: pan, transform, increase brightness, rgbshift
mask: pan, transform

Keras methods 'predict' and 'predict_generator' with different result

I have trained a basic CNN model for image classification.
While training the model I have used ImageDataGenerator from keras api.
After the model is being trained i used testdatagenerator and flow_from_directory method for testing.
Everything Went well.
Then I saved the model for future use.
Now i am using the same model and used predict method from keras api with a single image, but the prediction is very different every time I test using different images.
Could you please let me know any solution.
training_augmentation = ImageDataGenerator(rescale=1 / 255.0)
validation_testing_augmentation = ImageDataGenerator(rescale=1 / 255.0)
# Initialize training generator
training_generator = training_augmentation.flow_from_directory(
JPG_TRAIN_IMAGE_DIR,
class_mode="categorical",
target_size=(32, 32),
color_mode="rgb",
shuffle=True,
batch_size=batch_size
)
# initialize the validation generator
validation_generator = validation_testing_augmentation.flow_from_directory(
JPG_VAL_IMAGE_DIR,
class_mode="categorical",
target_size=(32, 32),
color_mode="rgb",
shuffle=False,
batch_size=batch_size
)
# initialize the testing generator
testing_generator = validation_testing_augmentation.flow_from_directory(
JPG_TEST_IMAGE_DIR,
class_mode="categorical",
target_size=(32, 32),
color_mode="rgb",
shuffle=False,
batch_size=batch_size
)
history = model.fit_generator(
training_generator,
steps_per_epoch=total_img_count_dict['train'] // batch_size,
validation_data=validation_generator,
validation_steps=total_img_count_dict['val'] // batch_size,
epochs=epochs,
callbacks=callbacks)
testing_generator.reset()
prediction_stats = model.predict_generator(testing_generator, steps=(total_img_count_dict['test'] // batch_size) + 1)
### Trying to use predict method
img_file = '/content/drive/My Drive/Traffic_Sign_Recognition/to_display_output/Copy of 00003_00019.jpg'
img = cv2.imread(img_file)
img=cv2.resize(img, (32,32))
img = img/255.0
a=np.reshape(img, (1, 32, 32, 3))
model = load_model('/content/drive/My Drive/Traffic_Sign_Recognition/basic_cnn.h5')
prediction = model.predict(a)
When I am trying to use predict, every time wrong prediction is coming.
Any leads will be appreciated.
Keras generator uses PIL for image reading which read images from disk as RGB.
You are using opencv for reading which reads images as BGR. You have to convert your image from BGR to RGB.
img = cv2.imread(img_file)
img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
...

Resources