Gil-Simas commited on
Commit
20e96a5
·
1 Parent(s): 52b3f36
Files changed (1) hide show
  1. user-friendly-metrics.py +54 -9
user-friendly-metrics.py CHANGED
@@ -108,10 +108,7 @@ def num_gt_ids(df):
108
  def calculate(predictions,
109
  references,
110
  max_iou: float = 0.5,
111
- recognition_thresholds: list = [0.3, 0.5, 0.8],
112
- namemap = {"num_misses": "fn",
113
- "num_false_positives": "fp",
114
- "num_detections": "tp"}
115
  ):
116
 
117
  """Returns the scores"""
@@ -147,12 +144,16 @@ def calculate(predictions,
147
  acc.update(refs[:,0].astype('int').tolist(), preds[:,0].astype('int').tolist(), C)
148
 
149
  mh = mm.metrics.create()
150
- summary = mh.compute(acc, metrics=['recall', 'precision', 'num_misses', 'num_false_positives', 'num_detections']).to_dict()
151
 
152
  df = events_to_df_map(acc.events)
153
  tr_ratios = track_ratios(df, obj_frequencies(df))
154
  unique_gt_ids = num_gt_ids(df)
155
 
 
 
 
 
156
  for key in list(summary.keys()):
157
  if key in namemap:
158
  summary[namemap[key]] = float(summary[key][0])
@@ -164,7 +165,6 @@ def calculate(predictions,
164
 
165
  for th in recognition_thresholds:
166
  recognized = recognition(tr_ratios, th)
167
- summary[f'recognition_{th}'] = float(recognition(tr_ratios, th)/unique_gt_ids)
168
  summary[f'recognized_{th}'] = int(recognized)
169
 
170
  return summary
@@ -245,10 +245,55 @@ def calculate_from_payload(payload: dict,
245
  filter_range_name = filter_range[0]
246
  output[sequence][model][filter][filter_range_name] = calculate(formated_predictions, all_formated_references[filter][filter_range_name], max_iou=max_iou, recognition_thresholds = recognition_thresholds)
247
 
248
- return output
 
 
 
 
249
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
250
 
 
 
 
 
 
251
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
252
 
253
-
254
-
 
108
  def calculate(predictions,
109
  references,
110
  max_iou: float = 0.5,
111
+ recognition_thresholds: list = [0.3, 0.5, 0.8]
 
 
 
112
  ):
113
 
114
  """Returns the scores"""
 
144
  acc.update(refs[:,0].astype('int').tolist(), preds[:,0].astype('int').tolist(), C)
145
 
146
  mh = mm.metrics.create()
147
+ summary = mh.compute(acc, metrics=['num_misses', 'num_false_positives', 'num_detections']).to_dict()
148
 
149
  df = events_to_df_map(acc.events)
150
  tr_ratios = track_ratios(df, obj_frequencies(df))
151
  unique_gt_ids = num_gt_ids(df)
152
 
153
+ namemap = {"num_misses": "fn",
154
+ "num_false_positives": "fp",
155
+ "num_detections": "tp"}
156
+
157
  for key in list(summary.keys()):
158
  if key in namemap:
159
  summary[namemap[key]] = float(summary[key][0])
 
165
 
166
  for th in recognition_thresholds:
167
  recognized = recognition(tr_ratios, th)
 
168
  summary[f'recognized_{th}'] = int(recognized)
169
 
170
  return summary
 
245
  filter_range_name = filter_range[0]
246
  output[sequence][model][filter][filter_range_name] = calculate(formated_predictions, all_formated_references[filter][filter_range_name], max_iou=max_iou, recognition_thresholds = recognition_thresholds)
247
 
248
+ global_and_per_sequence_output = {}
249
+ global_and_per_sequence_output["global"] = per_sequence_to_global(output, recognition_thresholds)
250
+ global_and_per_sequence_output["per_sequence"] = output
251
+
252
+ return global_and_per_sequence_output
253
 
254
+ def sum_dicts(dict1, dict2):
255
+ """
256
+ Recursively sums the numerical values in two nested dictionaries.
257
+ """
258
+ result = {}
259
+ for key in dict1.keys() | dict2.keys(): # Union of keys from both dictionaries
260
+ val1 = dict1.get(key, 0)
261
+ val2 = dict2.get(key, 0)
262
+ if isinstance(val1, dict) and isinstance(val2, dict):
263
+ # If both values are dictionaries, recursively sum them
264
+ result[key] = sum_dicts(val1, val2)
265
+ elif isinstance(val1, (int, float)) and isinstance(val2, (int, float)):
266
+ # If both are numbers, sum them
267
+ result[key] = val1 + val2
268
+ else:
269
+ # If only one dictionary has the key, take the non-zero value
270
+ result[key] = val1 if val1 != 0 else val2
271
+ return result
272
 
273
+ def realize_metrics(metrics_dict,
274
+ recognition_thresholds):
275
+ metrics_dict["precision"] = metrics_dict["tp"]/(metrics_dict["tp"]+metrics_dict["fp"])
276
+ metrics_dict["recall"] = metrics_dict["tp"]/(metrics_dict["tp"]+metrics_dict["fn"])
277
+ metrics_dict["f1"] = 2*metrics_dict["precision"]*metrics_dict["recall"]/(metrics_dict["precision"]+metrics_dict["recall"])
278
 
279
+ for th in recognition_thresholds:
280
+ metrics_dict[f"recognition_{th}"] = metrics_dict[f"recognized_{th}"]/metrics_dict["num_gt_ids"]
281
+
282
+ return metrics_dict
283
+
284
+ def per_sequence_to_global(metrics_dict,
285
+ recognition_thresholds):
286
+ global_metrics = {}
287
+ for sequence in metrics_dict:
288
+ for model in metrics_dict[sequence]:
289
+ if model not in global_metrics:
290
+ global_metrics[model] = metrics_dict[sequence][model]
291
+ global_metrics[model] = sum_dicts(global_metrics[model], metrics_dict[sequence][model])
292
+ metrics_dict[sequence][model] = realize_metrics(metrics_dict[sequence][model],
293
+ recognition_thresholds)
294
+
295
+ for model in global_metrics:
296
+ global_metrics[model] = realize_metrics(global_metrics[model],
297
+ recognition_thresholds)
298
 
299
+ return global_metrics