thoeppner commited on
Commit
a6b8808
·
verified ·
1 Parent(s): e0dbbb7

Update app.py

Browse files

added grad-cam feature

Files changed (1) hide show
  1. app.py +65 -6
app.py CHANGED
@@ -4,9 +4,11 @@ from PIL import Image
4
  import gradio as gr
5
  import matplotlib.pyplot as plt
6
  import pandas as pd
 
7
  import os
8
  import hashlib
9
  from huggingface_hub import hf_hub_download
 
10
 
11
  # Modell laden vom Hugging Face Model Hub
12
  device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
@@ -39,18 +41,71 @@ def get_image_hash(image):
39
  img_bytes = image.tobytes()
40
  return hashlib.md5(img_bytes).hexdigest()
41
 
42
- # Plot-Funktion
43
  def plot_probabilities(probabilities, labels):
44
  probs = probabilities.cpu().numpy().flatten()
45
  fig, ax = plt.subplots(figsize=(8, 4))
46
  ax.barh(labels, probs)
47
  ax.set_xlim(0, 1)
48
- ax.invert_yaxis() # Highest probability on top
49
  ax.set_xlabel('Confidence')
50
  ax.set_title('Emotion Probabilities')
51
  plt.tight_layout()
52
  return fig
53
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
  # Prediction-Funktion
55
  def predict_emotion(image):
56
  image = image.convert("RGB")
@@ -80,7 +135,10 @@ def predict_emotion(image):
80
  # Bild-Hash für spätere Zuordnung
81
  img_hash = get_image_hash(image)
82
 
83
- return prediction, f"Confidence: {confidence.item()*100:.2f}%\n{prediction_status}", top3, fig, img_hash
 
 
 
84
 
85
  # Funktion um Feedback zu speichern
86
  def save_feedback(img_hash, model_prediction, user_feedback, confidence):
@@ -108,9 +166,9 @@ def download_feedback():
108
 
109
  # Kombinierte Funktion
110
  def full_pipeline(image, user_feedback):
111
- prediction, confidence_text, top3, fig, img_hash = predict_emotion(image)
112
  feedback_message = save_feedback(img_hash, prediction, user_feedback, confidence_text.split("\n")[0])
113
- return prediction, confidence_text, top3, fig, feedback_message
114
 
115
  # Gradio Interface
116
  with gr.Blocks() as interface:
@@ -125,12 +183,13 @@ with gr.Blocks() as interface:
125
  confidence_output = gr.Textbox(label="Confidence + Einschätzung")
126
  top3_output = gr.Dataframe(headers=["Emotion", "Wahrscheinlichkeit (%)"], label="Top 3 Emotionen")
127
  plot_output = gr.Plot(label="Verteilung der Emotionen")
 
128
  feedback_message_output = gr.Textbox(label="Feedback-Status")
129
 
130
  submit_btn.click(
131
  fn=full_pipeline,
132
  inputs=[image_input, feedback_input],
133
- outputs=[prediction_output, confidence_output, top3_output, plot_output, feedback_message_output]
134
  )
135
 
