Keras CNN-LSTM RuntimeError - python

I'm trying to use the following model Inceptionv3 base CNN and LSTM layer for a regression problem. My input data is pictures with continuous target values. I'd like to feed the sequence of images to a CNN and after to an LSTM layer. However i get a
RuntimeError: You must compile your model before using it
message. Any idea what can be the cause? I tried to find out in github and on several pages but i didnt succeed.
from keras.applications.inception_v3 import InceptionV3
from keras.models import Sequential, Model
from keras.preprocessing.image import ImageDataGenerator
from keras.layers import Dense, Activation, Flatten, Dropout, BatchNormalization, Conv2D, MaxPooling2D, GlobalAveragePooling2D, LSTM, TimeDistributed, Input
from keras.optimizers import SGD, RMSprop
from keras.callbacks import EarlyStopping, ModelCheckpoint, CSVLogger, ReduceLROnPlateau
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
# custom R2-score metrics for keras backend
#https://www.kaggle.com/c/mercedes-benz-greener-manufacturing/discussion/34019
from keras import backend as K
def r2_keras(y_true, y_pred):
SS_res = K.sum(K.square(y_true - y_pred))
SS_tot = K.sum(K.square(y_true - K.mean(y_true)))
return ( 1 - SS_res/(SS_tot + K.epsilon()) )
train_data_dir = '...'
test_data_dir = '...'
train_df = pd.read_csv('...')
valid_df = pd.read_csv('...')
filepath_loss = '...'
filepath_csv = '...'
datagen=ImageDataGenerator(rescale=1./255.,)
img_width, img_height = 380, 380
frames = 5
channels = 3
pictures = Input(shape=(frames, img_width, img_height, channels))
train_generator=datagen.flow_from_dataframe(
dataframe=train_df,
directory=train_data_dir,
x_col="block_heights",
y_col="weighted_prices",
has_ext=False, #x_col column doesnt has the file extensions
#subset="training", if validation split is set in ImageDataGenerator
batch_size=16,
seed=42,
shuffle=False,
class_mode="other", #for regression other should be used
target_size=(img_width, img_height))
valid_generator=datagen.flow_from_dataframe(
dataframe=valid_df,
directory=train_data_dir,
x_col="block_heights",
y_col="weighted_prices",
has_ext=False, #x_col column doesnt has the file extensions
#subset="validation", if validation split is set in ImageDataGenerator
batch_size=16,
seed=42,
shuffle=False,
class_mode="other",
target_size=(img_width, img_height))
conv_base = InceptionV3(weights=None, include_top=False, input_shape=(img_width,img_height,3))
conv_base.trainable = True
model = Sequential()
model.add(TimeDistributed(conv_base))
model.add(TimeDistributed(Flatten()))
model.add(LSTM(10, return_sequences=True))
model.add(Dense(512, activation='relu'))
model.add(Dense(1, activation='linear'))
#error at callbacks if the learning rate is explicitly set somewhere
rms = RMSprop(lr=0.1, rho=0.9, epsilon=None, decay=0.0)
model.compile(loss='mse', optimizer=rms, metrics=['mae', r2_keras])
STEP_SIZE_TRAIN=train_generator.n//train_generator.batch_size
STEP_SIZE_VALID=valid_generator.n//valid_generator.batch_size
callbacks = [EarlyStopping(monitor='val_loss', patience=10, verbose=1, mode='auto'),
ReduceLROnPlateau(monitor='val_loss', factor=0.02, patience=3, min_lr=0.001),
ModelCheckpoint(filepath_loss, monitor='val_loss', verbose=1, save_best_only=True, mode='min'),
CSVLogger(filepath_csv, separator = ",", append = False)]
history = model.fit_generator(generator=train_generator,steps_per_epoch=STEP_SIZE_TRAIN, validation_data=valid_generator, validation_steps=STEP_SIZE_VALID, epochs=50, callbacks=callbacks)

Related

How to get resnet50 model to predict?

