Buckets:
tahamajs/Sysmem2_in_AI / ComputerAssignments /CA4_visual_question_answering /src /visualization /visualizer.py
| import matplotlib.pyplot as plt | |
| import seaborn as sns | |
| import numpy as np | |
| import torch | |
| from typing import List, Dict, Tuple, Optional, Any | |
| import networkx as nx | |
| from PIL import Image, ImageDraw, ImageFont | |
| import os | |
| from ..utils.base_classes import SceneGraph, VQAOutput | |
| class AttentionVisualizer: | |
| def __init__(self, figsize: Tuple[int, int] = (12, 8)): | |
| self.figsize = figsize | |
| plt.style.use("seaborn-v0_8") | |
| def visualize_attention_maps( | |
| self, | |
| image: torch.Tensor, | |
| attention_maps: List[torch.Tensor], | |
| titles: List[str] = None, | |
| save_path: str = None, | |
| ): | |
| num_maps = len(attention_maps) | |
| cols = min(3, num_maps) | |
| rows = (num_maps + cols - 1) // cols | |
| fig, axes = plt.subplots(rows, cols, figsize=self.figsize) | |
| if rows == 1 and cols == 1: | |
| axes = [axes] | |
| elif rows == 1: | |
| axes = axes | |
| else: | |
| axes = axes.flatten() | |
| if image.dim() == 3: | |
| image_np = image.permute(1, 2, 0).numpy() | |
| else: | |
| image_np = image.numpy() | |
| image_np = (image_np - image_np.min()) / (image_np.max() - image_np.min()) | |
| for i, (attention_map, ax) in enumerate(zip(attention_maps, axes)): | |
| if attention_map.dim() == 4: | |
| att_np = attention_map.squeeze().numpy() | |
| else: | |
| att_np = attention_map.numpy() | |
| att_resized = np.array( | |
| Image.fromarray(att_np).resize( | |
| (image_np.shape[1], image_np.shape[0]), Image.BILINEAR | |
| ) | |
| ) | |
| overlay = image_np.copy() | |
| overlay[:, :, 0] = np.maximum(overlay[:, :, 0], att_resized) | |
| ax.imshow(overlay) | |
| ax.set_title( | |
| titles[i] if titles and i < len(titles) else f"Attention {i+1}" | |
| ) | |
| ax.axis("off") | |
| for i in range(num_maps, len(axes)): | |
| axes[i].set_visible(False) | |
| plt.tight_layout() | |
| if save_path: | |
| plt.savefig(save_path, dpi=300, bbox_inches="tight") | |
| print(f"نقشههای توجه در {save_path} ذخیره شد") | |
| plt.show() | |
| def visualize_attention_evolution( | |
| self, | |
| attention_sequence: List[torch.Tensor], | |
| step_names: List[str] = None, | |
| save_path: str = None, | |
| ): | |
| num_steps = len(attention_sequence) | |
| cols = min(4, num_steps) | |
| rows = (num_steps + cols - 1) // cols | |
| fig, axes = plt.subplots(rows, cols, figsize=self.figsize) | |
| if rows == 1 and cols == 1: | |
| axes = [axes] | |
| elif rows == 1: | |
| axes = axes | |
| else: | |
| axes = axes.flatten() | |
| for i, (attention_map, ax) in enumerate(zip(attention_sequence, axes)): | |
| if attention_map.dim() == 4: | |
| att_np = attention_map.squeeze().numpy() | |
| else: | |
| att_np = attention_map.numpy() | |
| im = ax.imshow(att_np, cmap="hot", interpolation="bilinear") | |
| ax.set_title( | |
| step_names[i] if step_names and i < len(step_names) else f"Step {i+1}" | |
| ) | |
| ax.axis("off") | |
| plt.colorbar(im, ax=ax, fraction=0.046, pad=0.04) | |
| for i in range(num_steps, len(axes)): | |
| axes[i].set_visible(False) | |
| plt.tight_layout() | |
| if save_path: | |
| plt.savefig(save_path, dpi=300, bbox_inches="tight") | |
| print(f"تکامل توجه در {save_path} ذخیره شد") | |
| plt.show() | |
| class SceneGraphVisualizer: | |
| def __init__(self, figsize: Tuple[int, int] = (12, 8)): | |
| self.figsize = figsize | |
| plt.style.use("seaborn-v0_8") | |
| def visualize_scene_graph(self, scene_graph: SceneGraph, save_path: str = None): | |
| G = nx.DiGraph() | |
| for obj_id, obj_data in scene_graph.objects.items(): | |
| label = f"{obj_id}: {obj_data['type']}" | |
| if obj_data.get("attributes"): | |
| attrs = ", ".join( | |
| [f"{k}={v}" for k, v in obj_data["attributes"].items()] | |
| ) | |
| label += f"\\n({attrs})" | |
| G.add_node(obj_id, label=label, **obj_data) | |
| for rel in scene_graph.relationships: | |
| G.add_edge( | |
| rel["subject_id"], | |
| rel["object_id"], | |
| label=rel["predicate"], | |
| weight=rel["confidence"], | |
| ) | |
| plt.figure(figsize=self.figsize) | |
| pos = nx.spring_layout(G, k=2, iterations=50) | |
| nx.draw_networkx_nodes( | |
| G, pos, node_color="lightblue", node_size=2000, alpha=0.7 | |
| ) | |
| nx.draw_networkx_edges( | |
| G, pos, edge_color="gray", arrows=True, arrowsize=20, alpha=0.6 | |
| ) | |
| labels = nx.get_node_attributes(G, "label") | |
| nx.draw_networkx_labels(G, pos, labels, font_size=8) | |
| edge_labels = nx.get_edge_attributes(G, "label") | |
| nx.draw_networkx_edge_labels(G, pos, edge_labels, font_size=8) | |
| plt.title("Scene Graph Visualization") | |
| plt.axis("off") | |
| if save_path: | |
| plt.savefig(save_path, dpi=300, bbox_inches="tight") | |
| print(f"گراف صحنه در {save_path} ذخیره شد") | |
| plt.show() | |
| def visualize_scene_graph_on_image( | |
| self, image: torch.Tensor, scene_graph: SceneGraph, save_path: str = None | |
| ): | |
| if image.dim() == 3: | |
| image_np = image.permute(1, 2, 0).numpy() | |
| else: | |
| image_np = image.numpy() | |
| image_np = (image_np - image_np.min()) / (image_np.max() - image_np.min()) | |
| img_pil = Image.fromarray((image_np * 255).astype(np.uint8)) | |
| draw = ImageDraw.Draw(img_pil) | |
| colors = ["red", "blue", "green", "yellow", "purple", "orange", "pink", "brown"] | |
| for i, (obj_id, obj_data) in enumerate(scene_graph.objects.items()): | |
| bbox = obj_data["bbox"] | |
| color = colors[i % len(colors)] | |
| draw.rectangle(bbox, outline=color, width=3) | |
| label = f"{obj_id}: {obj_data['type']}" | |
| draw.text((bbox[0], bbox[1] - 20), label, fill=color) | |
| for rel in scene_graph.relationships: | |
| subj_id = rel["subject_id"] | |
| obj_id = rel["object_id"] | |
| if subj_id in scene_graph.objects and obj_id in scene_graph.objects: | |
| subj_bbox = scene_graph.objects[subj_id]["bbox"] | |
| obj_bbox = scene_graph.objects[obj_id]["bbox"] | |
| subj_center = ( | |
| (subj_bbox[0] + subj_bbox[2]) // 2, | |
| (subj_bbox[1] + subj_bbox[3]) // 2, | |
| ) | |
| obj_center = ( | |
| (obj_bbox[0] + obj_bbox[2]) // 2, | |
| (obj_bbox[1] + obj_bbox[3]) // 2, | |
| ) | |
| draw.line([subj_center, obj_center], fill="white", width=2) | |
| mid_point = ( | |
| (subj_center[0] + obj_center[0]) // 2, | |
| (subj_center[1] + obj_center[1]) // 2, | |
| ) | |
| draw.text(mid_point, rel["predicate"], fill="white") | |
| plt.figure(figsize=self.figsize) | |
| plt.imshow(img_pil) | |
| plt.title("Scene Graph on Image") | |
| plt.axis("off") | |
| if save_path: | |
| img_pil.save(save_path) | |
| print(f"گراف صحنه روی تصویر در {save_path} ذخیره شد") | |
| plt.show() | |
| class ResultsVisualizer: | |
| def __init__(self, figsize: Tuple[int, int] = (10, 6)): | |
| self.figsize = figsize | |
| plt.style.use("seaborn-v0_8") | |
| def plot_metrics_comparison( | |
| self, | |
| metrics_data: Dict[str, List[float]], | |
| model_names: List[str], | |
| save_path: str = None, | |
| ): | |
| num_metrics = len(metrics_data) | |
| cols = min(2, num_metrics) | |
| rows = (num_metrics + cols - 1) // cols | |
| fig, axes = plt.subplots(rows, cols, figsize=self.figsize) | |
| if rows == 1 and cols == 1: | |
| axes = [axes] | |
| elif rows == 1: | |
| axes = axes | |
| else: | |
| axes = axes.flatten() | |
| for i, (metric_name, values) in enumerate(metrics_data.items()): | |
| ax = axes[i] | |
| bars = ax.bar(model_names, values, alpha=0.7) | |
| for bar, value in zip(bars, values): | |
| ax.text( | |
| bar.get_x() + bar.get_width() / 2, | |
| bar.get_height() + 0.01, | |
| f"{value:.3f}", | |
| ha="center", | |
| va="bottom", | |
| ) | |
| ax.set_title(f"{metric_name.upper()} Comparison") | |
| ax.set_ylabel("Score") | |
| ax.set_ylim(0, 1.1) | |
| plt.setp(ax.get_xticklabels(), rotation=45, ha="right") | |
| for i in range(num_metrics, len(axes)): | |
| axes[i].set_visible(False) | |
| plt.tight_layout() | |
| if save_path: | |
| plt.savefig(save_path, dpi=300, bbox_inches="tight") | |
| print(f"مقایسه متریکها در {save_path} ذخیره شد") | |
| plt.show() | |
| def plot_training_curves( | |
| self, | |
| train_losses: List[float], | |
| val_losses: List[float] = None, | |
| train_metrics: Dict[str, List[float]] = None, | |
| val_metrics: Dict[str, List[float]] = None, | |
| save_path: str = None, | |
| ): | |
| epochs = range(1, len(train_losses) + 1) | |
| num_plots = 1 | |
| if train_metrics: | |
| num_plots += len(train_metrics) | |
| cols = min(2, num_plots) | |
| rows = (num_plots + cols - 1) // cols | |
| fig, axes = plt.subplots(rows, cols, figsize=self.figsize) | |
| if rows == 1 and cols == 1: | |
| axes = [axes] | |
| elif rows == 1: | |
| axes = axes | |
| else: | |
| axes = axes.flatten() | |
| ax = axes[0] | |
| ax.plot(epochs, train_losses, "b-", label="Training Loss", alpha=0.7) | |
| if val_losses: | |
| ax.plot(epochs, val_losses, "r-", label="Validation Loss", alpha=0.7) | |
| ax.set_title("Training and Validation Loss") | |
| ax.set_xlabel("Epoch") | |
| ax.set_ylabel("Loss") | |
| ax.legend() | |
| ax.grid(True, alpha=0.3) | |
| plot_idx = 1 | |
| if train_metrics: | |
| for metric_name, train_values in train_metrics.items(): | |
| if plot_idx < len(axes): | |
| ax = axes[plot_idx] | |
| ax.plot( | |
| epochs, | |
| train_values, | |
| "b-", | |
| label=f"Training {metric_name}", | |
| alpha=0.7, | |
| ) | |
| if val_metrics and metric_name in val_metrics: | |
| val_values = val_metrics[metric_name] | |
| ax.plot( | |
| epochs, | |
| val_values, | |
| "r-", | |
| label=f"Validation {metric_name}", | |
| alpha=0.7, | |
| ) | |
| ax.set_title(f"{metric_name.upper()} Over Time") | |
| ax.set_xlabel("Epoch") | |
| ax.set_ylabel("Score") | |
| ax.legend() | |
| ax.grid(True, alpha=0.3) | |
| plot_idx += 1 | |
| for i in range(plot_idx, len(axes)): | |
| axes[i].set_visible(False) | |
| plt.tight_layout() | |
| if save_path: | |
| plt.savefig(save_path, dpi=300, bbox_inches="tight") | |
| print(f"منحنیهای آموزش در {save_path} ذخیره شد") | |
| plt.show() | |
| def plot_question_type_analysis( | |
| self, question_types: List[str], accuracies: List[float], save_path: str = None | |
| ): | |
| plt.figure(figsize=self.figsize) | |
| bars = plt.bar(question_types, accuracies, alpha=0.7, color="skyblue") | |
| for bar, acc in zip(bars, accuracies): | |
| plt.text( | |
| bar.get_x() + bar.get_width() / 2, | |
| bar.get_height() + 0.01, | |
| f"{acc:.3f}", | |
| ha="center", | |
| va="bottom", | |
| ) | |
| plt.title("Accuracy by Question Type") | |
| plt.xlabel("Question Type") | |
| plt.ylabel("Accuracy") | |
| plt.ylim(0, 1.1) | |
| plt.xticks(rotation=45, ha="right") | |
| plt.tight_layout() | |
| if save_path: | |
| plt.savefig(save_path, dpi=300, bbox_inches="tight") | |
| print(f"تحلیل نوع سوال در {save_path} ذخیره شد") | |
| plt.show() | |
| class ReasoningVisualizer: | |
| def __init__(self, figsize: Tuple[int, int] = (12, 8)): | |
| self.figsize = figsize | |
| plt.style.use("seaborn-v0_8") | |
| def visualize_reasoning_trace( | |
| self, | |
| reasoning_steps: List[str], | |
| confidences: List[float] = None, | |
| save_path: str = None, | |
| ): | |
| fig, ax = plt.subplots(figsize=self.figsize) | |
| y_positions = range(len(reasoning_steps)) | |
| for i, (step, y_pos) in enumerate(zip(reasoning_steps, y_positions)): | |
| if confidences and i < len(confidences): | |
| color = plt.cm.RdYlGn(confidences[i]) | |
| else: | |
| color = "lightblue" | |
| rect = plt.Rectangle( | |
| (0, y_pos - 0.4), 1, 0.8, facecolor=color, alpha=0.7, edgecolor="black" | |
| ) | |
| ax.add_patch(rect) | |
| ax.text(0.5, y_pos, step, ha="center", va="center", fontsize=10) | |
| ax.text( | |
| -0.1, | |
| y_pos, | |
| f"{i+1}", | |
| ha="center", | |
| va="center", | |
| fontsize=12, | |
| fontweight="bold", | |
| ) | |
| ax.set_xlim(-0.2, 1.2) | |
| ax.set_ylim(-0.5, len(reasoning_steps) - 0.5) | |
| ax.set_yticks(y_positions) | |
| ax.set_yticklabels([f"Step {i+1}" for i in range(len(reasoning_steps))]) | |
| ax.set_xticks([]) | |
| ax.set_title("Reasoning Trace Visualization") | |
| for i in range(len(reasoning_steps) - 1): | |
| ax.annotate( | |
| "", | |
| xy=(0.5, i + 0.6), | |
| xytext=(0.5, i + 0.4), | |
| arrowprops=dict(arrowstyle="->", lw=2, color="black"), | |
| ) | |
| plt.tight_layout() | |
| if save_path: | |
| plt.savefig(save_path, dpi=300, bbox_inches="tight") | |
| print(f"ردیابی استدلال در {save_path} ذخیره شد") | |
| plt.show() | |
| def visualize_program_execution( | |
| self, program: List[str], execution_results: List[Any], save_path: str = None | |
| ): | |
| fig, ax = plt.subplots(figsize=self.figsize) | |
| y_positions = range(len(program)) | |
| for i, (instruction, y_pos) in enumerate(zip(program, y_positions)): | |
| if instruction in ["find", "filter"]: | |
| shape = "ellipse" | |
| color = "lightblue" | |
| elif instruction in ["count", "answer"]: | |
| shape = "rectangle" | |
| color = "lightgreen" | |
| else: | |
| shape = "diamond" | |
| color = "lightyellow" | |
| if shape == "ellipse": | |
| from matplotlib.patches import Ellipse | |
| patch = Ellipse( | |
| (0.5, y_pos), | |
| 0.8, | |
| 0.6, | |
| facecolor=color, | |
| alpha=0.7, | |
| edgecolor="black", | |
| ) | |
| elif shape == "rectangle": | |
| patch = plt.Rectangle( | |
| (0.1, y_pos - 0.3), | |
| 0.8, | |
| 0.6, | |
| facecolor=color, | |
| alpha=0.7, | |
| edgecolor="black", | |
| ) | |
| else: | |
| from matplotlib.patches import Polygon | |
| patch = Polygon( | |
| [ | |
| (0.5, y_pos + 0.3), | |
| (0.8, y_pos), | |
| (0.5, y_pos - 0.3), | |
| (0.2, y_pos), | |
| ], | |
| facecolor=color, | |
| alpha=0.7, | |
| edgecolor="black", | |
| ) | |
| ax.add_patch(patch) | |
| ax.text( | |
| 0.5, | |
| y_pos, | |
| instruction, | |
| ha="center", | |
| va="center", | |
| fontsize=10, | |
| fontweight="bold", | |
| ) | |
| if i < len(execution_results): | |
| result = execution_results[i] | |
| ax.text( | |
| 1.1, | |
| y_pos, | |
| f"→ {str(result)[:20]}...", | |
| ha="left", | |
| va="center", | |
| fontsize=8, | |
| style="italic", | |
| ) | |
| ax.set_xlim(-0.1, 1.8) | |
| ax.set_ylim(-0.5, len(program) - 0.5) | |
| ax.set_yticks(y_positions) | |
| ax.set_yticklabels([f"Step {i+1}" for i in range(len(program))]) | |
| ax.set_xticks([]) | |
| ax.set_title("Program Execution Visualization") | |
| for i in range(len(program) - 1): | |
| ax.annotate( | |
| "", | |
| xy=(0.5, i + 0.4), | |
| xytext=(0.5, i + 0.6), | |
| arrowprops=dict(arrowstyle="->", lw=2, color="black"), | |
| ) | |
| plt.tight_layout() | |
| if save_path: | |
| plt.savefig(save_path, dpi=300, bbox_inches="tight") | |
| print(f"اجرای برنامه در {save_path} ذخیره شد") | |
| plt.show() | |
| def demonstrate_visualization(): | |
| print("=== نمایش ابزارهای تجسم VQA ===") | |
| print("\n1. تجسم نقشههای توجه:") | |
| attention_viz = AttentionVisualizer() | |
| image = torch.randn(3, 224, 224) | |
| attention_maps = [torch.randn(1, 1, 14, 14) for _ in range(3)] | |
| titles = ["Find Objects", "Filter by Color", "Final Attention"] | |
| print(" نقشههای توجه شبیهسازی شده ایجاد شد") | |
| print("\n2. تجسم گراف صحنه:") | |
| scene_viz = SceneGraphVisualizer() | |
| scene_graph = SceneGraph() | |
| scene_graph.add_object(1, "person", (100, 100, 200, 300), {"color": "blue"}) | |
| scene_graph.add_object(2, "car", (250, 150, 400, 250), {"color": "red"}) | |
| scene_graph.add_relationship(1, "near", 2, 0.9) | |
| print(" گراف صحنه نمونه ایجاد شد") | |
| print("\n3. تجسم نتایج:") | |
| results_viz = ResultsVisualizer() | |
| metrics_data = {"accuracy": [0.85, 0.78, 0.92], "vqa_score": [0.82, 0.75, 0.89]} | |
| model_names = ["Traditional", "NMN", "Hybrid"] | |
| print(" دادههای متریک نمونه ایجاد شد") | |
| print("\n4. تجسم استدلال:") | |
| reasoning_viz = ReasoningVisualizer() | |
| reasoning_steps = [ | |
| "Parse question: What color is the car?", | |
| "Find objects of type 'car'", | |
| "Retrieve color attribute", | |
| "Answer: red", | |
| ] | |
| confidences = [0.95, 0.88, 0.92, 0.90] | |
| print(" مراحل استدلال نمونه ایجاد شد") | |
| print("\n✅ همه ابزارهای تجسم آماده هستند!") | |
| print("برای نمایش واقعی، از متدهای visualize استفاده کنید.") | |
| if __name__ == "__main__": | |
| demonstrate_visualization() | |
Xet Storage Details
- Size:
- 19.3 kB
- Xet hash:
- 2e794e1d7c7fc4545132f9b639f497bf62738f7fd4c0967350a34bdbef15fd86
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.