ClementPinard / SfmLearner-Pytorch

Pytorch version of SfmLearner from Tinghui Zhou et al.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

ATE calculation in compute_pose_errors()

seb-le opened this issue · comments

Hi. Thank you for your nice PyTorch implementation.

I have a question when studying your source code.

In "compute_pose_errors()" function of loss_functions.py,

when returning "ATE/snippet_length", that ATE is only ATE with respect to last snippets of the mini-batch.
(There is no saving or accumulating the ATE in For loop.)

Is this intended implementation?

Thank you!

Yes, it is to match original author code.
See here : https://github.com/tinghuiz/SfMLearner/blob/master/test_kitti_pose.py
I agree that it's a very permissive technique, but reconstructing the whole trajectory with only 5-frame of 3-frame snippets is ambiguous, see here : #39

Thank you for your quick answer.

As you said, I saw the original author code.

In the author code, the ATE is computed as the average of all of 5 frame snippets.
(It is not refer to the whole trajectory ATE)
https://github.com/tinghuiz/SfMLearner/blob/master/test_kitti_pose.py
https://github.com/tinghuiz/SfMLearner/blob/master/kitti_eval/eval_pose.py
https://github.com/tinghuiz/SfMLearner/blob/master/kitti_eval/pose_evaluation_utils.py

But, As I see the PyTorch implementation,

the "compute_pose_errors()" of "loss_functions.py"(not "test_pose.py") return the "ATE/snippet_length",

but that ATE is only ATE with respect to last snippet of the mini-batch.(not all snippets of the mini-batch)

It means that only ATE of every last snippet of mini-batch is used to calculate the average in "validate_with_gt_pose()" of "train.py"

If the PyTorch implementation is identical to author code, isn't the code below correct?

def compute_pose_errors(gt, pred):
    for (current_gt, current_pred) in zip(gt, pred):
        ( ... )
        ATE += torch.norm((current_gt[..., -1] - scale_factor * current_pred[..., -1]).reshape(-1)).cpu().numpy()
        ( ... )

return [ATE / snippet_length / batch_size , RE / snippet_length]

instead of

ATE = torch.norm((current_gt[..., -1] - scale_factor * current_pred[..., -1]).reshape(-1)).cpu().numpy()
( ... )
return [ATE / snippet_length, RE / snippet_length]

Of course, the "validate_with_gt_pose()" of "train.py" is also changed as below.

pose_errors.update(compute_pose_errors(gt_poses, final_poses), n=batch_size)

instead of

pose_errors.update(compute_pose_errors(gt_poses, final_poses))

Additionally, Could you let me know a reference or keyword with respect to RE?

I cannot find a material for RE metric.

I am sorry to ask you again because of my lack of knowledge.

Thank you!

Indeed you are right. My code is actually computing sqrt(sum(ATE^2))/seq_length instead of sum(ATE)/seq_length

I can change it or you can propose a PR if you want.

As for RE, it is the angle between the two rotations, ie, the angle of the rotation R1*R2^-1
See some documentation about it here : http://www.boris-belousov.net/2016/12/01/quat-dist/

I don't have any scientific article to back this RE metric, it only serves an indicative purpose. Normally ATE should be enough, but it focuses more on the rotation that the ATE which is a function of both rotation and translation estimation

Thank you for your kind answer!

I am learning a lot about this research field thanks to your answers and source code.

Thank you.