I am following a tutorial to create a deep learning model that takes ct scan images and detects from the ct scan whether its covid or not using resnet50
The model summary :
Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
resnet50 (Functional) (None, 2048) 23587712
flatten (Flatten) (None, 2048) 0
dropout (Dropout) (None, 2048) 0
dense (Dense) (None, 2) 4098
=================================================================
Total params: 23,591,810
Trainable params: 1,059,842
Non-trainable params: 22,531,968
when I try to predict using this :
pred=model.predict(img)
pr_cl=np.argmax(pred,axis=1)
i get output :
array([0], dtype=int64)
the output remains same for both covid and non-covid images
There are 2 classes (COVID and non-COVID) :
Found 1986 images belonging to 2 classes.
Found 495 images belonging to 2 classes.
How do i get the proper prediction from model showing whether its covid or not ?
Full Code :
import tensorflow as tf
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, MaxPooling2D
from tensorflow.keras.layers import Activation, Dropout, Flatten, Dense, BatchNormalization
import os
import pandas as pd
import numpy as np
import cv2
base_dir = r'\filepath for dataset'
img_h,img_w= (164,164)
batch_size=32
epochs=10
from tensorflow.keras.preprocessing.image import ImageDataGenerator
datagen= ImageDataGenerator(rescale=1./255,validation_split=0.2)
from tensorflow.keras.applications.resnet import ResNet50
from tensorflow.keras.applications.vgg19 import VGG19, preprocess_input
#from tensorflow.keras.applications.mobilenet_v2 import MobileNetV2
from tensorflow.keras.layers import Flatten,Dense,Dropout,BatchNormalization
from tensorflow.keras.models import Model,Sequential
from tensorflow.keras.utils import to_categorical
from tensorflow.keras.layers import Conv2D, MaxPooling2D, BatchNormalization
from tensorflow.keras.layers import PReLU
from tensorflow.keras.optimizers import RMSprop
from tensorflow.keras.callbacks import ReduceLROnPlateau
base_model= ResNet50(include_top=False, weights='imagenet',
input_tensor=None, input_shape=(img_h,img_w,3), pooling='avg')
for layer in base_model.layers[:-7]:
layer.trainable=False
model=Sequential()
model.add(base_model)
model.add(Flatten())
model.add(Dropout(0.4))
model.add(Dense(2,activation='softmax'))
model.summary()
for layer in base_model.layers:
print(layer,"-->",layer.trainable)
from tensorflow.keras.optimizers import Adam,SGD,Adagrad,Adadelta,RMSprop
from tensorflow.keras.callbacks import ReduceLROnPlateau
reduce_learning_rate = ReduceLROnPlateau(monitor='loss',
factor=0.1,
patience=3,
cooldown=2,
min_lr=1e-10,
verbose=1)
checkpoint =tf.keras.callbacks.ModelCheckpoint(filepath="reswtk.h5",
monitor='val_accuracy',
verbose=1,
save_best_only=True,
save_weights_only=False,
mode='auto',
save_freq='epoch')
import time
class TimeHistory(tf.keras.callbacks.Callback):
def on_train_begin(self, logs={}):
self.times = []
def on_epoch_begin(self, batch, logs={}):
self.epoch_time_start = time.time()
def on_epoch_end(self, batch, logs={}):
self.times.append(time.time() - self.epoch_time_start)
time_callback = TimeHistory()
callbacks = [reduce_learning_rate, checkpoint, time_callback]
optimizer = RMSprop(lr=0.001, rho=0.9, epsilon=1e-08, decay=0.0)
model.compile( loss='categorical_crossentropy',optimizer= optimizer, metrics=['accuracy'])
train_generator = datagen.flow_from_directory(
base_dir, # This is the source directory for training images
target_size=(img_h, img_w),
batch_size=batch_size,
class_mode='categorical',
subset='training',
#color_mode="rgb",
shuffle=True)
validation_generator = datagen.flow_from_directory(
base_dir,
target_size=(img_h, img_w),
batch_size=batch_size,
class_mode='categorical',
#color_mode="rgb",
subset='validation',
shuffle=False)
history = model.fit(
train_generator,
steps_per_epoch=train_generator.samples//batch_size,
epochs=epochs,
validation_data=validation_generator,
validation_steps=validation_generator.samples//batch_size,
callbacks=callbacks,
verbose=1)
model.evaluate(validation_generator,verbose=1)
accu= history.history['val_accuracy']
print(max(accu),"at epoch number-",accu.index(max(accu))+1)
img = cv2.imread("\filepath for png file")
image_resized= cv2.resize(img, (img_h,img_w))
cv2.imshow('CT scan', img)
cv2.waitKey(0)
img=np.expand_dims(image_resized,axis=0)
img.shape
pred=model.predict(img)
pr_cl=np.argmax(pred,axis=1)

