Sequential' object has no attribute '_ckpt_saved_epoch' error when trying to save my model using callback on Keras - tensorflow

I got this error when i tried to save my MobileNet model.
Traceback (most recent call last): File "../src/script.py", line 150, in <module> callbacks=[cb_checkpointer, cb_early_stopper] File "/opt/conda/lib/python3.6/site-packages/keras/legacy/interfaces.py", line 91, in wrapper
return func(*args, **kwargs) File "/opt/conda/lib/python3.6/site-packages/keras/engine/training.py", line 1418, in fit_generator
initial_epoch=initial_epoch) File "/opt/conda/lib/python3.6/site-packages/keras/engine/training_generator.py", line 264, in fit_generator
callbacks.on_train_end() File "/opt/conda/lib/python3.6/site-packages/keras/callbacks.py", line 142, in on_train_end callback.on_train_end(logs) File "/opt/conda/lib/python3.6/site-packages/tensorflow/python/keras/callbacks.py", line 940, in on_train_end
if self.model._ckpt_saved_epoch is not None: AttributeError: 'Sequential' object has no attribute '_ckpt_saved_epoch'
I am using callbacks for saving:
filepath="weights-improvement-{epoch:02d}-{val_acc:.2f}.hdf5"
cb_early_stopper = EarlyStopping(monitor = 'val_loss', mode='min', verbose=1, patience = EARLY_STOP_PATIENCE)
cb_checkpointer = ModelCheckpoint(filepath = filepath, monitor = 'val_loss', save_best_only = True, mode = 'auto')
My model code:
import numpy as np
import cv2
import os
#from tensorflow.python.keras.models import Sequential
from tensorflow.python.keras.layers import Dense
from tensorflow.python.keras import optimizers
from keras import regularizers
from keras.regularizers import l2
from keras.layers import Dropout
from keras.applications.mobilenet import MobileNet
from keras.layers import GlobalAveragePooling2D, Dense, Dropout, Flatten, BatchNormalization
from keras.models import Sequential
from keras.applications.resnet50 import preprocess_input
from keras.preprocessing.image import ImageDataGenerator
from tensorflow.python.keras.callbacks import EarlyStopping, ModelCheckpoint
#print(os.listdir("testset/"))
# Fixed for our classes
NUM_CLASSES = 3
# Fixed for color images
CHANNELS = 3
IMAGE_RESIZE = 224
RESNET50_POOLING_AVERAGE = 'avg'
DENSE_LAYER_ACTIVATION = 'softmax'
OBJECTIVE_FUNCTION = 'categorical_crossentropy'
# Common accuracy metric for all outputs, but can use different metrics for different output
LOSS_METRICS = ['accuracy']
# EARLY_STOP_PATIENCE must be < NUM_EPOCHS
NUM_EPOCHS = 100
EARLY_STOP_PATIENCE = 50
# These steps value should be proper FACTOR of no.-of-images in train & valid folders respectively
# Training images processed in each step would be no.-of-train-images / STEPS_PER_EPOCH_TRAINING
STEPS_PER_EPOCH_TRAINING = 27
STEPS_PER_EPOCH_VALIDATION = 11
# These steps value should be proper FACTOR of no.-of-images in train & valid folders respectively
# NOTE that these BATCH* are for Keras ImageDataGenerator batching to fill epoch step input
BATCH_SIZE_TRAINING = 8
BATCH_SIZE_VALIDATION = 8
base_mobilenet_model = MobileNet(include_top = False, weights = None)
model = Sequential()
model.add(BatchNormalization(input_shape = [224,224,3]))
model.add(base_mobilenet_model)
model.add(BatchNormalization())
model.add(GlobalAveragePooling2D())
model.add(Dropout(0.5))
# 2nd layer as Dense for 3-class classification,
model.add(Dense(NUM_CLASSES, activation = DENSE_LAYER_ACTIVATION,activity_regularizer=regularizers.l2(0.01)))
model.summary()
model.compile(optimizer = 'adam', loss = OBJECTIVE_FUNCTION, metrics = LOSS_METRICS)
image_size = IMAGE_RESIZE
shift = 0.2
# preprocessing_function is applied on each image but only after re-sizing & augmentation (resize => augment => pre-process)
# Each of the keras.application.resnet* preprocess_input MOSTLY mean BATCH NORMALIZATION (applied on each batch) stabilize the inputs to nonlinear activation functions
# Batch Normalization helps in faster convergence
# featurewise_center=True, featurewise_std_normalization=True,
data_generator = ImageDataGenerator(preprocessing_function=preprocess_input,
width_shift_range=shift,
height_shift_range=shift,
horizontal_flip=True,
vertical_flip=True,
rotation_range=45,
brightness_range=[0.2,1.0],
zoom_range=[0.5,1.0]
)
# flow_From_directory generates batches of augmented data (where augmentation can be color conversion, etc)
# Both train & valid folders must have NUM_CLASSES sub-folders
train_generator = data_generator.flow_from_directory(
'/kaggle/input/grade-dataset/trainset/',
target_size=(image_size, image_size),
batch_size=BATCH_SIZE_TRAINING,
class_mode='categorical')
validation_generator = data_generator.flow_from_directory(
'/kaggle/input/grade-dataset/testset/',
target_size=(image_size, image_size),
batch_size=BATCH_SIZE_VALIDATION,
class_mode='categorical')
# Max number of steps that these generator will have opportunity to process their source content
# len(train_generator) should be 'no. of available train images / BATCH_SIZE_TRAINING'
# len(valid_generator) should be 'no. of available train images / BATCH_SIZE_VALIDATION'
(BATCH_SIZE_TRAINING, len(train_generator), BATCH_SIZE_VALIDATION, len(validation_generator))
# Early stopping & checkpointing the best model in ../working dir & restoring that as our model for prediction
filepath="weights-improvement-{epoch:02d}-{val_acc:.2f}.hdf5"
cb_early_stopper = EarlyStopping(monitor = 'val_loss', mode='min', verbose=1, patience = EARLY_STOP_PATIENCE)
cb_checkpointer = ModelCheckpoint(filepath = filepath, monitor = 'val_loss', save_best_only = True, mode = 'auto')
fit_history = model.fit_generator(
train_generator,
steps_per_epoch=STEPS_PER_EPOCH_TRAINING,
epochs = NUM_EPOCHS,
validation_data=validation_generator,
validation_steps=STEPS_PER_EPOCH_VALIDATION,
callbacks=[cb_checkpointer, cb_early_stopper]
)
I solved the problem by replacing the code:
from tensorflow.python.keras.callbacks import EarlyStopping, ModelCheckpoint
with the code:
from keras.callbacks import EarlyStopping, ModelCheckpoint

