ThibaultGROUEIX / ChamferDistancePytorch

Chamfer Distance in Pytorch with f-score
MIT License
326 stars 43 forks source link

test camfer failed #2

Closed tornadomeet closed 4 years ago

tornadomeet commented 4 years ago

pc1.npy.zip pc2.npy.zip

the test will be failed if using the above of two point cloud, which the shape is [1, 8192, 3]. i found the min index is different between ext.chamferDist() and chamfer_python.distChamfer.

test will be ok if using https://github.com/ThibaultGROUEIX/chamfer_pytorch/blob/master/test_chamfer.py

pytorch version : 1.2

test code:

import torch
import dist_chamfer_idx as ext
import chamfer_python
distChamfer = ext.chamferDist()
from torch.autograd import Variable
import time
import numpy as np

def test_chamfer():
    distChamfer = ext.chamferDist()
    p1 = torch.from_numpy(np.load("pc1.npy")).cuda()
    p2 = torch.from_numpy(np.load("pc2.npy")).cuda()
    points1 = Variable(p1, requires_grad=True)
    points2 = Variable(p2)
    dist1, dist2, idx1, idx2= distChamfer(points1, points2)

    loss = torch.sum(dist1)
    print(loss)
    loss.backward()
    print(points1.grad, points2.grad)

    mydist1, mydist2, myidx1, myidx2 = chamfer_python.distChamfer(points1, points2)
    d1 = (dist1 - mydist1) ** 2
    d2 = (dist2 - mydist2) ** 2
    xd1 = idx1 - myidx1
    xd2 = idx2 - myidx2
    print("d1 = \n", d1)
    print("d2 = \n", d2)
    print("diff sum = \n", torch.sum(d1) + torch.sum(d2))
    print("xd1 = \n", xd1)
    print("xd2 = \n", xd2)
    print("xdiff norm sum = \n", torch.norm(xd1.float()) + torch.norm(xd2.float()))

    assert (
        torch.sum(d1) + torch.sum(d2) < 0.00000001
    ), "distance : chamfer cuda and chamfer normal are not giving the same results"
    assert (
            torch.norm(xd1.float()) + torch.norm(xd2.float()) == 0
    ), "index : chamfer cuda and chamfer normal are not giving the same results"

test_chamfer()

@ThibaultGROUEIX

ThibaultGROUEIX commented 4 years ago

Hi @tornadomeet

This is the conjunction of two factors: -- 1 : i sum the errors on the points. You use more points than my test case, and the points size is two orders of magnitude larger than my test. This introduces a difference of about 1000 between the test case and your test. --2 : chamfer_python has some numerical instability because of the type of the tensors (float). There are no longer any differences in the idx after changing them to double.

In summary, you can just git pull and your test should pass.

Best regards, Thibault

tornadomeet commented 4 years ago

thanks @ThibaultGROUEIX Now the test has passed!