Shape incompatible error while using ImageDataGenerator for transfer learning

I want to create a classification model. For this purpose I have collected some images from 3 different classes. First, I have implemented Xception model ( freezed all layers except the last one). However, it overfitted. Then, I have decided to use data augmentation strategy. This is the first time I have used Keras module for this purpose. I belive that I have correctly used it. But getting error ValueError: Shapes (None, None) and (None, None, None, 3) are incompatible. I have tried what I found from the web, but did not works. Can anyone point the what I am doing wrong? Here is the code.
from tensorflow import keras
from matplotlib import pyplot as plt
from keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.preprocessing import image
from tensorflow.keras.applications.imagenet_utils import preprocess_input
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Dropout, Flatten, Activation
from tensorflow.keras.layers import Conv2D, MaxPooling2D
from tensorflow.keras.models import Model
# this is the augmentation configuration we will use for training
train_datagen = ImageDataGenerator(
rescale=1./255,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True)
# this is the augmentation configuration we will use for testing:
# only rescaling
test_datagen = ImageDataGenerator(rescale=1./255)
# this is a generator that will read pictures found in
# subfolers of 'data/train', and indefinitely generate
# batches of augmented image data
train_generator = train_datagen.flow_from_directory(
'data2/train', # this is the target directory
target_size=(299, 299), # all images will be resized to 299x299 for the Xception
batch_size=32,
class_mode="categorical")
# this is a similar generator, for validation data
validation_generator = test_datagen.flow_from_directory(
'data2/validation',
target_size=(299, 299),
batch_size=32,
class_mode="categorical")
Xception = keras.applications.Xception(weights='imagenet', include_top=False)
num_classes=3
inp = Xception.input
new_classification_layer = Dense(num_classes, activation='softmax')
out = new_classification_layer(Xception.layers[-2].output)
model_Xception = Model(inp, out)
model_Xception.summary()
for l, layer in enumerate(model_Xception.layers[:-1]):
layer.trainable = False
for l, layer in enumerate(model_Xception.layers[-1:]):
layer.trainable = True
opt=keras.optimizers.Adam(learning_rate=0.001, beta_1=0.9, beta_2=0.999, epsilon=1e-07)
model_Xception.compile(loss='categorical_crossentropy',
optimizer=opt,
metrics=['accuracy'])
model_Xception.summary()
model_Xception.fit_generator(
train_generator,
epochs=5,
validation_data=validation_generator)
model_Xception.save_weights('first_try.h5')
That's because you are feeding a convolution's output to a Dense layer.
You need to add one of Flatten, GlobalMaxPooling2D or GlobalAveragePooling2D in order to transform your output to (batch_size, input_size). You can change these lines:
inp = Xception.input
out_xception = Xception.layers[-2].output
flatten = tf.keras.layers.Flatten()(out_xception)
new_classification_layer = tf.keras.layers.Dense(num_classes, activation='softmax')
out = new_classification_layer(flatten)
model_Xception = tf.keras.Model(inp, out)
model_Xception.summary()
Second thing is since you did not specify input_shape while defining the Xception model, Flatten will throw an error. Simply change it to:
Xception = tf.keras.applications.Xception(weights='imagenet', include_top=False,
input_shape = (299,299,3))

Keras Hyperband Search Using Directory Iterator

