Skip to content
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

Merged
merged 5 commits into from
Sep 18, 2021
Merged

Added PAT metric #659

merged 5 commits into from
Sep 18, 2021

Conversation

mohan1914
Copy link
Contributor

Add PAT metric for panoptic tracking evaluation.

@@ -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]:
Copy link
Contributor

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.

Copy link
Contributor Author

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()
Copy link
Contributor

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

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove unused SQ, RQ.

Copy link
Contributor Author

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]:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

indentation is incorrect

Copy link
Contributor Author

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]
Copy link
Contributor

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.

Copy link
Contributor Author

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:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use if value:

Copy link
Contributor Author

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:
Copy link
Contributor

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]]

Copy link
Contributor Author

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,]
Copy link
Contributor

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.

Copy link
Contributor Author

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)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could unions be 0?

Copy link
Contributor Author

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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Format to: # Accumulate

Copy link
Contributor Author

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]
Copy link
Contributor

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)
Copy link
Contributor

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

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@holger-motional holger-motional changed the title added PAT metric Added PAT metric Sep 15, 2021
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
Copy link
Collaborator

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

Copy link
Contributor Author

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,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nuScenes-panoptic --> Panoptic nuScenes?

Copy link
Contributor Author

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]
Copy link
Contributor

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..

Copy link
Contributor Author

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
Copy link
Contributor

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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

exceed 120 line width

Copy link
Contributor Author

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:
Copy link
Contributor

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
Copy link
Contributor

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
Copy link
Contributor

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
Copy link
Contributor

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,
Copy link
Contributor

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

Copy link
Contributor

@lubing-motional lubing-motional left a 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.

@lubing-motional
Copy link
Contributor

lubing-motional commented Sep 17, 2021

@mohan1914 Pls promote the version to 1.1.8 for following 2 places. you can refer to PR
(1) https://github.com/nutonomy/nuscenes-devkit/blob/master/setup/setup.py#L42
(2) https://github.com/nutonomy/nuscenes-devkit/blob/master/README.md, Add following line in the ChangeLog
"Sep 17, 2021: Devkit v1.1.8: Add PAT metric to Panoptic nuScenes."

@lubing-motional lubing-motional merged commit 5058621 into nutonomy:master Sep 18, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

4 participants