diff --git a/app.py b/app.py new file mode 100644 index 00000000..0dc86f26 --- /dev/null +++ b/app.py @@ -0,0 +1,300 @@ +import streamlit as st +import os +import sys +import subprocess +from tabs.dataset_viewer import dataset_viewer_tab +from tabs.inference import inference_tab +from tabs.evaluator import evaluator_tab + +def browse_folder(): + """ + Opens a native folder selection dialog and returns the selected folder path. + Works on Windows, macOS, and Linux (with zenity or kdialog). + Returns None if cancelled or error. + """ + try: + if sys.platform.startswith("win"): + script = ( + 'Add-Type -AssemblyName System.windows.forms;' + '$f=New-Object System.Windows.Forms.FolderBrowserDialog;' + 'if($f.ShowDialog() -eq "OK"){Write-Output $f.SelectedPath}' + ) + result = subprocess.run( + ["powershell", "-NoProfile", "-Command", script], + capture_output=True, text=True, timeout=30 + ) + folder = result.stdout.strip() + return folder if folder else None + elif sys.platform == "darwin": + script = 'POSIX path of (choose folder with prompt "Select dataset folder:")' + result = subprocess.run( + ["osascript", "-e", script], + capture_output=True, text=True, timeout=30 + ) + folder = result.stdout.strip() + return folder if folder else None + else: + # Linux: try zenity, then kdialog + for cmd in [ + ["zenity", "--file-selection", "--directory", "--title=Select dataset folder"], + ["kdialog", "--getexistingdirectory", "--title", "Select dataset folder"] + ]: + try: + result = subprocess.run(cmd, capture_output=True, text=True, timeout=30) + folder = result.stdout.strip() + if folder: + return folder + except Exception: + continue + return None + except Exception: + return None + +st.set_page_config(page_title="DetectionMetrics", layout="wide") + +# st.title("DetectionMetrics") + +PAGES = { + "Dataset Viewer": dataset_viewer_tab, + "Inference": inference_tab, + "Evaluator": evaluator_tab, +} + +# Initialize commonly used session state keys +st.session_state.setdefault("dataset_path", "") +st.session_state.setdefault("dataset_type_selectbox", "Coco") +st.session_state.setdefault("split_selectbox", "val") +st.session_state.setdefault("config_option", "Manual Configuration") +st.session_state.setdefault("confidence_threshold", 0.5) +st.session_state.setdefault("nms_threshold", 0.5) +st.session_state.setdefault("max_detections", 100) +st.session_state.setdefault("device", "cpu") +st.session_state.setdefault("batch_size", 1) +st.session_state.setdefault("evaluation_step", 5) +st.session_state.setdefault("detection_model", None) +st.session_state.setdefault("detection_model_loaded", False) + +# Sidebar: Dataset Inputs +with st.sidebar: + with st.expander("Dataset Inputs", expanded=True): + # First row: Type and Split + col1, col2 = st.columns(2) + with col1: + st.selectbox( + "Type", + ["Coco", "Custom"], + key="dataset_type_selectbox", + ) + with col2: + st.selectbox( + "Split", + ["train", "val"], + key="split_selectbox", + ) + + # Second row: Path and Browse button + col1, col2 = st.columns([3, 1]) + with col1: + dataset_path_input = st.text_input( + "Dataset Folder Path", + value=st.session_state.get("dataset_path", ""), + key="dataset_path_input", + ) + with col2: + st.markdown("
", unsafe_allow_html=True) + if st.button("Browse", key="browse_button"): + folder = browse_folder() + if folder and os.path.isdir(folder): + st.session_state["dataset_path"] = folder + st.rerun() + elif folder is not None: + st.warning("Selected path is not a valid folder.") + + if dataset_path_input != st.session_state.get("dataset_path", ""): + st.session_state["dataset_path"] = dataset_path_input + + with st.expander("Model Inputs", expanded=False): + st.file_uploader( + "Model File (.pt, .onnx, .h5, .pb, .pth)", + type=["pt", "onnx", "h5", "pb", "pth"], + key="model_file", + help="Upload your trained model file.", + ) + st.file_uploader( + "Ontology File (.json)", + type=["json"], + key="ontology_file", + help="Upload a JSON file with class labels.", + ) + st.radio( + "Configuration Method:", + ["Manual Configuration", "Upload Config File"], + key="config_option", + horizontal=True, + ) + if st.session_state.get("config_option", "Manual Configuration") == "Upload Config File": + st.file_uploader( + "Configuration File (.json)", + type=["json"], + key="config_file", + help="Upload a JSON configuration file.", + ) + else: + col1, col2 = st.columns(2) + with col1: + st.slider( + "Confidence Threshold", + min_value=0.0, + max_value=1.0, + value=st.session_state.get("confidence_threshold", 0.5), + step=0.01, + key="confidence_threshold", + help="Minimum confidence score for detections", + ) + st.slider( + "NMS Threshold", + min_value=0.0, + max_value=1.0, + value=st.session_state.get("nms_threshold", 0.5), + step=0.01, + key="nms_threshold", + help="Non-maximum suppression threshold", + ) + st.number_input( + "Max Detections/Image", + min_value=1, + max_value=1000, + value=st.session_state.get("max_detections", 100), + step=1, + key="max_detections", + ) + with col2: + st.selectbox( + "Device", + ["cpu", "gpu"], + index=0 if st.session_state.get("device", "cpu") == "cpu" else 1, + key="device", + ) + st.number_input( + "Batch Size", + min_value=1, + max_value=256, + value=st.session_state.get("batch_size", 1), + step=1, + key="batch_size", + ) + st.number_input( + "Evaluation Step", + min_value=0, + max_value=1000, + value=st.session_state.get("evaluation_step", 10), + step=1, + key="evaluation_step", + help="Update UI with intermediate metrics every N images (0 = disable intermediate updates)" + ) + + # Load model action in sidebar + from detectionmetrics.models.torch_detection import TorchImageDetectionModel + import json, tempfile + + + load_model_btn = st.button( + "Load Model", + type="primary", + use_container_width=True, + help="Load and save the model for use in the Inference tab", + key="sidebar_load_model_btn", + ) + + if load_model_btn: + model_file = st.session_state.get("model_file") + ontology_file = st.session_state.get("ontology_file") + config_option = st.session_state.get("config_option", "Manual Configuration") + config_file = st.session_state.get("config_file") if config_option == "Upload Config File" else None + + # Prepare configuration + config_data = None + config_path = None + try: + if config_option == "Upload Config File": + if config_file is not None: + config_data = json.load(config_file) + with tempfile.NamedTemporaryFile(delete=False, suffix='.json', mode='w') as tmp_cfg: + json.dump(config_data, tmp_cfg) + config_path = tmp_cfg.name + else: + st.error("Please upload a configuration file") + else: + confidence_threshold = float(st.session_state.get('confidence_threshold', 0.5)) + nms_threshold = float(st.session_state.get('nms_threshold', 0.5)) + max_detections = int(st.session_state.get('max_detections', 100)) + device = st.session_state.get('device', 'cpu') + batch_size = int(st.session_state.get('batch_size', 1)) + evaluation_step = int(st.session_state.get('evaluation_step', 5)) + config_data = { + "confidence_threshold": confidence_threshold, + "nms_threshold": nms_threshold, + "max_detections_per_image": max_detections, + "device": device, + "batch_size": batch_size, + "evaluation_step": evaluation_step, + } + with tempfile.NamedTemporaryFile(delete=False, suffix='.json', mode='w') as tmp_cfg: + json.dump(config_data, tmp_cfg) + config_path = tmp_cfg.name + except Exception as e: + st.error(f"Failed to prepare configuration: {e}") + config_path = None + + if model_file is None: + st.error("Please upload a model file") + elif config_path is None: + st.error("Please provide a valid model configuration") + elif ontology_file is None: + st.error("Please upload an ontology file") + else: + with st.spinner("Loading model..."): + # Persist ontology to temp file + try: + ontology_data = json.load(ontology_file) + with tempfile.NamedTemporaryFile(delete=False, suffix='.json', mode='w') as tmp_ont: + json.dump(ontology_data, tmp_ont) + ontology_path = tmp_ont.name + except Exception as e: + st.error(f"Failed to load ontology: {e}") + ontology_path = None + + # Persist model to temp file + try: + with tempfile.NamedTemporaryFile(delete=False, suffix='.pt', mode='wb') as tmp_model: + tmp_model.write(model_file.read()) + model_temp_path = tmp_model.name + except Exception as e: + st.error(f"Failed to save model file: {e}") + model_temp_path = None + + if ontology_path and model_temp_path: + try: + model = TorchImageDetectionModel( + model=model_temp_path, + model_cfg=config_path, + ontology_fname=ontology_path, + device=st.session_state.get('device', 'cpu'), + ) + st.session_state.detection_model = model + st.session_state.detection_model_loaded = True + st.success("Model loaded and saved for inference") + except Exception as e: + st.session_state.detection_model = None + st.session_state.detection_model_loaded = False + st.error(f"Failed to load model: {e}") + +# Main content area with horizontal tabs +tab1, tab2, tab3 = st.tabs(["Dataset Viewer", "Inference", "Evaluator"]) + +with tab1: + dataset_viewer_tab() +with tab2: + inference_tab() +with tab3: + evaluator_tab() \ No newline at end of file diff --git a/detectionmetrics/datasets/coco.py b/detectionmetrics/datasets/coco.py index 460313a3..df85832d 100644 --- a/detectionmetrics/datasets/coco.py +++ b/detectionmetrics/datasets/coco.py @@ -77,7 +77,7 @@ class CocoDataset(ImageDetectionDataset): """ def __init__(self, annotation_file: str, image_dir: str, split: str = "train"): - # Load COCO object once + # Load COCO object once - this loads all annotations into memory with efficient indexing self.coco = COCO(annotation_file) self.image_dir = image_dir self.split = split @@ -94,29 +94,29 @@ def read_annotation( ) -> Tuple[List[List[float]], List[int], List[int]]: """Return bounding boxes, labels, and category_ids for a given image ID. + This method uses COCO's efficient indexing to load annotations on-demand. + The COCO object maintains an internal index that allows for very fast + annotation retrieval without needing a separate cache. + :param fname: str (image_id in string form) :return: Tuple of (boxes, labels, category_ids) """ # Extract image ID (fname might be a path or ID string) try: - image_id = int( - os.path.basename(fname) - ) # handles both '123' and '/path/to/123' + image_id = int(os.path.basename(fname)) except ValueError: raise ValueError(f"Invalid annotation ID: {fname}") - + + # Use COCO's efficient indexing to get annotations for this image + # getAnnIds() and loadAnns() are very fast due to COCO's internal indexing ann_ids = self.coco.getAnnIds(imgIds=image_id) anns = self.coco.loadAnns(ann_ids) - - boxes = [] - labels = [] - category_ids = [] - + + boxes, labels, category_ids = [], [], [] for ann in anns: - # Convert [x, y, width, height] to [x1, y1, x2, y2] x, y, w, h = ann["bbox"] boxes.append([x, y, x + w, y + h]) labels.append(ann["category_id"]) category_ids.append(ann["category_id"]) - + return boxes, labels, category_ids diff --git a/detectionmetrics/models/torch_detection.py b/detectionmetrics/models/torch_detection.py index 83926ffe..e1594c3b 100644 --- a/detectionmetrics/models/torch_detection.py +++ b/detectionmetrics/models/torch_detection.py @@ -192,6 +192,7 @@ def __init__( model: Union[str, torch.nn.Module], model_cfg: str, ontology_fname: str, + device: torch.device = None, ): """Image detection model for PyTorch framework @@ -201,13 +202,17 @@ def __init__( :type model_cfg: str :param ontology_fname: JSON file containing model output ontology :type ontology_fname: str + :param device: torch.device to use (optional). If not provided, will auto-select cuda, mps, or cpu. """ - # Get device (GPU, MPS, or CPU) - self.device = torch.device( - "cuda" - if torch.cuda.is_available() - else "mps" if torch.backends.mps.is_available() else "cpu" - ) + # Get device (GPU, MPS, or CPU) if not provided + if device is None: + self.device = torch.device( + "cuda" + if torch.cuda.is_available() + else "mps" if torch.backends.mps.is_available() else "cpu" + ) + else: + self.device = device # Load model from file or use passed instance if isinstance(model, str): @@ -309,6 +314,8 @@ def eval( ontology_translation: Optional[str] = None, predictions_outdir: Optional[str] = None, results_per_sample: bool = False, + progress_callback=None, + metrics_callback=None, ) -> pd.DataFrame: """Evaluate model over a detection dataset and compute metrics @@ -322,6 +329,10 @@ def eval( :type predictions_outdir: Optional[str] :param results_per_sample: Store per-sample metrics :type results_per_sample: bool + :param progress_callback: Optional callback function for progress updates in Streamlit UI + :type progress_callback: Optional[Callable[[int, int], None]] + :param metrics_callback: Optional callback function for intermediate metrics updates in Streamlit UI + :type metrics_callback: Optional[Callable[[pd.DataFrame, int, int], None]] :return: DataFrame containing evaluation results :rtype: pd.DataFrame """ @@ -345,24 +356,46 @@ def eval( splits=[split] if isinstance(split, str) else split, ) + # This ensures compatibility with Streamlit and callback functions + if progress_callback is not None and metrics_callback is not None: + num_workers = 0 + else: + num_workers = self.model_cfg.get("num_workers") + dataloader = DataLoader( dataset, batch_size=self.model_cfg.get("batch_size", 1), - num_workers=self.model_cfg.get("num_workers", 1), - collate_fn=lambda x: tuple(zip(*x)), # handles variable-size targets + num_workers=num_workers, + collate_fn=lambda batch: tuple(zip(*batch)), # handles variable-size targets ) # Get iou_threshold from model config, default to 0.5 if not present iou_threshold = self.model_cfg.get("iou_threshold", 0.5) + # Get evaluation_step from model config, default to None (no intermediate updates) + evaluation_step = self.model_cfg.get("evaluation_step", None) + # If evaluation_step is 0, treat as None (disabled) + if evaluation_step == 0: + evaluation_step = None + # Init metrics metrics_factory = um.DetectionMetricsFactory( iou_threshold=iou_threshold, num_classes=self.n_classes ) + # Calculate total samples for progress tracking + total_samples = len(dataloader.dataset) + processed_samples = 0 + with torch.no_grad(): - pbar = tqdm(dataloader, leave=True) - for image_ids, images, targets in pbar: + # Use tqdm if no progress callback provided, otherwise use regular iteration + if progress_callback is None: + pbar = tqdm(dataloader, leave=True) + iterator = pbar + else: + iterator = dataloader + + for image_ids, images, targets in iterator: # Defensive check for empty images if not images or any(img.numel() == 0 for img in images): print("Skipping batch: empty image tensor detected.") @@ -448,8 +481,28 @@ def eval( predictions_outdir, f"{sample_id}_metrics.csv" ) ) + + processed_samples += 1 + + # Call progress callback if provided + if progress_callback is not None: + progress_callback(processed_samples, total_samples) + + # Call metrics callback if provided and evaluation_step is reached + if (metrics_callback is not None and + evaluation_step is not None and + processed_samples % evaluation_step == 0): + # Get intermediate metrics + intermediate_metrics = metrics_factory.get_metrics_dataframe(self.ontology) + metrics_callback(intermediate_metrics, processed_samples, total_samples) + + # Return both the DataFrame and the metrics factory for access to precision-recall curves + return { + "metrics_df": metrics_factory.get_metrics_dataframe(self.ontology), + "metrics_factory": metrics_factory + } + - return metrics_factory.get_metrics_dataframe(self.ontology) def get_computational_cost( self, image_size: Tuple[int], runs: int = 30, warm_up_runs: int = 5 diff --git a/detectionmetrics/utils/detection_metrics.py b/detectionmetrics/utils/detection_metrics.py index f2da8d70..9c61f4dc 100644 --- a/detectionmetrics/utils/detection_metrics.py +++ b/detectionmetrics/utils/detection_metrics.py @@ -9,6 +9,8 @@ def __init__(self, iou_threshold: float = 0.5, num_classes: Optional[int] = None self.iou_threshold = iou_threshold self.num_classes = num_classes self.results = defaultdict(list) # stores detection results per class + # Store raw data for multi-threshold evaluation + self.raw_data = [] # List of (gt_boxes, gt_labels, pred_boxes, pred_labels, pred_scores) def update(self, gt_boxes, gt_labels, pred_boxes, pred_labels, pred_scores): """ @@ -33,6 +35,9 @@ def update(self, gt_boxes, gt_labels, pred_boxes, pred_labels, pred_scores): if hasattr(pred_scores, "detach"): pred_scores = pred_scores.detach().cpu().numpy() + # Store raw data for multi-threshold evaluation + self.raw_data.append((gt_boxes, gt_labels, pred_boxes, pred_labels, pred_scores)) + # Handle empty inputs if len(gt_boxes) == 0 and len(pred_boxes) == 0: return # Nothing to process @@ -63,13 +68,19 @@ def _match_predictions( pred_boxes: np.ndarray, pred_labels: List[int], pred_scores: List[float], + iou_threshold: Optional[float] = None, ) -> Dict[int, List[Tuple[float, int]]]: """ Match predictions to ground truth and return per-class TP/FP flags with scores. + Args: + iou_threshold: If provided, overrides self.iou_threshold + Returns: Dict[label_id, List[(score, tp_or_fp)]] """ + if iou_threshold is None: + iou_threshold = self.iou_threshold results = defaultdict(list) used = set() @@ -90,7 +101,7 @@ def _match_predictions( max_iou = iou max_j = j - if max_iou >= self.iou_threshold: + if max_iou >= iou_threshold: results[p_label].append((score, 1)) # True positive used.add(max_j) else: @@ -148,6 +159,124 @@ def compute_metrics(self) -> Dict[int, Dict[str, float]]: return metrics + def compute_coco_map(self) -> float: + """ + Compute COCO-style mAP (mean AP over IoU thresholds 0.5:0.05:0.95). + + Returns: + float: mAP@[0.5:0.95] + """ + iou_thresholds = np.arange(0.5, 1.0, 0.05) + aps = [] + + for iou_thresh in iou_thresholds: + # Reset results for this threshold + threshold_results = defaultdict(list) + + # Process all raw data with current threshold + for gt_boxes, gt_labels, pred_boxes, pred_labels, pred_scores in self.raw_data: + # Handle empty inputs + if len(gt_boxes) == 0 and len(pred_boxes) == 0: + continue + + # Handle case where there are predictions but no ground truth + if len(gt_boxes) == 0: + for p_label, score in zip(pred_labels, pred_scores): + threshold_results[p_label].append((score, 0)) # All are false positives + continue + + # Handle case where there is ground truth but no predictions + if len(pred_boxes) == 0: + for g_label in gt_labels: + threshold_results[g_label].append((None, -1)) # All are false negatives + continue + + matches = self._match_predictions( + gt_boxes, gt_labels, pred_boxes, pred_labels, pred_scores, iou_thresh + ) + + for label in matches: + threshold_results[label].extend(matches[label]) + + # Compute AP for this threshold + threshold_ap_values = [] + for label, detections in threshold_results.items(): + detections = sorted( + [d for d in detections if d[0] is not None], key=lambda x: -x[0] + ) + tps = [d[1] == 1 for d in detections] + fps = [d[1] == 0 for d in detections] + fn_count = sum(1 for d in threshold_results[label] if d[1] == -1) + + ap, _, _ = compute_ap(tps, fps, fn_count) + threshold_ap_values.append(ap) + + # Mean AP for this threshold + if threshold_ap_values: + aps.append(np.mean(threshold_ap_values)) + else: + aps.append(0.0) + + # Return mean over all thresholds + return np.mean(aps) if aps else 0.0 + + def get_overall_precision_recall_curve(self) -> Dict[str, List[float]]: + """ + Get overall precision-recall curve data (aggregated across all classes). + + Returns: + Dict[str, List[float]] with keys 'precision' and 'recall' + """ + all_detections = [] + + # Collect all detections from all classes + for label, detections in self.results.items(): + all_detections.extend(detections) + + if len(all_detections) == 0: + return {"precision": [0.0], "recall": [0.0]} + + # Sort by score + all_detections = sorted( + [d for d in all_detections if d[0] is not None], key=lambda x: -x[0] + ) + + tps = [d[1] == 1 for d in all_detections] + fps = [d[1] == 0 for d in all_detections] + fn_count = sum(1 for d in all_detections if d[1] == -1) + + _, precision, recall = compute_ap(tps, fps, fn_count) + + return { + "precision": precision.tolist() if hasattr(precision, 'tolist') else list(precision), + "recall": recall.tolist() if hasattr(recall, 'tolist') else list(recall) + } + + def compute_auc_pr(self) -> float: + """ + Compute the Area Under the Precision-Recall Curve (AUC-PR). + + Returns: + float: Area under the precision-recall curve + """ + curve_data = self.get_overall_precision_recall_curve() + precision = np.array(curve_data['precision']) + recall = np.array(curve_data['recall']) + + # Handle edge cases + if len(precision) == 0 or len(recall) == 0: + return 0.0 + + # Sort by recall to ensure proper integration + sorted_indices = np.argsort(recall) + recall_sorted = recall[sorted_indices] + precision_sorted = precision[sorted_indices] + + # Compute AUC using trapezoidal rule + auc = np.trapz(precision_sorted, recall_sorted) + + return float(auc) + def get_metrics_dataframe(self, ontology: dict) -> pd.DataFrame: """ Get results as a pandas DataFrame. @@ -169,6 +298,20 @@ def get_metrics_dataframe(self, ontology: dict) -> pd.DataFrame: values = [v for v in metrics_dict[metric].values() if not pd.isna(v)] metrics_dict[metric]["mean"] = np.mean(values) if values else np.nan + # Add COCO-style mAP + coco_map = self.compute_coco_map() + metrics_dict["mAP@[0.5:0.95]"] = {} + for class_name in class_names: + metrics_dict["mAP@[0.5:0.95]"][class_name] = np.nan # Per-class not applicable + metrics_dict["mAP@[0.5:0.95]"]["mean"] = coco_map + + # Add AUC-PR + auc_pr = self.compute_auc_pr() + metrics_dict["AUC-PR"] = {} + for class_name in class_names: + metrics_dict["AUC-PR"][class_name] = np.nan # Per-class not applicable + metrics_dict["AUC-PR"]["mean"] = auc_pr + df = pd.DataFrame(metrics_dict) return df.T # metrics as rows, classes as columns (with mean) diff --git a/examples/tutorial_image_detection.ipynb b/examples/tutorial_image_detection.ipynb index 2bb934ae..c1c79d48 100644 --- a/examples/tutorial_image_detection.ipynb +++ b/examples/tutorial_image_detection.ipynb @@ -41,7 +41,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "metadata": {}, "outputs": [ { @@ -49,7 +49,7 @@ "output_type": "stream", "text": [ "loading annotations into memory...\n", - "Done (t=0.36s)\n", + "Done (t=0.39s)\n", "creating index...\n", "index created!\n", "Dataset loaded with 5000 samples\n", @@ -135,7 +135,8 @@ "detection_model = TorchImageDetectionModel(\n", " model=model_path,\n", " model_cfg=config_path,\n", - " ontology_fname=ontology_path # This is the model ontology (indices as keys)\n", + " ontology_fname=ontology_path, # This is the model ontology (indices as keys)\n", + " device=\"cpu\"\n", ")\n", "\n", "\n", @@ -279,7 +280,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "c464b2eff7a14f5dab25b423d48614e4", + "model_id": "486f5fb6f40b464b9a9446b2d9311702", "version_major": 2, "version_minor": 0 }, @@ -348,9 +349,17 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 12, "metadata": {}, "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "Metrics DataFrame:\n" + ] + }, { "data": { "text/html": [ @@ -540,53 +549,194 @@ "6 rows × 81 columns
\n", + "8 rows × 81 columns
\n", "" ], "text/plain": [ - " person bicycle car motorcycle airplane bus train \\\n", - "AP 0.870130 0.0 0.272727 0.636364 NaN NaN NaN \n", - "Precision 0.928571 0.0 0.500000 1.000000 NaN NaN NaN \n", - "Recall 0.928571 0.0 0.250000 0.666667 NaN NaN NaN \n", - "TP 13.000000 0.0 1.000000 2.000000 NaN NaN NaN \n", - "FP 1.000000 0.0 1.000000 0.000000 NaN NaN NaN \n", - "FN 1.000000 1.0 3.000000 1.000000 NaN NaN NaN \n", + " person bicycle car motorcycle airplane bus \\\n", + "AP 0.870130 0.0 0.272727 0.636364 NaN NaN \n", + "Precision 0.928571 0.0 0.500000 1.000000 NaN NaN \n", + "Recall 0.928571 0.0 0.250000 0.666667 NaN NaN \n", + "TP 13.000000 0.0 1.000000 2.000000 NaN NaN \n", + "FP 1.000000 0.0 1.000000 0.000000 NaN NaN \n", + "FN 1.000000 1.0 3.000000 1.000000 NaN NaN \n", + "mAP@[0.5:0.95] NaN NaN NaN NaN NaN NaN \n", + "AUC-PR NaN NaN NaN NaN NaN NaN \n", "\n", - " truck boat traffic light ... sink refrigerator book \\\n", - "AP 0.0 NaN NaN ... NaN NaN 0.106294 \n", - "Precision 0.0 NaN NaN ... NaN NaN 0.294118 \n", - "Recall 0.0 NaN NaN ... NaN NaN 0.217391 \n", - "TP 0.0 NaN NaN ... NaN NaN 5.000000 \n", - "FP 0.0 NaN NaN ... NaN NaN 12.000000 \n", - "FN 1.0 NaN NaN ... NaN NaN 18.000000 \n", + " train truck boat traffic light ... sink refrigerator \\\n", + "AP NaN 0.0 NaN NaN ... NaN NaN \n", + "Precision NaN 0.0 NaN NaN ... NaN NaN \n", + "Recall NaN 0.0 NaN NaN ... NaN NaN \n", + "TP NaN 0.0 NaN NaN ... NaN NaN \n", + "FP NaN 0.0 NaN NaN ... NaN NaN \n", + "FN NaN 1.0 NaN NaN ... NaN NaN \n", + "mAP@[0.5:0.95] NaN NaN NaN NaN ... NaN NaN \n", + "AUC-PR NaN NaN NaN NaN ... NaN NaN \n", "\n", - " clock vase scissors teddy bear hair drier toothbrush \\\n", - "AP 0.0 1.000000 NaN NaN NaN NaN \n", - "Precision 0.0 0.666667 NaN NaN NaN NaN \n", - "Recall 0.0 1.000000 NaN NaN NaN NaN \n", - "TP 0.0 2.000000 NaN NaN NaN NaN \n", - "FP 1.0 1.000000 NaN NaN NaN NaN \n", - "FN 0.0 0.000000 NaN NaN NaN NaN \n", + " book clock vase scissors teddy bear hair drier \\\n", + "AP 0.106294 0.0 1.000000 NaN NaN NaN \n", + "Precision 0.294118 0.0 0.666667 NaN NaN NaN \n", + "Recall 0.217391 0.0 1.000000 NaN NaN NaN \n", + "TP 5.000000 0.0 2.000000 NaN NaN NaN \n", + "FP 12.000000 1.0 1.000000 NaN NaN NaN \n", + "FN 18.000000 0.0 0.000000 NaN NaN NaN \n", + "mAP@[0.5:0.95] NaN NaN NaN NaN NaN NaN \n", + "AUC-PR NaN NaN NaN NaN NaN NaN \n", "\n", - " mean \n", - "AP 0.357276 \n", - "Precision 0.466075 \n", - "Recall 0.359035 \n", - "TP 1.666667 \n", - "FP 1.000000 \n", - "FN 2.055556 \n", + " toothbrush mean \n", + "AP NaN 0.357276 \n", + "Precision NaN 0.466075 \n", + "Recall NaN 0.359035 \n", + "TP NaN 1.666667 \n", + "FP NaN 1.000000 \n", + "FN NaN 2.055556 \n", + "mAP@[0.5:0.95] NaN 0.261200 \n", + "AUC-PR NaN 0.710032 \n", "\n", - "[6 rows x 81 columns]" + "[8 rows x 81 columns]" ] }, "metadata": {}, "output_type": "display_data" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA90AAAMWCAYAAADs4eXxAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAAPYQAAD2EBqD+naQAAg09JREFUeJzt3Qd4VFX6x/E3CRA6oYUuvbfQqwKKsIgFFURQQeyirsqqoKsUG7qi4l9RbAjqqiArVgSVIiAoAtIUkI6U0HsJkMz/ec91kplk0ufOnfL9PM+QmTt3JmcmN2F+95zzniiXy+USAAAAAADgd9H+f0oAAAAAAKAI3QAAAAAA2ITQDQAAAACATQjdAAAAAADYhNANAAAAAIBNCN0AAAAAANiE0A0AAAAAgE0I3QAAAAAA2ITQDQAAAACATQjdAABH1ahRQ6Kiosxl9OjRqdvnz5+ful0v27Ztk0igr9Pzdev7kFeezzN58mS/thNZ47gGALgRugEgCKxatUqGDh0qTZs2lbi4OClUqJBUqFBBLr74Yhk3bpwcPXrU6SaGjK5du3qFGvelQIECEh8fLz169JD3339fXC6X002Fj4DqeSlatKjUqlVLrr/+epk3b57TzQwKetzOnDlTbrrpJqlXr56ULFlSChYsaP5eXHLJJfL888/Lnj17nG4mAMBDAc8bAIDAOn/+vPzrX/+S//u//8tw3759+8xFw4Z+kP7vf/9rAiPyJjk5Wfbv3y/ff/+9uUybNk1mzJhhAkswKVOmjLzwwgupt2vXrp3n5/J8njZt2kioOX36tGzdutVcpk6dKm+++abccccdEqn++usvGThwoCxatCjDffq3Yu7cueaybt06RjYAQBAhdAOAg+677z6ZOHFi6u3KlSvLddddJ+XKlZM1a9bI9OnTTVg8cOCAXHHFFeYDdadOnSSYaPuSkpJMr2SwKV26tDz22GPm+t69e+WDDz4wX9U333wjr7/+utx///3ZPs/Zs2dND2NsbKztbdaey4ceesgvz+Wv5wkk7dm+++67zXu+evVqc3LEPSpBf5a33XabREdH3kA9PW67dOliTkC41axZU6688krTy3348GH5+eeffQbySPqdB4Cg5AIAOOKnn37SJJF6admypevo0aNe+8yZM8cVHR2duk/jxo1dycnJ5nLBBRekbh81alSG53/kkUdS769b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X/vlVOHCReTs2bM+79NK6np/Tp04cUK+/fYLufjintkOi8+uTUlJSRm26ygA9/0AEPRzuidMmCA1atQwZwzbtWsnS5cuzXTft99+Wy688EIpXbq0uXTv3j3L/QEAAIKBrpOtQ5U1mOra0+6LrqGtPAuqaa9uVr2op0+f8uptrVu3gfn6xx9rsm3Hrl1/SYMGlbwuWk09/Xzlrl27S+fOXc1c5syCtA5n1/169+4jb7wxRXr1ulIeeOB22bnzL8kLHbKtJwX279/ntV2DuA4T1+JnOfXNN5+bquX5GVquKlasJPv2JZqlx9IPhVe5aROAyBB0oXvq1KkybNgwGTVqlKxYsUKaN28uPXv2lH37vP/Yus2fP18GDBgg8+bNkyVLlki1atWkR48esmvXroC3HQAAIKc+/fQjM1d58uRPM1y0oJqupa1VyN3DtHU97I0bN/h8Lt2u95ctW87cbt++syle9r//fWxCa1bi4yvKjBnfe12aNGnul9c4atRzpgf4xRefydPjmzZNMF9/+22Z13a9rcuGNWli3Z8TehKjePHi5kRAfuj31PC+YYM1b95t2bJfUu8HgKAO3S+99JLcfvvtMmTIEGnUqJFMnDjR/CcyadIkn/v/97//laFDh0pCQoI0aNBA3nnnHfNHeM6cOQFvOwAAQE5omP76689MITJd1zr95fbb75Xjx4/Lt99+afbXud3duvWQWbO+MsttedLbs2d/Ze53zwHXz0733z/cBMPRo4dn6JVVU6d+KMuXLzW949o77XnJau3r3KhZs7Ypovbxx5Nl797EXC8ZdtFFF5uh7pMmveG1XW/ra+zZs3fqNi3gps+pgTg9HT7/448/SO/eV5vH5cdll11l5oW/++7rqdv0/X3vvYlmjnu7dh3z9fwAwk9QzenWoULLly+XRx99NHWbDl/SIePai50T+odWK2aWKVPGxpYCAADk3bfffmVCdWa9rm3atDe929o7q4XV1BNPPCuXXtpeunZtKYMH32GWvNIluaZMecvM5db7Pf3znw/L+vW/m/nhut61rgFeoUJFE35nzvzcBO7Zs72Hkdvhvvselhkzpskbb4yX0aOfS10y7KeffpTDhzOeDPCkFdIfe+wpefjhe+Tmm/uZ+dhLliw0heYef/wZE8jd3n77NXn++THy1VfzzDB4T599NlXOnz+f5dDytWtXy6xZ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/+abbxxoNeCfY7p69ermD0r6i/6nCITq32lPhG6E+vG8ePFiszypBhtdPuyZZ54xy+IBoXhMnzt3zjV69GgTtAsXLuyqVq2aa+jQoa7Dhw871HrA27x583x+NnYfx/pVj+v0j0lISDC/A/p3+r333nPlRpT+4/9OeAAAAAAAENZzugEAAAAAcBKhGwAAAAAAmxC6AQAAAACwCaEbAAAAAACbELoBAAAAALAJoRsAAAAAAJsQugEAAAAAsAmhGwAAAAAAmxC6AQCA30RFRcno0aNTb0+ePNls27Ztm6PtAgDAKYRuAABCiDvEui8FChSQKlWqyM033yy7du1yunkAACCdAuk3AACA4Pfkk09KzZo15cyZM/Lzzz+bML5o0SJZu3atFC5c2OnmAQCAvxG6AQAIQb169ZLWrVub67fddpuUK1dOnn/+efnyyy/luuuuc7p5AADgbwwvBwAgDFx44YXm6+bNm1O3rV+/Xvr27StlypQxvd8a0jWUp3fkyBF58MEHpUaNGhIbGytVq1aVQYMGyYEDB8z9Z8+elZEjR0qrVq2kVKlSUqxYMfP95s2bF8BXCABAaKKnGwCAMOAuVFa6dGnz9ffff5dOnTqZ+d4jRowwQXnatGnSp08f+d///idXX3212e/EiRMmQK9bt05uueUWadmypQnbGs537txpetCPHTsm77zzjgwYMEBuv/12OX78uLz77rvSs2dPWbp0qSQkJDj62gEACGaEbgAAQtDRo0dNONY53b/88ouMGTPG9FJffvnl5v77779fLrjgAvn111/NdjV06FDp3LmzDB8+PDV0v/DCC2Ye+GeffZa6TT3++OPicrlSg7yG+kKFCqXer+G7QYMG8uqrr5oADgAAfGN4OQAAIah79+5Svnx5qVatmhlCrj3Z2jutQ8MPHTokc+fONXO7tVdaw7leDh48aHqnN27cmFrpXHu9mzdv7hW43bQ6uoqJiUkN3CkpKeb5z58/b4arr1ixIsCvHACA0EJPNwAAIWjChAlSr1490+M9adIkWbBgQWqP9qZNm0wv9RNPPGEuvuzbt88MPdc54Ndee22232/KlCny4osvmnni586dS92uFdQBAEDmCN0AAISgtm3bplYv13naOmx84MCBsmHDBtMbrR566CHTs+1LnTp1cvy9PvzwQ7MOuH6fhx9+WOLj403v99ixY70KtwEAgIwI3QAAhDh3AO7WrZu89tprpiCaKliwoBmGnpXatWubOd1ZmT59utSqVcvM+3YPOVejRo3y0ysAACB8MacbAIAw0LVrV9P7PX78eClZsqS5/eabb8qePXsy7Lt///7U6zq0fNWqVTJjxowM+7kLqWmo97yttHjbkiVLbHo1AACED3q6AQAIEzr0u1+/fjJ58mQz51uHnDdt2tRUGtee6r1795qgrEuBadB2P0Z7svVx2kOua3FroTQtyjZx4kRTZE0rorurm/fu3Vu2bt1q7mvUqJFZcgwAAGSO0A0AQJi45pprzHDxcePGmaC9bNkys5SYhnCtXK5zsVu0aCEjR45MfUzx4sVl4cKFZqi49nZrwTTd75JLLjGV0JXO505MTDQ957NnzzZhW+d5f/rppzJ//nwHXzEAAMEvyuU5VgwAAAAAAPgNc7oBAAAAALAJoRsAAAAAAJsQugEAAAAAsAmhGwAAAAAAmxC6AQAAAACwCaEbAAAAAACbELoBAAAAALAJoRsAAAAAAJsQugEAAAAAsAmhGwAAAAAAmxC6AQAAAACwCaEbAAAAAACbELoBAAAAABB7/D/Q/jZ8i8//UgAAAABJRU5ErkJggg==", + "text/plain": [ + "