I would like to know which operations I need to perform on a TF Lite model to achieve the class activation maps for a given image during classification. I have a separate classify.py file that loads my functions for TF Lite model inference.
import collections
import operator
import numpy as np
Class = collections.namedtuple('Class', ['id', 'score'])
def input_details(interpreter, key):
return interpreter.get_input_details()[0][key]
def input_size(interpreter):
_, height, width, _ = input_details(interpreter, 'shape')
return width, height
def input_tensor(interpreter):
tensor_index = input_details(interpreter, 'index')
return interpreter.tensor(tensor_index)()[0]
def output_tensor(interpreter, dequantize=True):
output_details = interpreter.get_output_details()[0]
output_data = np.squeeze(interpreter.tensor(output_details['index'])())
if dequantize and np.issubdtype(output_details['dtype'], np.integer):
scale, zero_point = output_details['quantization']
return scale * (output_data - zero_point)
return output_data
def set_input(interpreter, data):
input_tensor(interpreter)[:, :] = data
def get_output(interpreter, top_k=1, score_threshold=0.0):
scores = output_tensor(interpreter)
classes = [
Class(i, scores[i])
for i in np.argpartition(scores, -top_k)[-top_k:]
if scores[i] >= score_threshold
]
return sorted(classes, key=operator.itemgetter(1), reverse=True)
Then, my image_classify.py performs the model inference for the given image as input to the tensor.
import argparse
import time
from PIL import Image
import classify
import tflite_runtime.interpreter as tflite
import platform
EDGETPU_SHARED_LIB = {
‘Linux’: ‘libedgetpu.so.1’,
‘Darwin’: ‘libedgetpu.1.dylib’,
‘Windows’: ‘edgetpu.dll’
}[platform.system()]
def load_labels(path, encoding=‘utf-8’):
with open(path, ‘r’, encoding=encoding) as f:
lines = f.readlines()
if not lines:
return {}
if lines[0].split(' ', maxsplit=1)[0].isdigit():
pairs = [line.split(' ', maxsplit=1) for line in lines]
return {int(index): label.strip() for index, label in pairs}
else:
return {index: line.strip() for index, line in enumerate(lines)}
def make_interpreter(model_file):
model_file, *device = model_file.split(‘@’)
return tflite.Interpreter(
model_path=model_file,
experimental_delegates=[
tflite.load_delegate(EDGETPU_SHARED_LIB,
{‘device’: device[0]} if device else {})
])
def main():
parser = argparse.ArgumentParser(
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument(
‘-m’, ‘–model’, required=True, help=‘File path of .tflite file.’)
parser.add_argument(
‘-i’, ‘–input’, required=True, help=‘Image to be classified.’)
parser.add_argument(
‘-l’, ‘–labels’, help=‘File path of labels file.’)
parser.add_argument(
‘-k’, ‘–top_k’, type=int, default=1,
help=‘Max number of classification results’)
parser.add_argument(
‘-t’, ‘–threshold’, type=float, default=0.0,
help=‘Classification score threshold’)
parser.add_argument(
‘-c’, ‘–count’, type=int, default=5,
help=‘Number of times to run inference’)
args = parser.parse_args()
labels = load_labels(args.labels) if args.labels else {}
interpreter = make_interpreter(args.model)
interpreter.allocate_tensors()
size = classify.input_size(interpreter)
image = Image.open(args.input).convert(‘RGB’).resize(size, Image.ANTIALIAS)
classify.set_input(interpreter, image)
for _ in range(args.count):
start = time.perf_counter()
interpreter.invoke()
inference_time = time.perf_counter() - start
classes = classify.get_output(interpreter, args.top_k, args.threshold)
print(‘%.1fms’ % (inference_time * 1000))
for klass in classes:
print(‘%s: %.5f’ % (labels.get(klass.id, klass.id), klass.score))
What I would like to do is to perform the same operations such as retrieving the layers, computing the gradients, performing the channel multiplications that are usually done for a standard tensorflow model, but instead, for a tensorflow lite model and show the grad-cam heat map for the image input