jeanfeydy / geomloss

Geometric loss functions between point clouds, images and volumes
MIT License
586 stars 57 forks source link

Error when using the hausdorff distance #70

Open de-gozaru opened 1 year ago

de-gozaru commented 1 year ago

Hi Jean,

Thank you for the excellent library!

I have a question about how to use the Hausdorff distance. I'm using it like this:

hausdorf_loss = SamplesLoss("hausdorff", p=2, blur=0.05)
source, target = torch.rand(1, 100, 3), torch.rand(1, 100, 3)
hausdorf_loss(source, target)

however, I got the following error:

---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
      1 hausdorf_loss = SamplesLoss("hausdorff", p=2, blur=0.05)
      2 source, target = torch.rand(1, 100, 3), torch.rand(1, 100, 3)
----> 3 hausdorf_loss(source, target)

File path/python3.8/site-packages/torch/nn/modules/module.py:1190, in Module._call_impl(self, *input, **kwargs)
   1186 # If we don't have any hooks, we want to skip the rest of the logic in
   1187 # this function, and just call forward.
   1188 if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks
   1189         or _global_forward_hooks or _global_forward_pre_hooks):
-> 1190     return forward_call(*input, **kwargs)
   1191 # Do not call functions when jit is used
   1192 full_backward_hooks, non_full_backward_hooks = [], []

File path/python3.8/site-packages/geomloss/samples_loss.py:265, in SamplesLoss.forward(self, *args)
    262     α, x, β, y = α.unsqueeze(0), x.unsqueeze(0), β.unsqueeze(0), y.unsqueeze(0)
    264 # Run --------------------------------------------------------------------------------
--> 265 values = routines[self.loss][backend](
    266     α,
    267     x,
    268     β,
    269     y,
    270     p=self.p,
    271     blur=self.blur,
    272     reach=self.reach,
    273     diameter=self.diameter,
    274     scaling=self.scaling,
    275     truncate=self.truncate,
    276     cost=self.cost,
    277     kernel=self.kernel,
    278     cluster_scale=self.cluster_scale,
    279     debias=self.debias,
    280     potentials=self.potentials,
    281     labels_x=l_x,
    282     labels_y=l_y,
    283     verbose=self.verbose,
    284 )
    286 # Make sure that the output has the correct shape ------------------------------------
    287 if (
    288     self.potentials
    289 ):  # Return some dual potentials (= test functions) sampled on the input measures

File path/python3.8/site-packages/geomloss/kernel_samples.py:108, in kernel_loss(α, x, β, y, blur, kernel, name, potentials, use_keops, ranges_xx, ranges_yy, ranges_xy, **kwargs)
     92 def kernel_loss(
     93     α,
     94     x,
   (...)
    105     **kwargs
    106 ):
    107     if kernel is None:
--> 108         kernel = kernel_routines[name]
    110     # Center the point clouds just in case, to prevent numeric overflows:
    111     # N.B.: This may break user-provided kernels and comes at a non-negligible
    112     #       cost for small problems, so let's disable this by default.
   (...)
    115 
    116     # (B,N,N) tensor
    117     K_xx = kernel(
    118         double_grad(x), x.detach(), blur=blur, use_keops=use_keops, ranges=ranges_xx
    119     )

KeyError: None

Am I doing something wrong?

Thank you in advance for your help!

Lawreros commented 1 year ago

I had the same issue, and it turned out that I wasn't in the right environment. Note that, while you can pip install geomloss, you need to install KeOps as well.

  1. Install PyTorch.

  2. Install the KeOps library.

  3. Install GeomLoss with: pip install geomloss

If that doesn't work, there also might be a bug with name defaulting to None and thus getting nothing from the list. A way around this is passing in the kernel function you want instead of going with the default argument value:

 from geomloss.kernel_samples import gaussian_kernel

 geomloss.SamplesLoss(loss='hausdorff', p=2, kernel=gaussian_kernel, blur=.05, verbose=True)