Tri-Netra-AI / src /utils.py
anannyavyas1's picture
Upload folder using huggingface_hub (part 2)
3366f95 verified
Raw
History Blame Contribute Delete
4.21 kB
import json
import os
import numpy as np
# removed tensorflow import
import matplotlib
matplotlib.use('Agg')
from sklearn.metrics import classification_report, confusion_matrix, roc_auc_score
import matplotlib.pyplot as plt
def save_history(history, filepath):
if history is None:
return
data = {key: value for key, value in history.history.items()}
np.savez_compressed(filepath, **data)
def plot_training_history(history, output_dir):
if history is None:
return
os.makedirs(output_dir, exist_ok=True)
plt.figure(figsize=(10, 4))
plt.plot(history.history['loss'], label='train_loss')
plt.plot(history.history['val_loss'], label='val_loss')
plt.plot(history.history.get('accuracy', []), label='train_acc')
plt.plot(history.history.get('val_accuracy', []), label='val_acc')
plt.legend()
plt.xlabel('Epoch')
plt.ylabel('Value')
plt.title('Training History')
plt.tight_layout()
plt.savefig(os.path.join(output_dir, 'training_history.png'))
plt.close()
def save_metrics_json(metrics, filepath):
with open(filepath, 'w', encoding='utf-8') as f:
json.dump(metrics, f, indent=2)
def load_metrics_json(filepath):
with open(filepath, 'r', encoding='utf-8') as f:
return json.load(f)
def load_history_npz(filepath):
data = np.load(filepath, allow_pickle=True)
return {key: data[key].tolist() for key in data.files}
def compute_metrics(model, dataset):
y_true = []
y_pred = []
y_score = []
for images, labels in dataset:
logits = model.predict(images, verbose=0)
probs = logits.flatten()
predictions = (probs >= 0.5).astype(int)
y_true.extend(labels.numpy().tolist())
y_pred.extend(predictions.tolist())
y_score.extend(probs.tolist())
report = classification_report(y_true, y_pred, output_dict=True, zero_division=0)
cm = confusion_matrix(y_true, y_pred)
roc_auc = roc_auc_score(y_true, y_score)
metrics = {
'classification_report': report,
'confusion_matrix': cm.tolist(),
'roc_auc': float(roc_auc),
}
return metrics
def _find_layer(model, layer_name):
try:
return model.get_layer(layer_name)
except ValueError:
for layer in model.layers:
if hasattr(layer, 'layers'):
try:
return layer.get_layer(layer_name)
except ValueError:
continue
raise
def make_gradcam_heatmap(img_array, model, last_conv_layer_name, pred_index=None):
conv_layer = _find_layer(model, last_conv_layer_name)
grad_model = tf.keras.models.Model(
[model.inputs],
[conv_layer.output, model.output],
)
with tf.GradientTape() as tape:
conv_outputs, predictions = grad_model(img_array)
if pred_index is None:
pred_index = 0
loss = predictions[:, pred_index]
grads = tape.gradient(loss, conv_outputs)
pooled_grads = tf.reduce_mean(grads, axis=(0, 1, 2))
conv_outputs = conv_outputs[0]
heatmap = conv_outputs @ pooled_grads[..., tf.newaxis]
heatmap = tf.squeeze(heatmap)
heatmap = tf.maximum(heatmap, 0) / (tf.math.reduce_max(heatmap) + 1e-8)
return heatmap.numpy()
def overlay_heatmap(image, heatmap, alpha=0.4, colormap='viridis'):
import matplotlib.cm as cm
image = np.array(image, dtype=np.uint8)
if heatmap.ndim == 2 and heatmap.shape[:2] != image.shape[:2]:
heatmap = tf.image.resize(heatmap[..., np.newaxis], image.shape[:2], method='bilinear').numpy().squeeze()
heatmap = np.uint8(255 * heatmap)
colormap = cm.get_cmap(colormap)
colored = colormap(heatmap)
colored = tf.keras.preprocessing.image.array_to_img(colored)
colored = np.array(colored)
if colored.shape[:2] != image.shape[:2]:
colored = tf.image.resize(colored, image.shape[:2], method='bilinear').numpy().astype(np.uint8)
overlay = colored[:, :, :3] * alpha + image * (1 - alpha)
overlay = np.clip(overlay, 0, 255).astype(np.uint8)
return overlay