Mentioning the Solution here, for the benefit of the Community.
Replacing the code,
from tensorflow.python.keras.callbacks import EarlyStopping, ModelCheckpoint
with the code,
from keras.callbacks import EarlyStopping, ModelCheckpoint
has resolved the error.

Related

Low validation accuracy but the train have high accuracy, also the validation loss so high

i have a question, when im creating the model, why it have high accuracy and low loss, but the validation accuracy low and validation loss so high.
Any recommend way to improve this?
It took 256 samples, validate on 65 samples.
This is the code that i used to
import numpy as np
import cv2
import os
import tensorflow as tf
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt
from keras.preprocessing.image import ImageDataGenerator
from keras.utils.np_utils import to_categorical
# from tensorflow.keras.models import Sequential
from keras.models import Sequential
# from tensorflow.keras.layers import Dense, Dropout, Activation, Flatten, Conv2D, MaxPooling2D
from keras.layers import Conv2D,MaxPooling2D,Dense, Dropout, Activation, Flatten
# from tensorflow.keras.optimizers import Adam,RMSprop,SGD
from keras.optimizers import Adam , RMSprop, SGD
import pickle
from streamlit_webrtc import webrtc_streamer
################################################################
path = 'DatasetsBatik'
testRatio = 0.2
validationRatio = 0.2
imageDimension =(32,32,3)
batchSizeVal=2
epochsVal=200
stepsPerEpochVal=200
################################################################
images=[]
classNumber =[]
myList = os.listdir(path)
print("Total Number of Classes Detected" , " : " , len(myList))
NumberOfClasses =len(myList)
print("Importing Classes ....")
for x in range(0,NumberOfClasses):
#0 Representing Kawung,
#1 Representing Megamendung,
#2 Representing Parang,
#3 Representing Sekar Jagad,
#4 Representing Simbut,
myPicList = os.listdir(path+"/"+str(x))
for y in myPicList:
currentImage = cv2.imread(path+"/"+str(x)+"/"+y)
currentImage = cv2.resize(currentImage, (imageDimension[0],imageDimension[1]) )
images.append(currentImage)
classNumber.append(x)
print(x,end = " " )
print("")
print(len(classNumber))
images = np.array(images)
classNumber = np.array(classNumber)
# print(images.shape)
# print(classNumber.shape)
### Split Data
X_train,X_test,Y_train,Y_test = train_test_split(images,classNumber,test_size = testRatio)
X_train,X_validation,Y_train,Y_validation= train_test_split(X_train,Y_train,test_size = validationRatio)
print("x_train.shape = " + str(X_train.shape))
print("x_test.shape = " +str(X_test.shape))
print("x_validation.shape = "+str(X_validation.shape))
NumberOfSamples=[]
for x in range(0,NumberOfClasses):
# print(len(np.where(Y_train ==x)[0]))
NumberOfSamples.append(len(np.where(Y_train==x)[0]))
print("Number Of Samples : " +str(NumberOfSamples))
plt.figure(figsize=(10,5))
plt.bar(range(0,NumberOfClasses),NumberOfSamples)
plt.title("Number of Images for each Class")
plt.xlabel("Class ID")
plt.ylabel("Number of Images")
plt.show()
# print(X_train)
def PreProcessing(img):
img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
img = cv2.equalizeHist(img)
img = img/255
return img
# img = X_train[30]
# img = cv2.resize(img,(300,300))
# cv2.imshow("PreProcessed",img)
# cv2.waitKey(0)
X_train=np.array(list(map(PreProcessing,X_train)))
# print(X_train)
X_test=np.array(list(map(PreProcessing,X_test)))
X_validation=np.array(list(map(PreProcessing,X_validation)))
# print(X_train.shape)
X_train = X_train.reshape(X_train.shape[0],X_train.shape[1],X_train.shape[2],1)
X_test = X_test.reshape(X_test.shape[0],X_test.shape[1],X_test.shape[2],1)
X_validation = X_validation.reshape(X_validation.shape[0],X_validation.shape[1],X_validation.shape[2],1)
# print(X_train.shape)
dataGen = ImageDataGenerator(width_shift_range=0.1,height_shift_range=0.1,zoom_range=0.2,shear_range=0.1,rotation_range=10)
dataGen.fit(X_train)
Y_train = to_categorical(Y_train,NumberOfClasses)
Y_test = to_categorical(Y_test,NumberOfClasses)
Y_validation = to_categorical(Y_validation,NumberOfClasses)
def myModel():
NumberOfFilters1 = 128
NumberOfFilters2 = 256
sizeOfFilter1=(5,5)
sizeOfFilter2=(3,3)
sizeOfPool=(2,2)
NumberOfNode=128
model = Sequential()
model.add((Conv2D(NumberOfFilters1,sizeOfFilter1,input_shape=(imageDimension[0],imageDimension[1],1),activation='relu')))
model.add(Dropout(0.5))
model.add(MaxPooling2D(pool_size=sizeOfPool))
# model.add((Conv2D(NumberOfFilters1,sizeOfFilter1,activation='relu')))
# model.add(MaxPooling2D(pool_size=sizeOfPool))
# model.add(Dropout(0.5))
model.add((Conv2D(NumberOfFilters2,sizeOfFilter2,activation='relu')))
model.add(MaxPooling2D(pool_size=sizeOfPool))
model.add(Dropout(0.5))
# model.add((Conv2D(NumberOfFilters2,sizeOfFilter2,activation='relu')))
# model.add(MaxPooling2D(pool_size=sizeOfPool))
# model.add(Dropout(0.5))
model.add(Flatten())
model.add(Dense(NumberOfNode,activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(NumberOfClasses,activation='softmax'))
model.compile(Adam(lr=0.0005),loss='categorical_crossentropy',metrics=['accuracy'])
return model
model = myModel()
print(model.summary())
history = model.fit_generator(dataGen.flow(X_train,Y_train,batch_size=batchSizeVal),steps_per_epoch=stepsPerEpochVal,epochs=epochsVal,validation_data=(X_validation,Y_validation),shuffle=1)
# history= model.fit(X_train, Y_train, batch_size=batchSizeVal,epochs=epochsVal,verbose=1,validation_data=(X_validation, Y_validation))
plt.figure(1)
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.legend(['training','validation'])
plt.title('Loss')
plt.xlabel('epoch')
plt.figure(2)
plt.plot(history.history['accuracy'])
plt.plot(history.history['val_accuracy'])
plt.legend(['training','validation'])
plt.title('Accuracy')
plt.xlabel('epoch')
plt.show()
score= model.evaluate(X_test,Y_test,verbose=0)
print('Test Score =',score[0])
print('Score Accuracy = ',score[1])
print(score)
# print(model.metrics_names)
pickle_out=open("10_TestModel4","wb")
pickle.dump(model,pickle_out)
pickle_out.close()
This is the result that i have now
Epoch 1
Finish,Epoch 200
I have tried to remove or add hidden layer, and also try some different learning rate, epoch, batch size, steps per epoch, adding drop out for the layer . Any recommend would be very helpfull, thankyou.

Why is the Accuracy Different in my PC From Kaggle When Using the Same Code

I am writing a watermark detection algorithm, and I've tried a code from Kaggle which fine-tunes a ResNet, but when I run the same code in Jupyter notebook, I get 50% accuracy when the sample code in Kaggle has around 97% accuracy. I don't have a GPU installed on my PC, and I changed the batch size to 32. Do you know why I get 40% lower accuracy?
My Code:
import tensorflow as tf
import numpy as numpy
import os
from pathlib import Path
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.optimizers import RMSprop
from PIL import Image
basedir = "/home/mahsa/Kaggle/archive/wm-nowm"
from PIL import ImageFile
ImageFile.LOAD_TRUNCATED_IMAGES = True
traindir = os.path.join(basedir,'train') # root for training
validdir = os.path.join(basedir,'valid') # root for testing
traingenerator = ImageDataGenerator(rescale=1./255)
validgenerator = ImageDataGenerator(rescale=1./255)
train_data = traingenerator.flow_from_directory(traindir,target_size=(150,150),batch_size=100,class_mode="binary")
valid_data = validgenerator.flow_from_directory(validdir,target_size=(150,150),batch_size=100,class_mode="binary")
existing = tf.keras.applications.InceptionResNetV2 (input_shape=(150, 150, 3),include_top=False, pooling='max', weights='imagenet')
#for layer in existing.layers:
# layer.trainable = False
#existing.summary()
last = existing.get_layer("mixed_7a")
last_output = last.output
# Flatten the output layer to 1 dimension
x = tf.keras.layers.Flatten()(last_output)
x = tf.keras.layers.Dropout(0.25)(x)
# Add a fully connected layer with 1,024 hidden units and ReLU activation
x = tf.keras.layers.Dense(128, activation='relu')(x)
x = tf.keras.layers.Dense(64, activation='relu')(x)
# Add a final sigmoid layer for classification
x = tf.keras.layers.Dense (1, activation='sigmoid')(x)
model = tf.keras.Model( existing.input, x)
model.compile(optimizer=RMSprop(lr=0.001),
loss='binary_crossentropy',
metrics = ['accuracy'])
history = model.fit(train_data,
validation_data=valid_data,
steps_per_epoch=150,
epochs=60,
validation_steps=50,
verbose=2)
I found out that the problem was batch_size, I increased the batch_size to 100, it took about 1.5 day to train the model but I got 99% accuracy.

Load HDF5 checkpoint models with custom metrics

I've created a Keras Regressor to run a RandomizedSearch CV using a ModelCheckpoint callback, but the training overran the Colab runtime 12H limit and stopped halfway through. The models are saved in hdf5 format.
I used tensorflow_addons to add the RSquare class to monitor the R2 for train and validation sets. However, when I used keras.models.load_model, I get the following error:
As you can see from the traceback, I have passed the custom_objects parameter, but still it is not recognised.
How can I solve this?
You can see the full code example below:
import os
import tensorflow as tf
import tensorflow_addons as tfa
from tensorflow.keras import Sequential
from tensorflow.keras.layers import Dense, Dropout
from tensorflow.keras.layers import Input, InputLayer
from tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint
from keras.wrappers.scikit_learn import KerasRegressor
from sklearn.model_selection import RandomizedSearchCV
def build_model(n_hidden = 2, n_neurons = 64, input_shape = (X_train.shape[1],), dropout = 0):
model = Sequential()
model.add(InputLayer(input_shape = input_shape))
for i in range(n_hidden):
model.add(Dense(n_neurons, activation = 'relu'))
model.add(Dropout(dropout))
model.add(Dense(1))
model.compile(loss = 'mean_squared_error', optimizer = 'adam', metrics = [tfa.metrics.RSquare(y_shape=(1,))])
return model
keras_reg = KerasRegressor(build_model)
checkdir = os.path.join(r'/content/drive/MyDrive/COP328/Case A', 'checkpoints', datetime.datetime.now().strftime('%d-%m-%Y_%H-%M-%S'), 'imputed_log1p-{epoch:02d}-{val_r_square:.3f}.hdf5')
callbacks = [ModelCheckpoint(checkdir, save_freq='epoch', save_best_only = True, monitor = 'val_r_square', mode = 'max'),
EarlyStopping(patience = 10)]
# Here is where training got interrupted because of Colab runtime being dropped:
param_dist = {
'n_hidden' : [1,2],
'n_neurons': [8,16,32,64,128],
'dropout': [0,0.2,0.4]
}
rnd_search_cv = RandomizedSearchCV(keras_reg, param_dist, n_iter= 15, cv = 5)
rnd_search_cv.fit(X_train, y_train, epochs = 200, batch_size = 64,
validation_data = (X_valid,y_valid),
callbacks = callbacks)
# Here is where I am trying to reload one of the most promising models based on R2, and getting the error:
from keras.models import load_model
import tensorflow_addons as tfa
rnd_model = load_model(r'/content/drive/MyDrive/COP328/Case A/checkpoints/26-06-2021_17-32-29/imputed_log1p-56-1.000.hdf5', custom_objects = {'r_square': tfa.metrics.RSquare, 'val_r_square': tfa.metrics.RSquare})
This solution doesn't take into account the addons package but one possibility is to create the coefficient of determination (R^2) as a different metric without that package, and then defining it as your loss.
def coeff_determination(y_true, y_pred):
from keras import backend as K
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()) )
Recall that minimizing MSE will maximize R^2.

