I am using Tensorflow 2.15.0.
%reload_ext autoreload
%autoreload 2
import warnings
import skimage
from tqdm.notebook import tqdm
from matplotlib import cm
import os
warnings.filterwarnings('ignore')
import numpy as np
import tensorflow as tf
from matplotlib import pyplot as plt
%matplotlib inline
from packaging.version import parse as version
from tf_keras_vis.utils import num_of_gpus
if version(tf.version.VERSION) < version('2.16.0'):
import tensorflow.keras as keras
else:
import keras
_, gpus = num_of_gpus()
print('Tensorflow recognized {} GPUs'.format(gpus))
model = keras.applications.vgg16.VGG16(weights='imagenet', include_top=True)
model.summary()
from tf_keras_vis.utils.model_modifiers import ReplaceToLinear
replace2linear = ReplaceToLinear()
# Instead of using the ReplaceToLinear instance above,
# you can also define the function from scratch as follows:
def model_modifier_function(cloned_model):
cloned_model.layers[-1].activation = keras.activations.linear
from tf_keras_vis.utils.scores import CategoricalScore
# 1 is the imagenet index corresponding to Goldfish, 294 to Bear and 413 to Assault Rifle.
score = CategoricalScore([1, 294, 413])
# Instead of using CategoricalScore object,
# you can also define the function from scratch as follows:
def score_function(output):
# The `output` variable refers to the output of the model,
# so, in this case, `output` shape is `(3, 1000)` i.e., (samples, classes).
return (output[0][1], output[1][294], output[2][413])
f1 = 'images/goldfish.jpg'
f2 = 'images/bear.jpg'
f3 = 'images/soldiers.jpg'
f4 = 'images/soldiers.jpg'
# Load images and Convert them to a Numpy array
img1 = keras.preprocessing.image.load_img(f1, target_size=(224, 224))
img2 = keras.preprocessing.image.load_img(f2, target_size=(224, 224))
img3 = keras.preprocessing.image.load_img(f3, target_size=(224, 224))
img4 = keras.preprocessing.image.load_img(f3, target_size=(224, 224))
# Uncomment lines to process either 4, 3, or 2 images
images = np.asarray([np.array(img1), np.array(img2), np.array(img3), np.array(img4)]) # Causes error
# images = np.asarray([np.array(img1), np.array(img2), np.array(img3)]) # OK
# images = np.asarray([np.array(img1), np.array(img2)]) # Causes error
# images = np.asarray(images2)
# Preparing input data for VGG16
X = keras.applications.vgg16.preprocess_input(images)
# # Rendering
# f, ax = plt.subplots(nrows=1, ncols=3, figsize=(12, 4))
# for i, title in enumerate(image_titles[:3]):
# ax[i].set_title(title, fontsize=16)
# ax[i].imshow(images[i])
# ax[i].axis('off')
# plt.tight_layout()
# plt.show()
from tf_keras_vis.scorecam import Scorecam
# Create ScoreCAM object
scorecam = Scorecam(model, model_modifier=replace2linear)
# Generate heatmap with Faster-ScoreCAM
cam = scorecam(score, X, penultimate_layer=-1, max_N=10)
This processes 3 images.
ValueError: Score function must return a Tensor, whose the first dimension is the same as the first dimension of seed_input or , a list or tuple, whose length is the first dimension of seed_input.
Am I doing something wrong? Thanks.
I am using Tensorflow 2.15.0.
I am running this code direct from the documentation:
This processes 3 images.
However, when I try to process 2 or 4 images, I get the following errors:
2 images:
InvalidArgumentError: {{function_node _wrapped__StridedSlice_device/job:localhost/replica:0/task:0/device:GPU:0}} slice index 2 of dimension 0 out of bounds. [Op:StridedSlice] name: strided_slice/
3 images:
ValueError: Score function must return a Tensor, whose the first dimension is the same as the first dimension of seed_input or , a list or tuple, whose length is the first dimension of seed_input.
Am I doing something wrong? Thanks.