136
  download_btn.click(
 
4
  import gradio as gr
5
  import matplotlib.pyplot as plt
6
  import pandas as pd
7
+ import numpy as np
8
  import os
9
  import hashlib
10
  from huggingface_hub import hf_hub_download
11
+ import cv2
12
 
13
  # Modell laden vom Hugging Face Model Hub
14
  device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
 
41
  img_bytes = image.tobytes()
42
  return hashlib.md5(img_bytes).hexdigest()
43
 
44
+ # Plot-Funktion für Wahrscheinlichkeiten
45
  def plot_probabilities(probabilities, labels):
46
  probs = probabilities.cpu().numpy().flatten()
47
  fig, ax = plt.subplots(figsize=(8, 4))
48
  ax.barh(labels, probs)
49
  ax.set_xlim(0, 1)
50
+ ax.invert_yaxis()
51
  ax.set_xlabel('Confidence')
52
  ax.set_title('Emotion Probabilities')
53
  plt.tight_layout()
54
  return fig
55
 
56
+ # Grad-CAM Hilfsfunktion
57
+ def generate_gradcam(image, model, class_idx):
58
+ model.eval()
59
+
60
+ # Hook für Features und Gradients
61
+ gradients = []
62
+ activations = []
63
+
64
+ def save_gradient(grad):
65
+ gradients.append(grad)
66
+
67
+ def forward_hook(module, input, output):
68
+ activations.append(output)
69
+ output.register_hook(save_gradient)
70
+
71
+ # Letztes Convolutional Layer
72
+ target_layer = model.layer4[1].conv2
73
+ handle = target_layer.register_forward_hook(forward_hook)
74
+
75
+ image_tensor = transform(image).unsqueeze(0).to(device)
76
+ output = model(image_tensor)
77
+
78
+ # Softmax -> Klasse auswählen
79
+ pred_class = output.argmax(dim=1).item()
80
+
81
+ model.zero_grad()
82
+ class_score = output[0, class_idx]
83
+ class_score.backward()
84
+
85
+ # Gradients und Activations holen
86
+ gradients = gradients[0].cpu().data.numpy()[0]
87
+ activations = activations[0].cpu().data.numpy()[0]
88
+
89
+ weights = np.mean(gradients, axis=(1, 2))
90
+ gradcam = np.zeros(activations.shape[1:], dtype=np.float32)
91
+
92
+ for i, w in enumerate(weights):
93
+ gradcam += w * activations[i, :, :]
94
+
95
+ gradcam = np.maximum(gradcam, 0)
96
+ gradcam = cv2.resize(gradcam, (224, 224))
97
+ gradcam = gradcam - np.min(gradcam)
98
+ gradcam = gradcam / np.max(gradcam)
99
+
100
+ # Bild zurückkonvertieren
101
+ heatmap = cv2.applyColorMap(np.uint8(255 * gradcam), cv2.COLORMAP_JET)
102
+ image_np = np.array(image.resize((224, 224)).convert("RGB"))
103
+ overlay = cv2.addWeighted(image_np, 0.6, heatmap, 0.4, 0)
104
+
105
+ handle.remove() # Hook entfernen
106
+
107
+ return Image.fromarray(overlay)
108
+
109
  # Prediction-Funktion
110
  def predict_emotion(image):
111
  image = image.convert("RGB")
 
135
  # Bild-Hash für spätere Zuordnung
136
  img_hash = get_image_hash(image)
137
 
138
+ # Grad-CAM Overlay
139
+ gradcam_img = generate_gradcam(image, model, predicted.item())
140
+
141
+ return prediction, f"Confidence: {confidence.item()*100:.2f}%\n{prediction_status}", top3, fig, gradcam_img, img_hash
142
 
143
  # Funktion um Feedback zu speichern
144
  def save_feedback(img_hash, model_prediction, user_feedback, confidence):
 
166
 
167
  # Kombinierte Funktion
168
  def full_pipeline(image, user_feedback):
169
+ prediction, confidence_text, top3, fig, gradcam_img, img_hash = predict_emotion(image)
170
  feedback_message = save_feedback(img_hash, prediction, user_feedback, confidence_text.split("\n")[0])
171
+ return prediction, confidence_text, top3, fig, gradcam_img, feedback_message
172
 
173
  # Gradio Interface
174
  with gr.Blocks() as interface:
 
183
  confidence_output = gr.Textbox(label="Confidence + Einschätzung")
184
  top3_output = gr.Dataframe(headers=["Emotion", "Wahrscheinlichkeit (%)"], label="Top 3 Emotionen")
185
  plot_output = gr.Plot(label="Verteilung der Emotionen")
186
+ gradcam_output = gr.Image(label="Grad-CAM Visualisierung")
187
  feedback_message_output = gr.Textbox(label="Feedback-Status")
188
 
189
  submit_btn.click(
190
  fn=full_pipeline,
191
  inputs=[image_input, feedback_input],
192
+ outputs=[prediction_output, confidence_output, top3_output, plot_output, gradcam_output, feedback_message_output]
193
  )
194
 
195
  download_btn.click(