I am using Tensorflow's flow_from_directory to collect a large image dataset and then train on it. I want to use Keras Tuner but when I run
tuner.search(test_data_gen, epochs=50,
validation_split=0.2, callbacks=[stop_early])
It throws the following error,
ValueError: `validation_split` is only supported for Tensors or NumPy arrays, found following types in the input: [<class 'tensorflow.python.keras.preprocessing.image.DirectoryIterator'>]
I don't know much about converting between data types in AI so any help is truly appreciated.
Here is the rest of my code:
import tensorflow as tf
from tensorflow import keras
import numpy as np
import matplotlib.pyplot as plt
import IPython.display as display
from PIL import Image, ImageSequence
import os
import pathlib
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Conv2D, Flatten, Dropout, MaxPooling2D
from tensorflow.keras.preprocessing.image import ImageDataGenerator
import cv2
import datetime
import kerastuner as kt
tf.compat.v1.enable_eager_execution()
epochs = 50
steps_per_epoch = 10
batch_size = 20
IMG_HEIGHT = 200
IMG_WIDTH = 200
train_dir = "Data/Train"
test_dir = "Data/Val"
train_image_generator = ImageDataGenerator(rescale=1. / 255)
test_image_generator = ImageDataGenerator(rescale=1. / 255)
train_data_gen = train_image_generator.flow_from_directory(batch_size=batch_size,
directory=train_dir,
shuffle=True,
target_size=(IMG_HEIGHT, IMG_WIDTH),
class_mode='sparse')
test_data_gen = test_image_generator.flow_from_directory(batch_size=batch_size,
directory=test_dir,
shuffle=True,
target_size=(IMG_HEIGHT, IMG_WIDTH),
class_mode='sparse')
def model_builder(hp):
model = keras.Sequential()
model.add(Conv2D(265, 3, padding='same', activation='relu', input_shape=(IMG_HEIGHT, IMG_WIDTH ,3)))
model.add(MaxPooling2D())
model.add(Conv2D(64, 3, padding='same', activation='relu'))
model.add(MaxPooling2D())
model.add(Conv2D(32, 3, padding='same', activation='relu'))
model.add(MaxPooling2D())
model.add(Flatten())
model.add(keras.layers.Dense(256, activation="relu"))
hp_units = hp.Int('units', min_value=32, max_value=512, step=32)
model.add(keras.layers.Dense(hp_units, activation="relu"))
model.add(keras.layers.Dense(80, activation="softmax"))
hp_learning_rate = hp.Choice('learning_rate', values=[1e-2, 1e-3, 1e-4])
model.compile(optimizer=keras.optimizers.Adam(learning_rate=hp_learning_rate),
loss=keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['top_k_categorical_accuracy'])
return model
tuner = kt.Hyperband(model_builder,
objective='val_accuracy',
max_epochs=30,
factor=3,
directory='Hypertuner_Dir',
project_name='AIOS')
stop_early = tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience=5)
and start searching with tuner
tuner.search(train_data_gen, epochs=50, validation_split=0.2, callbacks=[stop_early])
# Get the optimal hyperparameters
best_hps=tuner.get_best_hyperparameters(num_trials=1)[0]
print(f"""
The hyperparameter search is complete. The optimal number of units in the first densely-connected
layer is {best_hps.get('units')} and the optimal learning rate for the optimizer
is {best_hps.get('learning_rate')}.
""")
model = tuner.hypermodel.build(best_hps)
model.summary()
tf.keras.utils.plot_model(model, to_file="model.png", show_shapes=True, show_layer_names=True, rankdir='TB')
checkpoint_path = "training/cp.ckpt"
checkpoint_dir = os.path.dirname(checkpoint_path)
cp_callback = tf.keras.callbacks.ModelCheckpoint(filepath=checkpoint_path,
save_weights_only=True,
verbose=1)
os.system("rm -r logs")
log_dir = "logs/fit/" + datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
tensorboard_callback = tf.keras.callbacks.TensorBoard(log_dir=log_dir, histogram_freq=1)
#history = model.fit(train_data_gen,steps_per_epoch=steps_per_epoch,epochs=epochs,validation_data=test_data_gen,validation_steps=10,callbacks=[cp_callback, tensorboard_callback])
history = model.fit(train_data_gen,steps_per_epoch=steps_per_epoch,epochs=epochs,validation_split=0.2,validation_steps=10,callbacks=[cp_callback, tensorboard_callback])
model.load_weights(tf.train.latest_checkpoint(checkpoint_dir))
model.save('model.h5', include_optimizer=True)
test_loss, test_acc = model.evaluate(test_data_gen)
print("Tested Acc: ", test_acc)
print("Tested Acc: ", test_acc*100, "%")
val_acc_per_epoch = history.history['val_accuracy']
best_epoch = val_acc_per_epoch.index(max(val_acc_per_epoch)) + 1
print('Best epoch: %d' % (best_epoch,))
===================================EDIT====================================
According to the doc about validation_split:
validation_split: Float between 0 and 1. Fraction of the training data to be used as validation data. The model will set apart this fraction of the training data, will not train on it, and will evaluate the loss and any model metrics on this data at the end of each epoch. The validation data is selected from the last samples in the x and y data provided, before shuffling. This argument is not supported when x is a dataset, generator or keras.utils.Sequence instance.
Now, as you've generator, try as follows, reference
tuner.search(train_data_gen,
epochs=50,
validation_data=test_data_gen,
callbacks=[stop_early])
Also, ensure that each of your generators properly generates the valid batches.
Unfortunately doing a validation_split=0.2 does not work in this case, because this argument assumes that the data is a Tensor or a NumPy array. Since you have the data stored as a generator (which is a good idea), you can't simply split it.
You'll need to create a validation generator, just like you did with test_data_gen, and change validation_split=0.2 to validation_data=val_data_gen.

