-
Notifications
You must be signed in to change notification settings - Fork 644
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added PAT metric #659
Added PAT metric #659
Conversation
@@ -336,6 +382,65 @@ def get_lstq(self) -> Tuple[np.ndarray, np.ndarray]: | |||
lstq = np.sqrt(s_assoc * s_cls) | |||
return lstq, s_assoc | |||
|
|||
def get_pat(self) -> Tuple[np.ndarray, np.ndarray]: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return Tuple should have 3 arrays.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
pq_all = sq_all * rq_all | ||
|
||
# then do the REAL mean (no ignored classes) | ||
SQ = sq_all[self.include].mean() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use low-case variables to be consistent
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove unused SQ, RQ.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
#accumulate class-agnostic predictions | ||
unique_pred_, counts_pred_ = np.unique(x_inst_row[1][x_inst_row[1] > 0], return_counts=True) | ||
for p_id in unique_pred_[counts_pred_ > self.min_points]: | ||
if p_id not in self.instance_preds[scene]: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
indentation is incorrect
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
corrected
unique_pr_id, counts_pr_id = np.unique(pr_ids, return_counts=True) | ||
|
||
track_length = len(pr_ids) | ||
unique_pr_id, counts_pr_id = unique_pr_id[unique_pr_id!=1], counts_pr_id[unique_pr_id!=1] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could you add more inline comments for lines like this, why need to remove pr_id == 1, I feel it is hard to decode all the logic by just reading the code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
matched_gt_[[id2idx_gt_[g_id] for g_id in gt_labels_[tp_indexes_agnostic]]] = True | ||
|
||
for idx, value in enumerate(tp_indexes_agnostic): | ||
if value == True: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use if value:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
self.instance_gts[scene][cl][g_label].append(p_label) | ||
|
||
for g_label in unique_gt_: | ||
if matched_gt_[id2idx_gt_[g_label]] == False: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use if not matched_gt_[id2idx_gt_[g_label]]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
for g_label in unique_gt_: | ||
if matched_gt_[id2idx_gt_[g_label]] == False: | ||
if g_label not in self.instance_gts[scene][cl]: | ||
self.instance_gts[scene][cl][g_label] = [1,] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could you double check the indentations, here has 5 spaces, i see many places have wrong indentations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
pred_areas_ = np.array([counts_pred_[id2idx_pred_[p_id]] for p_id in pred_labels_]) | ||
intersections_ = counts_combo_ | ||
unions_ = gt_areas_ + pred_areas_ - intersections_ | ||
ious_agnostic = intersections_.astype(np.float32) / unions_.astype(np.float32) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could unions be 0?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No. gt_areas_ can never be 0.
@@ -186,6 +224,14 @@ def add_batch_panoptic(self, | |||
x_inst_row[0] = x_inst_row[0][gt_not_in_excl_mask] | |||
y_inst_row[0] = y_inst_row[0][gt_not_in_excl_mask] | |||
|
|||
#accumulate class-agnostic predictions |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Format to: # Accumulate
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
unique_pr_id, counts_pr_id = np.unique(pr_ids, return_counts=True) | ||
|
||
track_length = len(pr_ids) | ||
unique_pr_id, counts_pr_id = unique_pr_id[unique_pr_id!=1], counts_pr_id[unique_pr_id!=1] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
spacing around !=
fp_pr_id.append(0) | ||
|
||
fp_pr_id = np.array(fp_pr_id) | ||
gt_id_aq = (np.sum(counts_pr_id**2/np.double(track_length + fp_pr_id)))/np.double(track_length) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's add more spacing around operators
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
unique_pred_, counts_pred_ = np.unique(x_inst_row[x_inst_row > 0], return_counts=True) | ||
id2idx_pred_ = {inst_id: idx for idx, inst_id in enumerate(unique_pred_)} | ||
gt_labels_ = unique_combo_ // self.offset | ||
pred_labels_ = unique_combo_ % self.offset |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps some comments on what these two lines are doing?:
gt_labels_ = unique_combo_ // self.offset
pred_labels_ = unique_combo_ % self.offset
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added the comment. Let me know if it is intuitive.
@@ -160,6 +196,8 @@ def add_batch_panoptic(self, | |||
self.gts[scene] = [{} for _ in range(self.n_classes)] | |||
self.intersects[scene] = [{} for _ in range(self.n_classes)] | |||
self.intersects_ovr[scene] = [{} for _ in range(self.n_classes)] | |||
self.instance_preds[scene] = {} | |||
self.instance_gts[scene] = [{} for _ in range(self.n_classes)] | |||
# Make sure instance IDs are non-zeros. Otherwise, they will be ignored. Note in nuScenes-panoptic, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nuScenes-panoptic
--> Panoptic nuScenes
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Corrected it
track_length = len(pr_ids) | ||
# void/stuff have instance value 1 due to the +1 in ln205 as well as unmatched gt is denoted by 1 | ||
# Thus we remove 1 from the prediction id list | ||
unique_pr_id, counts_pr_id = unique_pr_id[unique_pr_id != 1], counts_pr_id[unique_pr_id != 1] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tks for the inline comment, sigh, this looks like a hack on top of another hack..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup
# preds[uid]: TPA + FPA (class-agnostic) | ||
# counts_pr_id[idx]: TPA (class-agnostic) | ||
# If prediction id is not in preds it means it has number of points < self.min_points. | ||
# Similar to PQ computation we consider pred with number of points < self.min_points with IoU overlap greater than 0.5 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
change line if it exceeds 120 line width
# Total possible id switches | ||
total_ids = track_length - 1 | ||
# Gt tracks with no corresponding prediction match are assigned 1. | ||
# We consider an id switch occurs if previous predicted id and the current one don't match for the given gt track |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
exceed 120 line width
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
unique_pr_id, counts_pr_id = unique_pr_id[unique_pr_id != 1], counts_pr_id[unique_pr_id != 1] | ||
fp_pr_id = [] | ||
|
||
# Computes the total false positve for each prediction id: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo: positive
pq = pq_all[self.include].mean() | ||
|
||
accumulate_tq = 0.0 | ||
accumlate_norm = 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo: accumulate_norm
# Accumulate TQ over all the possible unique gt instances | ||
accumulate_tq += np.sqrt(gt_id_aq * gt_id_is) | ||
# Count the total number of unique gt instances | ||
accumlate_norm +=1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
minor: space after +=, similarly for line 461.
@@ -129,6 +133,48 @@ def get_panoptic_track_stats(self, | |||
unique_combo_, counts_combo_ = np.unique(offset_combo_, return_counts=True) | |||
self.update_dict_stat(cl_intersects, unique_combo_, counts_combo_) | |||
|
|||
# Computation for PAT score |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could you help to correct the return typing to Tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray, Dict[int, int], Dict[int, int], np.ndarray]
in lines 83-84. tks.
mean_ptq, class_all_ptq, mean_sptq, class_all_sptq = self.evaluator['tracking'].get_ptq() | ||
mean_iou, class_all_iou = self.evaluator['tracking'].getSemIoU() | ||
lstq, s_assoc = self.evaluator['tracking'].get_lstq() | ||
mean_motsa, mean_s_motsa, mean_motsp = self.evaluator['tracking'].get_motsa() | ||
|
||
results = self.wrap_result_mopt(mean_ptq=mean_ptq, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
update the function doc-string part at line 203-210 to add the added PAT, PQ, TQ fields
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Took a second pass, clearer that previous round, even though it's still hard for me to follow the logic for all the details due to the implementation complexity, but think it's hard to improve that without massive changes. So I'd proceed to approve it due to the time being.
@mohan1914 Pls promote the version to 1.1.8 for following 2 places. you can refer to PR |
Add PAT metric for panoptic tracking evaluation.