Source code for wandb_callbacks.utils

import cv2
import random
import numpy as np

import tensorflow as tf



[docs]def get_samples_for_activation(class_names, X_val, Y_val): """get_samples_for_activation. Returns sample images from the given data. Sample images contain one image per class in the dataset. :param class_names: class names of the dataset. :param X_val: features of the dataset. :param Y_val: labels of the dataset. """ sample_images, sample_labels, sample_labels_enc = [], [], [] # create random indices rand_ind = [i for i in range(len(Y_val))] random.shuffle(rand_ind) indices = [0] * len(class_names) for i, r_ind in enumerate(rand_ind): # get sample and lbl from random index sample = X_val[r_ind] lbl = Y_val[r_ind] # append the list if the label is not in yet lbl_i = np.argmax(lbl) if indices[lbl_i] == 0: indices[lbl_i] = 1 sample_images.append(sample) sample_labels.append(class_names[lbl_i]) sample_labels_enc.append(Y_val[i]) # check if all labels are in list lbl_sum = np.sum(indices) if lbl_sum == len(class_names): break return np.asarray(sample_images), \ np.asarray(sample_labels), \ np.asarray(sample_labels_enc)
[docs]class GradCAM: """ Reference: https://www.pyimagesearch.com/2020/03/09/grad-cam-visualize-class-activation-maps-with-keras-tensorflow-and-deep-learning/ """ def __init__(self, model, layerName): self.model = model self.layerName = layerName self.gradModel = tf.keras.models.Model(inputs=[self.model.inputs], outputs=[self.model.get_layer(self.layerName).output, self.model.output]) def compute_heatmap(self, image, classIdx, eps=1e-8): with tf.GradientTape() as tape: inputs = tf.cast(image, tf.float32) (convOutputs, predictions) = self.gradModel(inputs) if len(predictions) == 1: # Binary Classification loss = predictions[0] else: loss = predictions[:, classIdx] grads = tape.gradient(loss, convOutputs) castConvOutputs = tf.cast(convOutputs > 0, "float32") castGrads = tf.cast(grads > 0, "float32") guidedGrads = castConvOutputs * castGrads * grads convOutputs = convOutputs[0] guidedGrads = guidedGrads[0] weights = tf.reduce_mean(guidedGrads, axis=(0, 1)) cam = tf.reduce_sum(tf.multiply(weights, convOutputs), axis=-1) (w, h) = (image.shape[2], image.shape[1]) heatmap = cv2.resize(cam.numpy(), (w, h)) numer = heatmap - np.min(heatmap) denom = (heatmap.max() - heatmap.min()) + eps heatmap = numer / denom heatmap = (heatmap * 255).astype("uint8") return heatmap def overlay_heatmap(self, heatmap, image, alpha=0.5, colormap=cv2.COLORMAP_VIRIDIS): heatmap = cv2.applyColorMap(heatmap, colormap) output = cv2.addWeighted(image, alpha, heatmap, 1 - alpha, 0) return (heatmap, output)