I am currently trying to reimplement “Deep SVDD” for my own project.
During training, I use my network to compute the outputs as usual. To compute the loss, I then use the hypersphere center c and radius R as follows:
outputs = model(data)
dist = torch.sum((outputs - self.c) ** 2, dim=1)
scores = dist - self.R ** 2
loss = self.R ** 2 + (1 / self.nu) * torch.mean(torch.max(torch.zeros_like(scores), scores))
loss.backward()
optimizer.step()
After backpropagating the loss and updating the parameters, I now want to update the radius R. In the original implementation this is done by
self.R.data = torch.tensor(get_radius(dist, self.nu), device=self.device)
where the get_radius function is defined as follows:
def get_radius(dist: torch.Tensor, nu: float):
return np.quantile(np.sqrt(dist.clone().data.cpu().numpy()), 1 - nu)
After updating the radius, the processing of the current training batch is done.
Now I am wondering whether this is the proper way to do this. I know that the use of .data can be problematic and can cause issues during backpropagation. I have been reading around about it but I can’t quite wrap my head around it and how to fix it. Would it cause issues in the original implementation and how should I implement it instead to avoid any issues and why?
More generally, my question is how to properly update the radius in my implementation without causing issues with backpropagation or more generally how to update tensors like the radius?