Keras predicting different output for same input image

am working on a classification problem for binary classes, I have finished the training and testing the model in single images now using the below code
import warnings
import time
from urllib.request import urlopen
import os
import urllib.request
start_time = time.time()
with warnings.catch_warnings():
warnings.filterwarnings("ignore", category=FutureWarning)
import numpy as np
from keras.preprocessing.image import img_to_array, load_img
from keras.models import Sequential
from keras.layers import Dropout, Flatten, Dense, GlobalAveragePooling2D
from keras.applications.vgg16 import VGG16
import tensorflow as tf
import logging
logging.getLogger('tensorflow').disabled = True
img_size = 224
class PersonPrediction:
def __init__(self):
self.class_dictionary = np.load(
'class_indices_vgg.npy',
allow_pickle=True).item()
self.top_model_weights_path = 'v2/weights/bottleneck_fc_model_2020-10-10-05.h5'
self.num_classes = len(self.class_dictionary)
self.model = self.create_model(self.num_classes)
self.graph = tf.compat.v1.get_default_graph()
def create_model(self, num_of_cls):
model = Sequential()
vgg_model = VGG16(include_top=False, weights='imagenet', input_shape=(img_size, img_size, 3))
for layer in vgg_model.layers[:-4]:
layer.trainable = False
model.add(vgg_model)
model.add(GlobalAveragePooling2D())
model.add(Dense(512, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(1, activation='sigmoid'))
return model
def predict(self, path=None, file_name=None):
if path:
image_path = path
path = self.url_to_image(image_path)
else:
path = os.path.join('imgs', file_name)
print("[INFO] loading and preprocessing image...")
image = load_img(path, target_size=(224, 224))
image = img_to_array(image)
# important! otherwise the predictions will be '0'
image = image / 255
image = np.expand_dims(image, axis=0)
label_idx = self.model.predict_classes(image)[0][0]
probability = self.model.predict(image)[0]
inv_map = {v: k for k, v in self.class_dictionary.items()}
label = inv_map[label_idx]
return label, probability[0]
path = 'temp.jpg'
tax_model = PersonPrediction()
label, proba = tax_model.predict(
file_name='frame303.jpg')
print(label, proba)
Problem is I keep getting chaning predictions of both label and accuracy every time I rerun the code, am not sure what is causing that
There are a number of sources that create randomness in the results when training a model. First the weights are randomly initialized so your model is starting from a different point in N space (N is the number of trainable parameters). Second layers like dropout have randomness in terms of which nodes will be nodes will be selected. Some GPU processes particularly with multi-processing can also have some degree of randomness. I have seen a number of posts on getting repeatable results in tensorflow but I have not found one that seems to really work. In general though the results should be reasonably close if your model is working correctly and you run enough epochs. Now once the model is trained and you use it for predictions as long as you use the same trained model you should get identical prediction results.

Getting very low accuracy while fine tuning Inception v3 pre trained model

I am using Inception v3 model for identification of disease present in a Chest XRay image. For training I am using NIH Chest XRay Dataset. I have 14 different classes of diseases present in the dataset and also I have reduced the original image resolution to reduce the dataset size on disk. As I don't have a GPU I am using Google Colab to train my model and I am taking only 300 images per classs for all minority classes and 400 images for 'No Finding' class (Majority class). Please point out the bugs in my code if any and please suggest me some other approaches so that I can achieve better accuracy.
import numpy as np
import tensorflow as tf
import random as rn
import os
os.environ['PYTHONHASHSEED'] = '0'
np.random.seed(42)
rn.seed(12345)
session_conf = tf.ConfigProto(intra_op_parallelism_threads=1, inter_op_parallelism_threads=1)
from keras import backend as K
tf.set_random_seed(1234)
sess = tf.Session(graph=tf.get_default_graph(), config=session_conf)
K.set_session(sess)
from keras.applications.inception_v3 import InceptionV3
from keras.preprocessing import image
from keras.models import Model
from keras.layers import Dense, GlobalAveragePooling2D
from keras.preprocessing.image import ImageDataGenerator
# from keras import backend as K
from keras.callbacks import ModelCheckpoint
from keras.callbacks import TensorBoard
from keras.layers.core import Flatten, Dense, Dropout, Reshape, Lambda
from keras.layers.normalization import BatchNormalization
from sklearn.preprocessing import LabelEncoder
from keras.utils.np_utils import to_categorical
from sklearn.metrics import log_loss
from sklearn.model_selection import train_test_split
# import os.path
'''F1 score calculation class'''
# import numpy as np
# from keras.callbacks import Callback
# from sklearn.metrics import confusion_matrix, f1_score, precision_score, recall_score
# class Metrics(Callback):
# def on_train_begin(self, logs={}):
# self.val_f1s = []
# self.val_recalls = []
# self.val_precisions = []
# def on_epoch_end(self, epoch, logs={}):
# val_predict = (np.asarray(self.model.predict(self.model.validation_data[0]))).round()
# val_targ = self.model.validation_data[1]
# _val_f1 = f1_score(val_targ, val_predict)
# _val_recall = recall_score(val_targ, val_predict)
# _val_precision = precision_score(val_targ, val_predict)
# self.val_f1s.append(_val_f1)
# self.val_recalls.append(_val_recall)
# self.val_precisions.append(_val_precision)
# print(" — val_f1: %f — val_precision: %f — val_recall %f" % (_val_f1, _val_precision, _val_recall))
# return
# metrics = Metrics()
# create the base pre-trained model
base_model = InceptionV3(weights='imagenet', include_top=False)
# dimensions of our images.
#Inception input size
img_width, img_height = 299, 299
top_layers_checkpoint_path = 'cp.top.best.hdf5'
fine_tuned_checkpoint_path = 'cp.fine_tuned.best.hdf5'
new_extended_inception_weights = 'final_weights.hdf5'
train_data_dir = 'drive/My Drive/Colab Notebooks/Sample-300-XRay-Dataset/train'
validation_data_dir = 'drive/My Drive/Colab Notebooks/Sample-300-XRay-Dataset/test'
nb_train_samples = 3528
nb_validation_samples = 896
top_epochs = 50
fit_epochs = 50
batch_size = 24
# add a global spatial average pooling layer
x = base_model.output
x = GlobalAveragePooling2D()(x)
# let's add a fully-connected layer
x = Dense(1024, activation='relu')(x)
x = BatchNormalization()(x)
#x =Dropout(0.2)(x)
x = Dense(512, activation='relu')(x)
x = BatchNormalization()(x)
#x= Dropout(0.3)(x)
# and a logistic layer -- we have 15 classes
predictions = Dense(15, activation='softmax')(x)
# this is the model we will train
model = Model(inputs=base_model.input, outputs=predictions)
if os.path.exists(top_layers_checkpoint_path):
model.load_weights(top_layers_checkpoint_path)
print ("Checkpoint '" + top_layers_checkpoint_path + "' loaded.")
# first: train only the top layers (which were randomly initialized)
# i.e. freeze all convolutional InceptionV3 layers
for layer in base_model.layers:
layer.trainable = False
# compile the model (should be done *after* setting layers to non-trainable)
model.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy'])
# prepare data augmentation configuration
train_datagen = ImageDataGenerator(
rescale=1. / 255,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True)
test_datagen = ImageDataGenerator(rescale=1. / 255)
train_generator = train_datagen.flow_from_directory(
train_data_dir,
target_size=(img_height, img_width),
batch_size=batch_size,
class_mode='categorical')
validation_generator = test_datagen.flow_from_directory(
validation_data_dir,
target_size=(img_height, img_width),
batch_size=batch_size,
class_mode='categorical')
#Save the model after every epoch.
mc_top = ModelCheckpoint(top_layers_checkpoint_path, monitor='val_acc', verbose=0, save_best_only=True, save_weights_only=False, mode='auto', period=1)
#Save the TensorBoard logs.
tb = TensorBoard(log_dir='./logs', histogram_freq=0, write_graph=True, write_images=True)
# train the model on the new data for a few epochs
#model.fit_generator(...)
model.fit_generator(
train_generator,
samples_per_epoch=nb_train_samples // batch_size,
epochs=top_epochs,
validation_data=validation_generator,
nb_val_samples=nb_validation_samples // batch_size,
callbacks=[mc_top, tb])
# at this point, the top layers are well trained and we can start fine-tuning
# convolutional layers from inception V3. We will freeze the bottom N layers
# and train the remaining top layers.
# let's visualize layer names and layer indices to see how many layers
# we should freeze:
# for i, layer in enumerate(base_model.layers):
# print(i, layer.name)
#Save the model after every epoch.
mc_fit = ModelCheckpoint(fine_tuned_checkpoint_path, monitor='val_acc', verbose=0, save_best_only=True, save_weights_only=False, mode='auto', period=1)
if os.path.exists(fine_tuned_checkpoint_path):
model.load_weights(fine_tuned_checkpoint_path)
print ("Checkpoint '" + fine_tuned_checkpoint_path + "' loaded.")
# we chose to train the top 2 inception blocks, i.e. we will freeze
# the first 172 layers and unfreeze the rest:
for layer in model.layers[:172]:
layer.trainable = False
for layer in model.layers[172:]:
layer.trainable = True
# we need to recompile the model for these modifications to take effect
# we use SGD with a low learning rate
from keras.optimizers import SGD
model.compile(optimizer=SGD(lr=0.0001, momentum=0.9), loss='categorical_crossentropy', metrics=['accuracy'])
# we train our model again (this time fine-tuning the top 2 inception blocks
# alongside the top Dense layers
#model.fit_generator(...)
model.fit_generator(
train_generator,
samples_per_epoch=nb_train_samples // batch_size,
epochs=fit_epochs,
validation_data=validation_generator,
nb_val_samples=nb_validation_samples // batch_size,
callbacks=[mc_fit, tb])
model.save_weights(new_extended_inception_weights)