Im trying to do fine-tuning with Keras, but it doesnt work

im trying to do some finetuning with the infamous Diabetic Retinopaty Dataset.
So as i know, im followging those steps
-Train a VGG16 network without head layers, loading imagenet weights and freezing all conv layers for a few epochs.
-Unfreeze some conv layers (the last block) and training again.
The fact is that i always obtain the same acc score again and again. When i train the model with all layers frozen and the imagenet weights, i get almost 0.74. And when i unfreze some layers and train again, i get the exact same score, its seems like it does nothing.
Im using Tensorflow-Gpu 2.0 and Keras 2.3.0.
Here is my code:
from __future__ import absolute_import, division, print_function, unicode_literals
import os
import tensorboard
from tensorflow.keras.preprocessing.image import ImageDataGenerator
import keras
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dropout, Flatten, Dense
from tensorflow.keras.layers import Conv2D, MaxPooling2D, GlobalAveragePooling2D, GlobalMaxPooling2D, Input
import pandas as pandas
from tensorflow.keras.applications import vgg16
import tensorflow as tf
from tensorflow.keras.models import Model
import datetime
from keras.callbacks import TensorBoard
import pkg_resources
from keras import callbacks
from PIL import Image
import numpy as np
from pathlib import Path
import tensorflow.keras as k
for entry_point in pkg_resources.iter_entry_points('tensorboard_plugins'):
print(entry_point.dist)
#-----------------------------------------------------------
#Corregir el fallo de la CPU
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
#os.environ["PATH"].append("C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v10.0/bin/cudart64_100.dll")
print("Num GPUs Available: ", len(tf.config.experimental.list_physical_devices('GPU')))
#------------------------------------------------------------
trainLabels = pandas.read_csv("./trainLabels_cropped.csv", dtype=str)
#Hay que añadir la extension a la lista de imagenes
def append_ext(fn):
return fn+".jpeg"
trainLabels["image"]=trainLabels["image"].apply(append_ext)
#test_data["id_code"]=test_data["id_code"].apply(append_ext)
train_datagen = ImageDataGenerator(
zoom_range=[-0.5, 0.5],
width_shift_range=[-5, 5],
height_shift_range=[-5, 5],
rotation_range=5,
shear_range=5,
#samplewise_center=True,
#samplewise_std_normalization=True,
#fill_mode='nearest',
validation_split=0.25)
train_generator = train_datagen.flow_from_dataframe(
dataframe=trainLabels,
directory='resized_train_cropped/resized_train_cropped/',
x_col="image",
y_col="level",
target_size=(224, 224),
batch_size=10,
class_mode='categorical',
color_mode='rgb', #quitar o no quitar
subset='training')
validation_generator = train_datagen.flow_from_dataframe(
dataframe=trainLabels,
directory='resized_train_cropped/resized_train_cropped/',
x_col="image",
y_col="level",
target_size=(224, 224),
batch_size=10,
class_mode='categorical',
color_mode='rgb',
subset='validation')
basemodel=Sequential()
baseModel=vgg16.VGG16(weights="imagenet", include_top=False, input_tensor=Input(shape=(224, 224, 3)))
for l in baseModel.layers:
l.trainable=False
for layer in baseModel.layers:
print("{}: {}".format(layer, layer.trainable))
headModel = baseModel.output
headModel = Flatten(name="flatten")(headModel)
headModel = Dense(512, activation="relu")(headModel)
headModel = Dropout(0.5)(headModel)
headModel = Dense(5, activation="softmax")(headModel)
model = Model(inputs=baseModel.input, outputs=headModel)
optimizer=k.optimizers.Adam(learning_rate=1e-4)
model.compile(loss='categorical_crossentropy',
optimizer=optimizer,
metrics=['acc'])
#Model Summary
model.summary()
log_dir="logs\\fit\\" +'Prueba'+ datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
tensorboard_callback = TensorBoard(log_dir=log_dir, histogram_freq=1)
parada=callbacks.callbacks.EarlyStopping(monitor='acc',mode='max',verbose=1,restore_best_weights=True,patience=2)
learningRate=callbacks.callbacks.ReduceLROnPlateau(monitor='acc', factor=0.1, verbose=1, mode='max', min_delta=0.0001, cooldown=0, min_lr=0,patience=2)
#checkpoint=keras.callbacks.callbacks.ModelCheckpoint('\\pesos\\weights', monitor='acc', verbose=0, save_best_only=True, save_weights_only=True, mode='auto', period=1)
model.fit_generator(
train_generator,
steps_per_epoch=250,
epochs=20,
validation_data=validation_generator,
validation_steps=250
#callbacks=[parada]
)
train_generator.reset()
validation_generator.reset()
for l in baseModel.layers[15:]:
l.trainable=True
for layer in baseModel.layers:
print("{}: {}".format(layer, layer.trainable))
optimizer=k.optimizers.Adam(learning_rate=1e-6)
model.compile(loss='categorical_crossentropy',
optimizer=optimizer,
metrics=['acc'])
model.fit_generator(
train_generator,
steps_per_epoch=250,
epochs=30,
validation_data=validation_generator,
validation_steps=250
#callbacks=[parada]
)
Try the following :
1) Add a couple of more dense layers.
2) Try using other activation functions such as 'tanh' and see if that helps. (ReLU could cause an update in a neuron that prevents any subsequent data points from altering it's weights via the gradient)

Error “IndexError: How to predict input image using trained model in Keras?

I trained a model to classify images from 9 classes and saved it using model.save(). Here is the code I used:
from keras.applications.resnet50 import ResNet50, preprocess_input
from keras.layers import Dense, Dropout
from keras.models import Model
from keras.optimizers import Adam, SGD
from keras.preprocessing.image import ImageDataGenerator, image
from keras.callbacks import EarlyStopping, ModelCheckpoint
from sklearn.metrics import confusion_matrix, classification_report, accuracy_score
from keras import backend as K
import numpy as np
import matplotlib.pyplot as plt
from PIL import ImageFile
ImageFile.LOAD_TRUNCATED_IMAGE = True
# Define some constant needed throughout the script
N_CLASSES = 9
EPOCHS = 2
PATIENCE = 5
TRAIN_PATH= '/Datasets/Train/'
VALID_PATH = '/Datasets/Test/'
MODEL_CHECK_WEIGHT_NAME = 'resnet_monki_v1_chk.h5'
# Define model to be used we freeze the pre trained resnet model weight, and add few layer on top of it to utilize our custom dataset
K.set_learning_phase(0)
model = ResNet50(input_shape=(224,224,3),include_top=False, weights='imagenet', pooling='avg')
K.set_learning_phase(1)
x = model.output
x = Dense(512, activation='relu')(x)
x = Dropout(0.5)(x)
x = Dense(512, activation='relu')(x)
x = Dropout(0.5)(x)
output = Dense(N_CLASSES, activation='softmax', name='custom_output')(x)
custom_resnet = Model(inputs=model.input, outputs = output)
for layer in model.layers:
layer.trainable = False
custom_resnet.compile(Adam(lr=0.001), loss='categorical_crossentropy', metrics=['accuracy'])
custom_resnet.summary()
# 4. Load dataset to be used
datagen = ImageDataGenerator(preprocessing_function=preprocess_input)
traingen = datagen.flow_from_directory(TRAIN_PATH, target_size=(224,224), batch_size=32, class_mode='categorical')
validgen = datagen.flow_from_directory(VALID_PATH, target_size=(224,224), batch_size=32, class_mode='categorical', shuffle=False)
# 5. Train Model we use ModelCheckpoint to save the best model based on validation accuracy
es_callback = EarlyStopping(monitor='val_acc', patience=PATIENCE, mode='max')
mc_callback = ModelCheckpoint(filepath=MODEL_CHECK_WEIGHT_NAME, monitor='val_acc', save_best_only=True, mode='max')
train_history = custom_resnet.fit_generator(traingen, steps_per_epoch=len(traingen), epochs= EPOCHS, validation_data=traingen, validation_steps=len(validgen), verbose=2, callbacks=[es_callback, mc_callback])
model.save('custom_resnet.h5')
It successfully trained. To load and test this model on new images, I used the below code:
from keras.models import load_model
import cv2
import numpy as np
class_names = ['A', 'B', 'C', 'D', 'E','F', 'G', 'H', 'R']
model = load_model('custom_resnet.h5')
model.compile(loss='categorical_crossentropy',
optimizer='adam',
metrics=['accuracy'])
img = cv2.imread('/path to image/4.jpg')
img = cv2.resize(img,(224,224))
img = np.reshape(img,[1,224,224,3])
classes = np.argmax(model.predict(img), axis = -1)
print(classes)
It outputs:
[1915]
Why wouldn't it give out the actual value of the class and why the index is too big? I only have 9 classes!
Thanks
You have saved the original resnet_base instead of your custom model.
You did model.save('custom_resnet.h5')
But, model = ResNet50(input_shape=(224,224,3),include_top=False, weights='imagenet', pooling='avg')
You need to save the custom_resnet model with custom_resnet.save('custom_resnet.h5')
That's why when you're using predict, you're getting (1,2048) shaped features not actual predictions.
Updated code:
from keras.applications.resnet50 import ResNet50, preprocess_input
from keras.layers import Dense, Dropout
from keras.models import Model
from keras.optimizers import Adam, SGD
from keras.preprocessing.image import ImageDataGenerator, image
from keras.callbacks import EarlyStopping, ModelCheckpoint
from sklearn.metrics import confusion_matrix, classification_report, accuracy_score
from keras import backend as K
import numpy as np
import matplotlib.pyplot as plt
from PIL import ImageFile
ImageFile.LOAD_TRUNCATED_IMAGE = True
# Define some constant needed throughout the script
N_CLASSES = 9
EPOCHS = 2
PATIENCE = 5
TRAIN_PATH= '/Datasets/Train/'
VALID_PATH = '/Datasets/Test/'
MODEL_CHECK_WEIGHT_NAME = 'resnet_monki_v1_chk.h5'
# Define model to be used we freeze the pre trained resnet model weight, and add few layer on top of it to utilize our custom dataset
K.set_learning_phase(0)
model = ResNet50(input_shape=(224,224,3),include_top=False, weights='imagenet', pooling='avg')
K.set_learning_phase(1)
x = model.output
x = Dense(512, activation='relu')(x)
x = Dropout(0.5)(x)
x = Dense(512, activation='relu')(x)
x = Dropout(0.5)(x)
output = Dense(N_CLASSES, activation='softmax', name='custom_output')(x)
custom_resnet = Model(inputs=model.input, outputs = output)
for layer in model.layers:
layer.trainable = False
custom_resnet.compile(Adam(lr=0.001), loss='categorical_crossentropy', metrics=['accuracy'])
custom_resnet.summary()
# 4. Load dataset to be used
datagen = ImageDataGenerator(preprocessing_function=preprocess_input)
traingen = datagen.flow_from_directory(TRAIN_PATH, target_size=(224,224), batch_size=32, class_mode='categorical')
validgen = datagen.flow_from_directory(VALID_PATH, target_size=(224,224), batch_size=32, class_mode='categorical', shuffle=False)
# 5. Train Model we use ModelCheckpoint to save the best model based on validation accuracy
es_callback = EarlyStopping(monitor='val_acc', patience=PATIENCE, mode='max')
mc_callback = ModelCheckpoint(filepath=MODEL_CHECK_WEIGHT_NAME, monitor='val_acc', save_best_only=True, mode='max')
train_history = custom_resnet.fit_generator(traingen, steps_per_epoch=len(traingen), epochs= EPOCHS, validation_data=traingen, validation_steps=len(validgen), verbose=2, callbacks=[es_callback, mc_callback])
custom_resnet.save('custom_resnet.h5')
Inference code:
from keras.models import load_model
import cv2
import numpy as np
class_names = ['A', 'B', 'C', 'D', 'E','F', 'G', 'H', 'R']
model = load_model('custom_resnet.h5')
model.compile(loss='categorical_crossentropy',
optimizer='adam',
metrics=['accuracy'])
img = cv2.imread('/path to image/4.jpg')
img = cv2.resize(img,(224,224))
img = np.reshape(img,[1,224,224,3])
classes = np.argmax(model.predict(img), axis = -1)
print(classes)
use
np.argmax(model.predict(img)[0], axis = -1)
i am reading from zero index of model.predict

Categories