rahulmishra/TransferLearning1
0
1import tensorflow as tf2 3# Create a function to import an image and resize it to be able to be used with our model4def load_and_prep_image(filename, img_shape=224, scale=True):5 """6 Reads in an image from filename, turns it into a tensor and reshapes into7 (224, 224, 3).8 Parameters9 ----------10 filename (str): string filename of target image11 img_shape (int): size to resize target image to, default 22412 scale (bool): whether to scale pixel values to range(0, 1), default True13 """14 # Read in the image15 img = tf.io.read_file(filename)16 # Decode it into a tensor17 img = tf.image.decode_jpeg(img)18 # Resize the image19 img = tf.image.resize(img, [img_shape, img_shape])20 if scale:21 # Rescale the image (get all values between 0 and 1)22 return img/255.23 else:24 return img25 26# Note: The following confusion matrix code is a remix of Scikit-Learn's 27# plot_confusion_matrix function - https://scikit-learn.org/stable/modules/generated/sklearn.metrics.plot_confusion_matrix.html28import itertools29import matplotlib.pyplot as plt30import numpy as np31from sklearn.metrics import confusion_matrix32 33# Our function needs a different name to sklearn's plot_confusion_matrix34def make_confusion_matrix(y_true, y_pred, classes=None, figsize=(10, 10), text_size=15, norm=False, savefig=False): 35 """Makes a labelled confusion matrix comparing predictions and ground truth labels.36 If classes is passed, confusion matrix will be labelled, if not, integer class values37 will be used.38 Args:39 y_true: Array of truth labels (must be same shape as y_pred).40 y_pred: Array of predicted labels (must be same shape as y_true).41 classes: Array of class labels (e.g. string form). If `None`, integer labels are used.42 figsize: Size of output figure (default=(10, 10)).43 text_size: Size of output figure text (default=15).44 norm: normalize values or not (default=False).45 savefig: save confusion matrix to file (default=False).46 47 Returns:48 A labelled confusion matrix plot comparing y_true and y_pred.49 Example usage:50 make_confusion_matrix(y_true=test_labels, # ground truth test labels51 y_pred=y_preds, # predicted labels52 classes=class_names, # array of class label names53 figsize=(15, 15),54 text_size=10)55 """ 56 # Create the confustion matrix57 cm = confusion_matrix(y_true, y_pred)58 cm_norm = cm.astype("float") / cm.sum(axis=1)[:, np.newaxis] # normalize it59 n_classes = cm.shape[0] # find the number of classes we're dealing with60 61 # Plot the figure and make it pretty62 fig, ax = plt.subplots(figsize=figsize)63 cax = ax.matshow(cm, cmap=plt.cm.Blues) # colors will represent how 'correct' a class is, darker == better64 fig.colorbar(cax)65 66 # Are there a list of classes?67 if classes:68 labels = classes69 else:70 labels = np.arange(cm.shape[0])71 72 # Label the axes73 ax.set(title="Confusion Matrix",74 xlabel="Predicted label",75 ylabel="True label",76 xticks=np.arange(n_classes), # create enough axis slots for each class77 yticks=np.arange(n_classes), 78 xticklabels=labels, # axes will labeled with class names (if they exist) or ints79 yticklabels=labels)80 81 # Make x-axis labels appear on bottom82 ax.xaxis.set_label_position("bottom")83 ax.xaxis.tick_bottom()84 85 # Set the threshold for different colors86 threshold = (cm.max() + cm.min()) / 2.87 88 # Plot the text on each cell89 for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):90 if norm:91 plt.text(j, i, f"{cm[i, j]} ({cm_norm[i, j]*100:.1f}%)",92 horizontalalignment="center",93 color="white" if cm[i, j] > threshold else "black",94 size=text_size)95 else:96 plt.text(j, i, f"{cm[i, j]}",97 horizontalalignment="center",98 color="white" if cm[i, j] > threshold else "black",99 size=text_size)100 101 # Save the figure to the current working directory102 if savefig:103 fig.savefig("confusion_matrix.png")104 105# Make a function to predict on images and plot them (works with multi-class)106def pred_and_plot(model, filename, class_names):107 """108 Imports an image located at filename, makes a prediction on it with109 a trained model and plots the image with the predicted class as the title.110 """111 # Import the target image and preprocess it112 img = load_and_prep_image(filename)113 114 # Make a prediction115 pred = model.predict(tf.expand_dims(img, axis=0))116 117 # Get the predicted class118 if len(pred[0]) > 1: # check for multi-class119 pred_class = class_names[pred.argmax()] # if more than one output, take the max120 else:121 pred_class = class_names[int(tf.round(pred)[0][0])] # if only one output, round122 123 # Plot the image and predicted class124 plt.imshow(img)125 plt.title(f"Prediction: {pred_class}")126 plt.axis(False);127 128import datetime129 130def create_tensorboard_callback(dir_name, experiment_name):131 """132 Creates a TensorBoard callback instand to store log files.133 Stores log files with the filepath:134 "dir_name/experiment_name/current_datetime/"135 Args:136 dir_name: target directory to store TensorBoard log files137 experiment_name: name of experiment directory (e.g. efficientnet_model_1)138 """139 log_dir = dir_name + "/" + experiment_name + "/" + datetime.datetime.now().strftime("%Y%m%d-%H%M%S")140 tensorboard_callback = tf.keras.callbacks.TensorBoard(141 log_dir=log_dir142 )143 print(f"Saving TensorBoard log files to: {log_dir}")144 return tensorboard_callback145 146# Plot the validation and training data separately147import matplotlib.pyplot as plt148 149def plot_loss_curves(history):150 """151 Returns separate loss curves for training and validation metrics.152 Args:153 history: TensorFlow model History object (see: https://www.tensorflow.org/api_docs/python/tf/keras/callbacks/History)154 """ 155 loss = history.history['loss']156 val_loss = history.history['val_loss']157 158 accuracy = history.history['accuracy']159 val_accuracy = history.history['val_accuracy']160 161 epochs = range(len(history.history['loss']))162 163 # Plot loss164 plt.plot(epochs, loss, label='training_loss')165 plt.plot(epochs, val_loss, label='val_loss')166 plt.title('Loss')167 plt.xlabel('Epochs')168 plt.legend()169 170 # Plot accuracy171 plt.figure()172 plt.plot(epochs, accuracy, label='training_accuracy')173 plt.plot(epochs, val_accuracy, label='val_accuracy')174 plt.title('Accuracy')175 plt.xlabel('Epochs')176 plt.legend();177 178def compare_historys(original_history, new_history, initial_epochs=5):179 """180 Compares two TensorFlow model History objects.181 182 Args:183 original_history: History object from original model (before new_history)184 new_history: History object from continued model training (after original_history)185 initial_epochs: Number of epochs in original_history (new_history plot starts from here) 186 """187 188 # Get original history measurements189 acc = original_history.history["accuracy"]190 loss = original_history.history["loss"]191 192 val_acc = original_history.history["val_accuracy"]193 val_loss = original_history.history["val_loss"]194 195 # Combine original history with new history196 total_acc = acc + new_history.history["accuracy"]197 total_loss = loss + new_history.history["loss"]198 199 total_val_acc = val_acc + new_history.history["val_accuracy"]200 total_val_loss = val_loss + new_history.history["val_loss"]201 202 # Make plots203 plt.figure(figsize=(8, 8))204 plt.subplot(2, 1, 1)205 plt.plot(total_acc, label='Training Accuracy')206 plt.plot(total_val_acc, label='Validation Accuracy')207 plt.plot([initial_epochs-1, initial_epochs-1],208 plt.ylim(), label='Start Fine Tuning') # reshift plot around epochs209 plt.legend(loc='lower right')210 plt.title('Training and Validation Accuracy')211 212 plt.subplot(2, 1, 2)213 plt.plot(total_loss, label='Training Loss')214 plt.plot(total_val_loss, label='Validation Loss')215 plt.plot([initial_epochs-1, initial_epochs-1],216 plt.ylim(), label='Start Fine Tuning') # reshift plot around epochs217 plt.legend(loc='upper right')218 plt.title('Training and Validation Loss')219 plt.xlabel('epoch')220 plt.show()221 222# Create function to unzip a zipfile into current working directory 223# (since we're going to be downloading and unzipping a few files)224import zipfile225 226def unzip_data(filename):227 """228 Unzips filename into the current working directory.229 Args:230 filename (str): a filepath to a target zip folder to be unzipped.231 """232 zip_ref = zipfile.ZipFile(filename, "r")233 zip_ref.extractall()234 zip_ref.close()235 236# Walk through an image classification directory and find out how many files (images)237# are in each subdirectory.238import os239 240def walk_through_dir(dir_path):241 """242 Walks through dir_path returning its contents.243 Args:244 dir_path (str): target directory245 246 Returns:247 A print out of:248 number of subdiretories in dir_path249 number of images (files) in each subdirectory250 name of each subdirectory251 """252 for dirpath, dirnames, filenames in os.walk(dir_path):253 print(f"There are {len(dirnames)} directories and {len(filenames)} images in '{dirpath}'.")254 255# Function to evaluate: accuracy, precision, recall, f1-score256from sklearn.metrics import accuracy_score, precision_recall_fscore_support257 258def calculate_results(y_true, y_pred):259 """260 Calculates model accuracy, precision, recall and f1 score of a binary classification model.261 Args:262 y_true: true labels in the form of a 1D array263 y_pred: predicted labels in the form of a 1D array264 Returns a dictionary of accuracy, precision, recall, f1-score.265 """266 # Calculate model accuracy267 model_accuracy = accuracy_score(y_true, y_pred) * 100268 # Calculate model precision, recall and f1 score using "weighted average269 model_precision, model_recall, model_f1, _ = precision_recall_fscore_support(y_true, y_pred, average="weighted")270 model_results = {"accuracy": model_accuracy,271 "precision": model_precision,272 "recall": model_recall,273 "f1": model_f1}274 return model_results