| | |
| | """DenseNet.ipynb |
| | |
| | Automatically generated by Colaboratory. |
| | |
| | Original file is located at |
| | https://colab.research.google.com/drive/1puXj_yhdhVZAi2D2P1mpDlDvccwU_63N |
| | """ |
| |
|
| | import tensorflow as tf |
| | from tensorflow.keras import Input |
| | from tensorflow.keras.applications.densenet import DenseNet121, DenseNet169, DenseNet201 |
| | from tensorflow.keras.applications import MobileNetV3Small |
| | from tensorflow.keras.optimizers import Adam |
| | from tensorflow.keras.models import Sequential, Model |
| | from tensorflow.keras.callbacks import ModelCheckpoint |
| | from tensorflow.keras.layers import Dense, GlobalAveragePooling2D |
| | from tensorflow.keras.layers import Input, Conv2D, MaxPooling2D, Dense, Flatten, Dropout |
| | from tensorflow.keras.preprocessing.image import ImageDataGenerator |
| | from sklearn.model_selection import train_test_split |
| | from sklearn.metrics import classification_report, confusion_matrix, accuracy_score, precision_score, recall_score, f1_score, log_loss, jaccard_score |
| | import numpy as np |
| | import os |
| | from PIL import Image |
| | from shutil import copyfile |
| | import pandas as pd |
| | import seaborn as sns |
| | import matplotlib.pyplot as plt |
| |
|
| | from google.colab import drive |
| | drive.mount('/content/drive') |
| |
|
| | train_data_dir = '/content/drive/MyDrive/BoneFractureDataset/training' |
| | test_data_dir = '/content/drive/MyDrive/BoneFractureDataset/training' |
| | validation_data_dir = '/content/drive/MyDrive/BoneFractureDataset/training' |
| | IMG_WIDTH, IMG_HEIGHT = 299, 299 |
| | input_shape = (IMG_WIDTH, IMG_HEIGHT, 3) |
| |
|
| | train_datagen = ImageDataGenerator(rescale=1./255) |
| | test_datagen = ImageDataGenerator(rescale=1./255) |
| | validation_datagen = ImageDataGenerator(rescale=1./255) |
| |
|
| | train_datagen_augmented = ImageDataGenerator( |
| | rescale=1./255, |
| | rotation_range=20, |
| | width_shift_range=0.2, |
| | height_shift_range=0.2, |
| | shear_range=0.2, |
| | zoom_range=0.2, |
| | horizontal_flip=True, |
| | vertical_flip=False, |
| | fill_mode='nearest' |
| | ) |
| |
|
| | train_generator = train_datagen_augmented.flow_from_directory(train_data_dir, target_size=(IMG_WIDTH, IMG_HEIGHT), batch_size=10, class_mode='categorical') |
| |
|
| | test_datagen_augmented = ImageDataGenerator( |
| | rescale=1./255, |
| | rotation_range=20, |
| | width_shift_range=0.2, |
| | height_shift_range=0.2, |
| | shear_range=0.2, |
| | zoom_range=0.2, |
| | horizontal_flip=True, |
| | vertical_flip=False, |
| | fill_mode='nearest' |
| | ) |
| | test_generator = test_datagen.flow_from_directory(test_data_dir, target_size=(IMG_WIDTH, IMG_HEIGHT), batch_size=8, class_mode='categorical', shuffle=False) |
| |
|
| | validation_datagen_augmented = ImageDataGenerator( |
| | rescale=1./255, |
| | rotation_range=20, |
| | width_shift_range=0.2, |
| | height_shift_range=0.2, |
| | shear_range=0.2, |
| | zoom_range=0.2, |
| | horizontal_flip=True, |
| | vertical_flip=False, |
| | fill_mode='nearest' |
| | ) |
| | validation_generator = validation_datagen.flow_from_directory(validation_data_dir, target_size=(IMG_WIDTH, IMG_HEIGHT), batch_size=8, class_mode='categorical', shuffle=True) |
| |
|
| | class_indices = train_generator.class_indices |
| | print(class_indices) |
| |
|
| | classes = os.listdir(train_data_dir) |
| | for class_name in classes: |
| | class_path = os.path.join(train_data_dir, class_name) |
| | num_images = len(os.listdir(class_path)) |
| | print(f"Class: {class_name}, Number of images: {num_images}") |
| |
|
| | batch = train_generator.next() |
| | for i in range(len(batch[0])): |
| | img = batch[0][i] |
| | label = batch[1][i] |
| | height, width, channels = img.shape |
| | print(f"Image {i+1} - Shape: {width}x{height}x{channels}, Label: {label}") |
| |
|
| | classes = os.listdir(test_data_dir) |
| | for class_name in classes: |
| | class_path = os.path.join(test_data_dir, class_name) |
| | num_images = len(os.listdir(class_path)) |
| | print(f"Class: {class_name}, Number of images: {num_images}") |
| |
|
| | batch = test_generator.next() |
| | for i in range(len(batch[0])): |
| | img = batch[0][i] |
| | label = batch[1][i] |
| | height, width, channels = img.shape |
| | print(f"Image {i+1} - Shape: {width}x{height}x{channels}, Label: {label}") |
| |
|
| | classes = os.listdir(validation_data_dir) |
| | for class_name in classes: |
| | class_path = os.path.join(validation_data_dir, class_name) |
| | num_images = len(os.listdir(class_path)) |
| | print(f"Class: {class_name}, Number of images: {num_images}") |
| |
|
| | batch = validation_generator.next() |
| | for i in range(len(batch[0])): |
| | img = batch[0][i] |
| | label = batch[1][i] |
| | height, width, channels = img.shape |
| | print(f"Image {i+1} - Shape: {width}x{height}x{channels}, Label: {label}") |
| |
|
| | print("GPU is", "available" if tf.config.list_physical_devices('GPU') else "NOT available") |
| | if tf.config.list_physical_devices('GPU'): |
| | tf.config.experimental.set_memory_growth(tf.config.list_physical_devices('GPU')[0], True) |
| | print("GPU device configured") |
| | else: |
| | print("No GPU device found") |
| |
|
| | from tensorflow.keras.callbacks import ModelCheckpoint |
| | model_dir = '/kaggle/working/Checkpoints_densenet201' |
| | if not os.path.exists(model_dir): |
| | os.makedirs(model_dir) |
| | checkpoint_path = model_dir + '/cp.ckpt' |
| | checkpoint_dir = os.path.dirname(checkpoint_path) |
| | cp_callback = tf.keras.callbacks.ModelCheckpoint(filepath=checkpoint_path, save_weights_only=True, save_best_only=True, monitor="val_accuracy", mode="max", verbose=1) |
| |
|
| | checkpoint_path |
| |
|
| | from tensorflow.keras import models, layers, optimizers |
| |
|
| | def create_model(summary=True): |
| | new_input = Input(shape=(IMG_WIDTH, IMG_HEIGHT, 3)) |
| | base_model = DenseNet201(weights='imagenet', include_top=False, input_tensor=new_input) |
| | flat1 = Flatten()(base_model.layers[-1].output) |
| | output = Dense(2, activation='softmax')(flat1) |
| | model = Model(inputs=base_model.inputs, outputs=output) |
| | model.compile(optimizer=Adam(learning_rate=0.001), loss='binary_crossentropy', metrics=['accuracy']) |
| | if summary: |
| | print(model.summary()) |
| | return model |
| |
|
| | model = create_model() |
| |
|
| | history = model.fit(train_generator, steps_per_epoch=20, epochs=20, validation_data=validation_generator, validation_steps=25, callbacks=[cp_callback]) |
| | evaluation = model.evaluate(train_generator) |
| | print(f"Test Accuracy: {evaluation[1] * 100:.2f}%") |
| |
|
| | initial_epoch = 0 |
| | saved_history = { |
| | 'loss': history.history['loss'], |
| | 'accuracy': history.history['accuracy'], |
| | 'val_loss': history.history['val_loss'], |
| | 'val_accuracy': history.history['val_accuracy'], |
| | } |
| |
|
| | np.save("/kaggle/working/saved_D201history.npy", saved_history) |
| |
|
| | latest_checkpoint = tf.train.latest_checkpoint(checkpoint_dir) |
| | print(latest_checkpoint) |
| | if latest_checkpoint is not None: |
| | loaded_model = create_model(summary=True) |
| | status = loaded_model.load_weights(latest_checkpoint) |
| | status.expect_partial() |
| | else: |
| | print("No checkpoint file found in the specified directory.") |
| |
|
| | previous_history = np.load("/kaggle/working/saved_D201history.npy", allow_pickle=True).item() |
| | initial_epoch = len(previous_history['loss']) |
| | print(initial_epoch) |
| |
|
| | loaded_model.compile(optimizer=Adam(learning_rate=1e-5), loss=tf.keras.losses.BinaryCrossentropy(), metrics=['accuracy']) |
| | new_history = loaded_model.fit( |
| | train_generator, |
| | steps_per_epoch=20, |
| | epochs=20, |
| | initial_epoch=initial_epoch, |
| | validation_data=validation_generator, |
| | validation_steps=30, |
| | callbacks=[cp_callback] |
| | ) |
| |
|
| | import matplotlib.pyplot as plt |
| | from matplotlib.lines import Line2D |
| | from matplotlib.legend_handler import HandlerLine2D |
| | import numpy as np |
| |
|
| | plt.figure(figsize=(10, 6)) |
| | train_loss, = plt.plot(previous_history['loss'], label='Train Loss', color='blue') |
| | val_loss, = plt.plot(previous_history['val_loss'], label='Validation Loss', color='orange') |
| | train_accuracy, = plt.plot(previous_history['accuracy'], label='Train Accuracy', color='green') |
| | val_accuracy, = plt.plot(previous_history['val_accuracy'], label='Validation Accuracy', color='red') |
| | plt.title('Model Performance during Training', fontdict={'family': 'Serif', 'weight': 'bold', 'size': 12},pad=10) |
| | plt.xlabel('No. of Epochs', fontdict={'family': 'Serif', 'weight': 'bold', 'size': 12}) |
| | plt.xticks(np.linspace(0, 150, num=16), fontname='Serif', weight='bold') |
| | plt.yticks(np.linspace(0, 5, num=11), fontname='Serif', weight='bold') |
| | plt.xlim(0, 150) |
| | plt.ylim(0, 5) |
| | legend_lines = [ |
| | Line2D([0], [0], color='blue', lw=3), |
| | Line2D([0], [0], color='orange', lw=3), |
| | Line2D([0], [0], color='green', lw=3), |
| | Line2D([0], [0], color='red', lw=3) |
| | ] |
| | plt.legend(legend_lines, ['Train Loss', 'Validation Loss', 'Train Accuracy', 'Validation Accuracy'], |
| | loc='lower center', bbox_to_anchor=(0.5, 1.1), ncol=5, |
| | prop={'family': 'Serif', 'weight': 'bold', 'size': 8}, frameon=False, |
| | handler_map={Line2D: HandlerLine2D(numpoints=5)}) |
| | plt.gca().xaxis.labelpad = 10 |
| | plt.gca().spines['top'].set_visible(False) |
| | plt.gca().spines['right'].set_visible(False) |
| | plt.tight_layout() |
| | plt.show() |
| |
|
| | latest_checkpoint = tf.train.latest_checkpoint(checkpoint_dir) |
| | print(checkpoint_dir) |
| | if latest_checkpoint is not None: |
| | loaded_model = create_model(summary=True) |
| | status = loaded_model.load_weights(latest_checkpoint) |
| | status.expect_partial() |
| | else: |
| | print("No checkpoint file found in the specified directory.") |
| |
|
| | loaded_model.compile(optimizer=Adam(learning_rate=1e-3), loss=tf.keras.losses.BinaryCrossentropy(), metrics=['accuracy']) |
| |
|
| | test_loss, test_acc = loaded_model.evaluate(test_generator) |
| | print(f"Test Accuracy: {test_acc}") |
| |
|
| | |
| | |
| |
|
| | true_classes = [1, 0, 1, 1, 0] |
| | predicted_classes = [1, 1, 0, 1, 0] |
| | print(f"Accuracy: {accuracy_score(true_classes, predicted_classes)}") |
| | print(f"Precision: {precision_score(true_classes, predicted_classes)}") |
| | print(f"Recall: {recall_score(true_classes, predicted_classes)}") |
| | print(f"F1 Score: {f1_score(true_classes, predicted_classes)}") |
| | print(f"Log Loss: {log_loss(true_classes, predicted_classes)}") |
| | print(f"Jaccard Score: {jaccard_score(true_classes, predicted_classes)}") |
| |
|
| | print("\nClassification Report:") |
| | print(classification_report(true_classes, predicted_classes,digits=4)) |
| |
|
| | conf_matrix = confusion_matrix(true_classes, predicted_classes) |
| | plt.figure(figsize=(6, 4.5)) |
| | custom_palette = sns.color_palette(palette='blend:#7AB,#EDA') |
| | font = {'family': 'Serif', 'weight': 'bold', 'size': 12} |
| | heatmap = sns.heatmap(conf_matrix, annot=True, fmt='d', cmap=custom_palette,vmin=0,vmax=350, |
| | xticklabels=['Fractured', 'Non_fractured'], yticklabels=['Fractured', 'Non_fractured'],annot_kws={"family": "Serif",'weight': 'bold', 'size': 12}) |
| | heatmap.set_xlabel('Predicted Labels', fontdict=font) |
| | heatmap.set_ylabel('True Labels', fontdict=font) |
| | heatmap.set_title('Fracture Classification', fontdict=font, pad=12) |
| | heatmap.set_xticklabels(heatmap.get_xticklabels(), fontname='Serif', fontsize=12) |
| | heatmap.set_yticklabels(heatmap.get_yticklabels(), fontname='Serif', fontsize=12) |
| | cbar = heatmap.collections[0].colorbar |
| | cbar.set_label('Count', fontdict=font) |
| | cbar.ax.tick_params(labelsize=10) |
| | plt.gca().xaxis.labelpad = 10 |
| | plt.tight_layout() |
| | plt.show() |
| |
|
| | import numpy as np |
| |
|
| | print(type(true_classes)) |
| | print(type(predictions)) |
| |
|
| | !pip install scikit-learn |
| | !pip install matplotlib |
| |
|
| | from sklearn.metrics import roc_curve, roc_auc_score |
| | import matplotlib.pyplot as plt |
| | from matplotlib.patches import Patch |
| |
|
| | print(type(predictions)) |
| |
|
| | predictions = np.array(predictions) |
| |
|
| | def save_and_display_gradcam(img_path, heatmap, alpha=0.7): |
| | img = cv2.imread(img_path) |
| | img = cv2.resize(img, (299, 299)) |
| | heatmap = cv2.resize(heatmap, (img.shape[1], img.shape[0])) |
| | heatmap = np.uint8(255 * heatmap) |
| | heatmap = cv2.applyColorMap(heatmap, cv2.COLORMAP_PLASMA) |
| | superimposed_img = cv2.addWeighted(heatmap, alpha, img, 1 - alpha, 0) |
| | plt.figure(figsize=(4, 4)) |
| | plt.imshow(cv2.cvtColor(superimposed_img, cv2.COLOR_BGR2RGB)) |
| | plt.title('GradCAM', fontdict={'family': 'Serif', 'weight': 'bold', 'size': 12}) |
| | plt.axis('off') |
| | plt.tight_layout() |
| | plt.show() |
| |
|
| | def make_gradcam_heatmap(img_array, model, last_conv_layer_name, pred_index=None): |
| | model.layers[-1].activation = None |
| | grad_model = tf.keras.models.Model( |
| | [model.inputs], [model.get_layer(last_conv_layer_name).output, model.output] |
| | ) |
| | with tf.GradientTape() as tape: |
| | last_conv_layer_output, preds = grad_model(img_array) |
| | if pred_index is None: |
| | pred_index = tf.argmax(preds[0]) |
| | class_channel = preds[:, pred_index] |
| | grads = tape.gradient(class_channel, last_conv_layer_output) |
| | pooled_grads = tf.reduce_mean(grads, axis=(0, 1, 2)) |
| | last_conv_layer_output = last_conv_layer_output[0] |
| | heatmap = last_conv_layer_output @ pooled_grads[..., tf.newaxis] |
| | heatmap = tf.squeeze(heatmap) |
| | heatmap = tf.maximum(heatmap, 0) / tf.math.reduce_max(heatmap) |
| | return heatmap.numpy() |
| |
|
| | def make_prediction_and_visualize_(): |
| | img_path = '/content/drive/MyDrive/BoneFractureDataset/testing/fractured/3.jpg' |
| | img = cv2.imread(img_path) |
| | img = cv2.resize(img, (299, 299)) |
| | rescaled_img = img/255.0 |
| | batch_pred = np.expand_dims(rescaled_img, 0) |
| | last_conv_layer_name = 'conv5_block32_concat' |
| | heatmap = make_gradcam_heatmap(batch_pred, loaded_model, last_conv_layer_name) |
| | save_and_display_gradcam(img_path, heatmap) |
| | make_prediction_and_visualize_() |
| |
|
| | def save_and_display_gradcam_plusplus(img_path, heatmap, alpha=0.7): |
| | img = cv2.imread(img_path) |
| | img = cv2.resize(img, (299, 299)) |
| | heatmap = cv2.resize(heatmap, (img.shape[1], img.shape[0])) |
| | heatmap = np.uint8(255 * heatmap) |
| | heatmap = cv2.applyColorMap(heatmap, cv2.COLORMAP_PLASMA) |
| | superimposed_img = cv2.addWeighted(heatmap, alpha, img, 1 - alpha, 0) |
| | plt.figure(figsize=(4, 4)) |
| | plt.imshow(cv2.cvtColor(superimposed_img, cv2.COLOR_BGR2RGB)) |
| | plt.title('GradCAM++', fontdict={'family': 'Serif', 'weight': 'bold', 'size': 12}) |
| | plt.axis('off') |
| | plt.tight_layout() |
| | plt.show() |
| |
|
| | def make_gradcam_plusplus_heatmap(img_array, model, last_conv_layer_name, pred_index=None): |
| | model.layers[-1].activation = None |
| | grad_model = tf.keras.models.Model( |
| | [model.inputs], [model.get_layer(last_conv_layer_name).output, model.output] |
| | ) |
| | with tf.GradientTape() as tape: |
| | last_conv_layer_output, preds = grad_model(img_array) |
| | if pred_index is None: |
| | pred_index = tf.argmax(preds[0]) |
| | class_output = preds[:, pred_index] |
| | conv_output = last_conv_layer_output[0] |
| | grads = tape.gradient(class_output, last_conv_layer_output) |
| | pooled_grads = tf.reduce_mean(grads[0], axis=(0, 1, 2)) |
| | last_conv_layer_output = last_conv_layer_output[0] |
| | guided_grads = tf.cast(last_conv_layer_output > 0, 'float32') * grads[0] |
| | weights = tf.reduce_mean(guided_grads, axis=(0, 1)) |
| | heatmap = tf.reduce_sum(tf.multiply(weights, last_conv_layer_output), axis=-1) |
| | heatmap = tf.maximum(heatmap, 0) / tf.reduce_max(heatmap) |
| | return heatmap.numpy() |
| |
|
| | def make_prediction_and_visualize_gradcam_plusplus(): |
| | img_path = '/content/drive/MyDrive/testing/not_fractured/1-rotated1-rotated1-rotated1-rotated1.jpg' |
| | img = cv2.imread(img_path) |
| | img = cv2.resize(img, (299, 299)) |
| | rescaled_img = img / 255.0 |
| | batch_pred = np.expand_dims(rescaled_img, 0) |
| | last_conv_layer_name = 'conv5_block32_concat' |
| | heatmap = make_gradcam_plusplus_heatmap(batch_pred, loaded_model, last_conv_layer_name) |
| | save_and_display_gradcam_plusplus(img_path, heatmap) |
| | make_prediction_and_visualize_gradcam_plusplus() |
| |
|
| | def save_and_display_scorecam(img_path, heatmap, alpha=0.7): |
| | img = cv2.imread(img_path) |
| | img = cv2.resize(img, (299, 299)) |
| | heatmap = cv2.resize(heatmap, (img.shape[1], img.shape[0])) |
| | heatmap = np.uint8(255 * heatmap) |
| | heatmap = cv2.applyColorMap(heatmap, cv2.COLORMAP_PLASMA) |
| | superimposed_img = cv2.addWeighted(heatmap, alpha, img, 1 - alpha, 0) |
| | plt.figure(figsize=(4, 4)) |
| | plt.imshow(cv2.cvtColor(superimposed_img, cv2.COLOR_BGR2RGB)) |
| | plt.title('ScoreCAM', fontdict={'family': 'Serif', 'weight': 'bold', 'size': 12}) |
| | plt.axis('off') |
| | plt.tight_layout() |
| | plt.show() |
| |
|
| | import tensorflow as tf |
| | def make_scorecam_heatmap(img_array, model, last_conv_layer_name, pred_index=None): |
| | model.layers[-1].activation = None |
| | grad_model = tf.keras.models.Model( |
| | [model.inputs], [model.get_layer(last_conv_layer_name).output, model.output] |
| | ) |
| | with tf.GradientTape() as tape: |
| | last_conv_layer_output, preds = grad_model(img_array) |
| | if pred_index is None: |
| | pred_index = tf.argmax(preds[0]) |
| | class_output = preds[:, pred_index] |
| | conv_output = last_conv_layer_output[0] |
| | grads = tape.gradient(class_output, last_conv_layer_output) |
| | guided_grads = tf.cast(grads[0] > 0, 'float32') * grads[0] |
| | weights = tf.reduce_mean(guided_grads, axis=(0, 1)) |
| | cam = tf.reduce_sum(tf.multiply(weights, conv_output), axis=-1) |
| | cam = tf.maximum(cam, 0) |
| | cam /= tf.reduce_max(cam) |
| | return cam.numpy() |
| |
|
| | def make_prediction_and_visualize_scorecam(): |
| | img_path = '/content/drive/MyDrive/BoneFractureDataset/training/fractured/10.jpg' |
| | img = cv2.imread(img_path) |
| | img = cv2.resize(img, (299, 299)) |
| | rescaled_img = img/255.0 |
| | batch_pred = np.expand_dims(rescaled_img, 0) |
| | last_conv_layer_name = 'conv5_block32_concat' |
| | heatmap = make_scorecam_heatmap(batch_pred, loaded_model, last_conv_layer_name) |
| | save_and_display_scorecam(img_path, heatmap) |
| | make_prediction_and_visualize_scorecam() |
| |
|
| | def save_and_display_faster_scorecam(img_path, heatmap, alpha=0.7): |
| | img = cv2.imread(img_path) |
| | img = cv2.resize(img, (299, 299)) |
| | heatmap = cv2.resize(heatmap, (img.shape[1], img.shape[0])) |
| | heatmap = np.uint8(255 * heatmap) |
| | heatmap = cv2.applyColorMap(heatmap, cv2.COLORMAP_PLASMA) |
| | superimposed_img = cv2.addWeighted(heatmap, alpha, img, 1 - alpha, 0) |
| | plt.figure(figsize=(4, 4)) |
| | plt.imshow(cv2.cvtColor(superimposed_img, cv2.COLOR_BGR2RGB)) |
| | plt.title('Faster ScoreCAM', fontdict={'family': 'Serif', 'weight': 'bold', 'size': 12}) |
| | plt.axis('off') |
| | plt.tight_layout() |
| | plt.show() |
| |
|
| | def faster_scorecam_heatmap(img_array, model, last_conv_layer_name, pred_index=None): |
| | model.layers[-1].activation = None |
| | grad_model = tf.keras.models.Model( |
| | [model.inputs], [model.get_layer(last_conv_layer_name).output, model.output] |
| | ) |
| | with tf.GradientTape() as tape: |
| | last_conv_layer_output, preds = grad_model(img_array) |
| | if pred_index is None: |
| | pred_index = tf.argmax(preds[0]) |
| | class_output = preds[:, pred_index] |
| | conv_output = last_conv_layer_output[0] |
| | grads = tape.gradient(class_output, last_conv_layer_output)[0] |
| | weights = tf.reduce_mean(grads, axis=(0, 1)) |
| | weights = tf.reshape(weights, (1, 1, -1)) |
| | conv_output = tf.expand_dims(conv_output, axis=0) |
| | conv_output = tf.expand_dims(conv_output, axis=-1) |
| | cam = tf.matmul(weights, conv_output) |
| | cam = tf.squeeze(cam) |
| | cam = tf.maximum(cam, 0) |
| | cam /= tf.reduce_max(cam) |
| | return cam.numpy() |
| |
|
| | def make_prediction_and_visualize_faster_scorecam(): |
| | img_path = '/content/drive/MyDrive/BoneFractureDataset/testing/fractured/3.jpg' |
| | img = cv2.imread(img_path) |
| | img = cv2.resize(img, (299, 299)) |
| | rescaled_img = img/255.0 |
| | batch_pred = np.expand_dims(rescaled_img, 0) |
| | last_conv_layer_name = 'conv5_block32_concat' |
| | heatmap = faster_scorecam_heatmap(batch_pred, loaded_model, last_conv_layer_name) |
| | save_and_display_faster_scorecam(img_path, heatmap) |
| | make_prediction_and_visualize_faster_scorecam() |
| |
|
| | def save_and_display_layercam(img_path, heatmap, alpha=0.7): |
| | img = cv2.imread(img_path) |
| | img = cv2.resize(img, (299, 299)) |
| | heatmap = cv2.resize(heatmap, (img.shape[1], img.shape[0])) |
| | heatmap = np.uint8(255 * heatmap) |
| | heatmap = cv2.applyColorMap(heatmap, cv2.COLORMAP_PLASMA) |
| | superimposed_img = cv2.addWeighted(heatmap, alpha, img, 1 - alpha, 0) |
| | plt.figure(figsize=(4, 4)) |
| | plt.imshow(cv2.cvtColor(superimposed_img, cv2.COLOR_BGR2RGB)) |
| | plt.title('LayerCAM', fontdict={'family': 'Serif', 'weight': 'bold', 'size': 12}) |
| | plt.axis('off') |
| | plt.tight_layout() |
| | plt.show() |
| |
|
| | import tensorflow as tf |
| | def generate_layercam_heatmap(img_array, model, last_conv_layer_name, target_class_index=None): |
| | model.layers[-1].activation = None |
| | grad_model = tf.keras.models.Model( |
| | [model.inputs], [model.get_layer(last_conv_layer_name).output, model.output] |
| | ) |
| | with tf.GradientTape() as tape: |
| | last_conv_layer_output, preds = grad_model(img_array) |
| | if target_class_index is None: |
| | target_class_index = tf.argmax(preds[0]) |
| | class_output = preds[:, target_class_index] |
| | conv_output = last_conv_layer_output[0] |
| | grads = tape.gradient(class_output, last_conv_layer_output)[0] |
| | weights = tf.reduce_mean(grads, axis=(0, 1)) |
| | weights = tf.reshape(weights, (1, 1, -1)) |
| | conv_output = tf.expand_dims(conv_output, axis=0) |
| | conv_output = tf.expand_dims(conv_output, axis=-1) |
| | cam = tf.matmul(weights, conv_output) |
| | cam = tf.squeeze(cam) |
| | cam = tf.maximum(cam, 0) |
| | cam /= tf.reduce_max(cam) |
| | return cam.numpy() |
| |
|
| | def make_prediction_and_visualize_layercam(): |
| | img_path = '/content/drive/MyDrive/BoneFractureDataset/testing/fractured/3.jpg' |
| | img = cv2.imread(img_path) |
| | img = cv2.resize(img, (299, 299)) |
| | rescaled_img = img/255.0 |
| | batch_pred = np.expand_dims(rescaled_img, 0) |
| | last_conv_layer_name = 'conv5_block32_concat' |
| | heatmap = generate_layercam_heatmap(batch_pred, loaded_model, last_conv_layer_name) |
| | save_and_display_layercam(img_path, heatmap) |
| | make_prediction_and_visualize_layercam() |
| |
|
| | def save_and_display_saliency_map(img_path, saliency_map): |
| | img = cv2.imread(img_path) |
| | img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) |
| | saliency_map = cv2.resize(saliency_map, (img.shape[1], img.shape[0])) |
| | saliency_map = (saliency_map - saliency_map.min()) / (saliency_map.max() - saliency_map.min()) |
| | heatmap = cv2.applyColorMap(np.uint8(255 * saliency_map), cv2.COLORMAP_JET) |
| | heatmap = cv2.cvtColor(heatmap, cv2.COLOR_BGR2RGB) |
| | alpha = 0.4 |
| | blended = cv2.addWeighted(img, alpha, heatmap, 1 - alpha, 0) |
| | plt.figure(figsize=(4, 4)) |
| | plt.imshow(blended) |
| | plt.title('Vanilla Saliency', fontdict={'family': 'Serif', 'weight': 'bold', 'size': 12}) |
| | plt.axis('off') |
| | plt.tight_layout() |
| | plt.show() |
| |
|
| | def generate_vanilla_saliency_map(img_array, model): |
| | img_tensor = tf.convert_to_tensor(img_array) |
| | img_tensor = tf.expand_dims(img_tensor, axis=0) |
| | with tf.GradientTape() as tape: |
| | tape.watch(img_tensor) |
| | preds = model(img_tensor) |
| | top_pred_index = tf.argmax(preds[0]) |
| | top_class_score = preds[:, top_pred_index] |
| | grads = tape.gradient(top_class_score, img_tensor) |
| | saliency_map = tf.abs(grads) |
| | saliency_map = tf.reduce_max(saliency_map, axis=-1) |
| | return saliency_map[0].numpy() |
| |
|
| | def make_prediction_and_visualize_vanilla_saliency(): |
| | img_path = '/content/drive/MyDrive/BoneFractureDataset/testing/fractured/3.jpg' |
| | img = cv2.imread(img_path) |
| | img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) |
| | img = cv2.resize(img, (299, 299)) |
| | img = img / 255.0 |
| | saliency_map = generate_vanilla_saliency_map(img, loaded_model) |
| | save_and_display_saliency_map(img_path, saliency_map) |
| | make_prediction_and_visualize_vanilla_saliency() |
| |
|
| | def save_and_display_SmoothGrad(img_path, saliency_map): |
| | img = cv2.imread(img_path) |
| | img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) |
| | saliency_map = cv2.resize(saliency_map, (img.shape[1], img.shape[0])) |
| | saliency_map = (saliency_map - saliency_map.min()) / (saliency_map.max() - saliency_map.min()) |
| | heatmap = cv2.applyColorMap(np.uint8(255 * saliency_map), cv2.COLORMAP_JET) |
| | heatmap = cv2.cvtColor(heatmap, cv2.COLOR_BGR2RGB) |
| | alpha = 0.4 |
| | blended = cv2.addWeighted(img, alpha, heatmap, 1 - alpha, 0) |
| | plt.figure(figsize=(4, 4)) |
| | plt.imshow(blended) |
| | plt.title('Smooth Grad', fontdict={'family': 'Serif', 'weight': 'bold', 'size': 12}) |
| | plt.axis('off') |
| | plt.tight_layout() |
| | plt.show() |
| |
|
| | def generate_smoothgrad_saliency_map(img_array, model, n=50, sigma=1.0): |
| | img_tensor = tf.convert_to_tensor(img_array) |
| | img_tensor = tf.expand_dims(img_tensor, axis=0) |
| | img_tensor = tf.cast(img_tensor, dtype=tf.float32) |
| | with tf.GradientTape() as tape: |
| | tape.watch(img_tensor) |
| | preds = model(img_tensor) |
| | top_pred_index = tf.argmax(preds[0]) |
| | top_class_score = preds[:, top_pred_index] |
| | total_gradients = tf.zeros_like(img_tensor) |
| | for _ in range(n): |
| | noise = tf.random.normal(shape=img_tensor.shape, mean=0.0, stddev=sigma) |
| | perturbed_img = img_tensor + noise |
| | with tf.GradientTape() as perturbed_tape: |
| | perturbed_tape.watch(perturbed_img) |
| | perturbed_preds = model(perturbed_img) |
| | perturbed_top_class_score = perturbed_preds[:, top_pred_index] |
| | perturbed_grads = perturbed_tape.gradient(perturbed_top_class_score, perturbed_img) |
| | total_gradients += perturbed_grads |
| | averaged_gradients = total_gradients / n |
| | saliency_map = tf.abs(averaged_gradients) |
| | saliency_map = tf.reduce_max(saliency_map, axis=-1) |
| | return saliency_map[0].numpy() |
| |
|
| | def make_prediction_and_visualize_smoothgrad_saliency(): |
| | img_path = '/content/drive/MyDrive/BoneFractureDataset/testing/fractured/3.jpg' |
| | img = cv2.imread(img_path) |
| | img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) |
| | img = cv2.resize(img, (299, 299)) |
| | img = img / 255.0 |
| | heatmap = generate_smoothgrad_saliency_map(img, loaded_model) |
| | save_and_display_SmoothGrad(img_path, heatmap) |
| | make_prediction_and_visualize_smoothgrad_saliency() |
| |
|
| |
|