Grapevine_Disease_Detection/venv/src/gradient.py.bak
2026-03-23 00:36:57 +01:00

264 lines
8.1 KiB
Python

import matplotlib.pylab as plt
import numpy as np
import tensorflow as tf
import os
import math
from tensorflow.keras.models import load_model
from data_pretreat import * # src/ function
#model = load_model('/home/jhodi/bit/Python/Grapevine_Pathology_Detection/venv/models/2026-03-14_21:21:01.562003/model.keras')
model_dir = input("Model dir : ")
model = load_model(model_dir+"/model.keras")
model.build([None, 224, 224, 3])
model.summary()
# img_height = 224
# img_width = 224
# batch_size = 32
#
# test_dir = os.getcwd()[:-9]+"/data/datasplit/test"
# class_names = ['Black_Rot', 'ESCA', 'Healthy', 'Leaf_Blight']
def read_image(file_name):
image = tf.io.read_file(file_name)
image = tf.io.decode_jpeg(image, channels=channels)
image = tf.image.convert_image_dtype(image, tf.float32)
image = tf.image.resize_with_pad(image, target_height=img_height, target_width=img_width)
return image
def top_k_predictions(img, k=2):
image_batch = tf.expand_dims(img, 0)
predictions = model(image_batch)
probs = tf.nn.softmax(predictions, axis=-1)
top_probs, top_idxs = tf.math.top_k(input=probs, k=k)
top_labels = [class_names[idx.numpy()] for idx in top_idxs[0]]
return top_labels, top_probs[0]
# Load img
img_name_tensors = {}
for images, labels in test_ds:
for i, class_name in enumerate(class_names):
class_idx = class_names.index(class_name)
mask = labels == class_idx
if tf.reduce_any(mask):
img_name_tensors[class_name] = images[mask][0] / 255.0
# Show img with prediction
# plt.figure(figsize=(14, 12))
# num_images = len(img_name_tensors)
# cols = 2
# rows = math.ceil(num_images / cols)
#
# for n, (name, img_tensor) in enumerate(img_name_tensors.items()):
# ax = plt.subplot(rows, cols, n+1)
# ax.imshow(img_tensor)
#
# pred_labels, pred_probs = top_k_predictions(img_tensor, k=2)
#
# pred_text = f"Real classe: {name}\n\nPrédictions:\n"
# for label, prob in zip(pred_labels, pred_probs):
# pred_text += f"{label}: {prob.numpy():0.1%}\n"
#
# ax.set_title(pred_text, fontsize=10, fontweight='bold')
# ax.axis('off')
#
# plt.tight_layout()
# plt.show()
# Calculate Integrated Gradients
def f(x):
#A simplified model function.
return tf.where(x < 0.8, x, 0.8)
def interpolated_path(x):
#A straight line path.
return tf.zeros_like(x)
x = tf.linspace(start=0.0, stop=1.0, num=6)
y = f(x)
# Establish a baseline
baseline = tf.zeros(shape=(224,224,3))
# plt.imshow(baseline)
# plt.title("Baseline")
# plt.axis('off')
# plt.show()
m_steps=50
alphas = tf.linspace(start=0.0, stop=1.0, num=m_steps+1) # Generate m_steps intervals for integral_approximation() below.
def interpolate_images(baseline,
image,
alphas):
alphas_x = alphas[:, tf.newaxis, tf.newaxis, tf.newaxis]
baseline_x = tf.expand_dims(baseline, axis=0)
input_x = tf.expand_dims(image, axis=0)
delta = input_x - baseline_x
images = baseline_x + alphas_x * delta
return images
interpolated_images = interpolate_images(
baseline=baseline,
image=img_name_tensors['Leaf_Blight'], # class index : 3
alphas=alphas)
# fig = plt.figure(figsize=(20, 20))
#
# i = 0
# for alpha, image in zip(alphas[0::10], interpolated_images[0::10]):
# i += 1
# plt.subplot(1, len(alphas[0::10]), i)
# plt.title(f'alpha: {alpha:.1f}')
# plt.imshow(image)
# plt.axis('off')
#
# plt.tight_layout();
def compute_gradients(images, target_class_idx):
with tf.GradientTape() as tape:
tape.watch(images)
logits = model(images)
probs = tf.nn.softmax(logits, axis=-1)[:, target_class_idx]
return tape.gradient(probs, images)
path_gradients = compute_gradients(
images=interpolated_images,
target_class_idx=3)
print(path_gradients.shape)
pred = model(interpolated_images)
pred_proba = tf.nn.softmax(pred, axis=-1)[:, 3]
def integral_approximation(gradients):
# riemann_trapezoidal
grads = (gradients[:-1] + gradients[1:]) / tf.constant(2.0)
integrated_gradients = tf.math.reduce_mean(grads, axis=0)
return integrated_gradients
ig = integral_approximation(
gradients=path_gradients)
print(ig.shape)
# Putting it all together
def integrated_gradients(baseline,
image,
target_class_idx,
m_steps=50,
batch_size=32):
# Generate alphas.
alphas = tf.linspace(start=0.0, stop=1.0, num=m_steps+1)
# Collect gradients.
gradient_batches = []
# Iterate alphas range and batch computation for speed, memory efficiency, and scaling to larger m_steps.
for alpha in tf.range(0, len(alphas), batch_size):
from_ = alpha
to = tf.minimum(from_ + batch_size, len(alphas))
alpha_batch = alphas[from_:to]
gradient_batch = one_batch(baseline, image, alpha_batch, target_class_idx)
gradient_batches.append(gradient_batch)
# Concatenate path gradients together row-wise into single tensor.
total_gradients = tf.concat(gradient_batches, axis=0)
# Integral approximation through averaging gradients.
avg_gradients = integral_approximation(gradients=total_gradients)
# Scale integrated gradients with respect to input.
integrated_gradients = (image - baseline) * avg_gradients
return integrated_gradients
@tf.function
def one_batch(baseline, image, alpha_batch, target_class_idx):
# Generate interpolated inputs between baseline and input.
interpolated_path_input_batch = interpolate_images(baseline=baseline,
image=image,
alphas=alpha_batch)
# Compute gradients between model outputs and interpolated inputs.
gradient_batch = compute_gradients(images=interpolated_path_input_batch,
target_class_idx=target_class_idx)
return gradient_batch
ig_attributions = integrated_gradients(baseline=baseline,
image=img_name_tensors['Leaf_Blight'],
target_class_idx=3,
m_steps=240)
print(ig_attributions.shape)
# Visualize attributions
def plot_img_attributions(baseline,
image,
target_class_idx,
m_steps=50,
cmap=None,
overlay_alpha=0.4):
attributions = integrated_gradients(baseline=baseline,
image=image,
target_class_idx=target_class_idx,
m_steps=m_steps)
# Sum of the attributions across color channels for visualization.
# The attribution mask shape is a grayscale image with height and width
# equal to the original image.
attribution_mask = tf.reduce_sum(tf.math.abs(attributions), axis=-1)
fig, axs = plt.subplots(nrows=2, ncols=2, squeeze=False, figsize=(8, 8))
axs[0, 0].set_title('Baseline image')
axs[0, 0].imshow(baseline)
axs[0, 0].axis('off')
axs[0, 1].set_title('Original image')
axs[0, 1].imshow(image)
axs[0, 1].axis('off')
axs[1, 0].set_title('Attribution mask')
axs[1, 0].imshow(attribution_mask, cmap=cmap)
axs[1, 0].axis('off')
axs[1, 1].set_title('Overlay')
axs[1, 1].imshow(attribution_mask, cmap=cmap)
axs[1, 1].imshow(image, alpha=overlay_alpha)
axs[1, 1].axis('off')
plt.tight_layout()
return fig
_ = plot_img_attributions(image=img_name_tensors['Leaf_Blight'],
baseline=baseline,
target_class_idx=3,
m_steps=240,
cmap=plt.cm.inferno,
overlay_alpha=0.4)
plt.show()
_ = plot_img_attributions(image=img_name_tensors['ESCA'],
baseline=baseline,
target_class_idx=1,
m_steps=55,
cmap=plt.cm.viridis,
overlay_alpha=0.5)
plt.show()
"""
@ref :
https://www.tensorflow.org/tutorials/interpretability/integrated_gradients?hl=en
"""