Repository: deepchecks/deepchecks

Issue:
[FEAT][CV] Improve conditions on vision metric checks
Current performance degradation thresholds on performance metrics are too rigid - they often raise an alarm when non is warranted, and they are not adaptive to the dependence of these metrics on the number of classes.

Suggestions:
1. Condition should be on train-test change, not abs value
2. Condition should be on performing worse than 1/n_classes, or something along these lines. 


Discussion:

Resolving patch:
diff --git a/deepchecks/core/check_result.py b/deepchecks/core/check_result.py
--- a/deepchecks/core/check_result.py
+++ b/deepchecks/core/check_result.py
@@ -239,11 +239,11 @@ def to_wandb(self, dedicated_run: bool = True, **kwargs: Any):
         for item in self.display:
             if isinstance(item, Styler):
                 wandb.log({f'{section_suffix}display_table_{table_i}':
-                           wandb.Table(dataframe=item.data, allow_mixed_types=True)}, commit=False)
+                           wandb.Table(dataframe=item.data.reset_index(), allow_mixed_types=True)}, commit=False)
                 table_i += 1
             elif isinstance(item, pd.DataFrame):
                 wandb.log({f'{section_suffix}display_table_{table_i}':
-                           wandb.Table(dataframe=item, allow_mixed_types=True)}, commit=False)
+                           wandb.Table(dataframe=item.reset_index(), allow_mixed_types=True)}, commit=False)
                 table_i += 1
             elif isinstance(item, str):
                 pass
diff --git a/deepchecks/vision/checks/performance/mean_average_precision_report.py b/deepchecks/vision/checks/performance/mean_average_precision_report.py
--- a/deepchecks/vision/checks/performance/mean_average_precision_report.py
+++ b/deepchecks/vision/checks/performance/mean_average_precision_report.py
@@ -94,7 +94,7 @@ def compute(self, context: Context, dataset_kind: DatasetKind) -> CheckResult:
         return CheckResult(value=results, display=[results, fig])
 
     def add_condition_test_average_precision_not_less_than(self: MPR, min_score: float) -> MPR:
-        """Add condition - mAP score is not less than given score.
+        """Add condition - AP scores in different area thresholds is not less than given score.
 
         Parameters
         ----------
@@ -113,3 +113,21 @@ def condition(df: pd.DataFrame):
             return ConditionResult(True)
 
         return self.add_condition(f'Scores are not less than {min_score}', condition)
+
+    def add_condition_test_mean_average_precision_not_less_than(self: MPR, min_score: float = 0.3) -> MPR:
+        """Add condition - mAP score in all areas is not less than given score.
+
+        Parameters
+        ----------
+        min_score : float
+            Minimum score to pass the check.
+        """
+        def condition(df: pd.DataFrame):
+            df = df.reset_index()
+            value = df.loc[df['Area size'] == 'All', :]['mAP@0.5..0.95 (%)'][0]
+            if value < min_score:
+                details = f'mAP score is: {format_number(value)}'
+                return ConditionResult(False, details)
+            return ConditionResult(True)
+
+        return self.add_condition(f'mAP score is not less than {min_score}', condition)
diff --git a/deepchecks/vision/suites/default_suites.py b/deepchecks/vision/suites/default_suites.py
--- a/deepchecks/vision/suites/default_suites.py
+++ b/deepchecks/vision/suites/default_suites.py
@@ -15,7 +15,7 @@
 """
 from deepchecks.vision.checks import ClassPerformance, TrainTestLabelDrift, MeanAveragePrecisionReport, \
     MeanAverageRecallReport, ImagePropertyDrift, ImageDatasetDrift, SimpleModelComparison, ConfusionMatrixReport, \
-    RobustnessReport, TrainTestPredictionDrift, ImageSegmentPerformance, SimpleFeatureContribution
+    TrainTestPredictionDrift, ImageSegmentPerformance, SimpleFeatureContribution
 from deepchecks.vision import Suite
 
 
@@ -30,7 +30,7 @@ def train_test_validation() -> Suite:
     return Suite(
         'Train Test Validation Suite',
         HeatmapComparison(),
-        TrainTestLabelDrift(),
+        TrainTestLabelDrift().add_condition_drift_score_not_greater_than(),
         TrainTestPredictionDrift().add_condition_drift_score_not_greater_than(),
         ImagePropertyDrift().add_condition_drift_score_not_greater_than(),
         ImageDatasetDrift(),
@@ -42,13 +42,12 @@ def model_evaluation() -> Suite:
     """Create a suite that is meant to test model performance and overfit."""
     return Suite(
         'Model Evaluation Suite',
-        ClassPerformance(),
-        MeanAveragePrecisionReport(),
+        ClassPerformance().add_condition_train_test_relative_degradation_not_greater_than(),
+        MeanAveragePrecisionReport().add_condition_test_mean_average_precision_not_less_than(),
         MeanAverageRecallReport(),
         SimpleModelComparison(),
         ConfusionMatrixReport(),
-        RobustnessReport().add_condition_degradation_not_greater_than(),
-        ImageSegmentPerformance()
+        ImageSegmentPerformance().add_condition_score_from_mean_ratio_not_less_than()
     )
 
 


Test patch:
diff --git a/tests/vision/checks/performance/mean_average_precision_report_test.py b/tests/vision/checks/performance/mean_average_precision_report_test.py
--- a/tests/vision/checks/performance/mean_average_precision_report_test.py
+++ b/tests/vision/checks/performance/mean_average_precision_report_test.py
@@ -31,7 +31,9 @@ def test_coco(coco_test_visiondata, trained_yolov5_object_detection, device):
     # Arrange
     check = MeanAveragePrecisionReport() \
             .add_condition_test_average_precision_not_less_than(0.1) \
-            .add_condition_test_average_precision_not_less_than(0.4)
+            .add_condition_test_average_precision_not_less_than(0.4) \
+            .add_condition_test_mean_average_precision_not_less_than() \
+            .add_condition_test_mean_average_precision_not_less_than(0.5)
 
     # Act
     result = check.run(coco_test_visiondata,
@@ -69,6 +71,17 @@ def test_coco(coco_test_visiondata, trained_yolov5_object_detection, device):
                 "'Medium (32^2 < area < 96^2)': {'AP@.75 (%)': '0.35'}}"
     ))
 
+    assert_that(result.conditions_results[2], equal_condition_result(
+        is_pass=True,
+        name='mAP score is not less than 0.3'
+    ))
+
+    assert_that(result.conditions_results[3], equal_condition_result(
+        is_pass=False,
+        name='mAP score is not less than 0.5',
+        details="mAP score is: 0.41"
+    ))
+
 
 def test_coco_area_param(coco_test_visiondata, trained_yolov5_object_detection, device):
     # Arrange