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

How to train Topology Loss in batch images #19

Open
whikwon opened this issue Feb 26, 2020 · 8 comments
Open

How to train Topology Loss in batch images #19

whikwon opened this issue Feb 26, 2020 · 8 comments

Comments

@whikwon
Copy link

whikwon commented Feb 26, 2020

I'm looking into your example code1 and code2.

From the code2, I can understand how to train network with one image. But as code1 differs from code2 a lot, I can't understand how to train in batch.

What kinds of classes or functions do I have to use to train in batch?

@whikwon
Copy link
Author

whikwon commented Feb 26, 2020

How can I use LevelSetLayer2D in batch training?

@bruel-gabrielsson
Copy link
Owner

Hi! I think the training in "code1" is not the best way to go anymore. However, you can look at "top_batch_cost" in utils to get inspiration to apply a specific diagram cost over a batch. Does this help?

@whikwon
Copy link
Author

whikwon commented Feb 27, 2020

@bruel-gabrielsson Thank you for reply.
Should I have to set $p, q, i$ (from your paper) in the cost_function?
From the code below, cost function deals with only 0-dimension topological feature, right?

def cost_function(dgms):
''' Undefined are -1.0 for our rips and infinite are at saturation value '''
dgm0 = dgms[0].type(dtype).clone()
min_value = -1.0 # not always true, but can be assumed in most contexts
dgm0[dgm0 == -np.inf] = min_value
NAN = torch.tensor(float('nan')).type(dtype)
lifetimes0 = torch.abs(dgm0[:,1]-dgm0[:,0])
lifetimes0[lifetimes0 != lifetimes0] = 0
sorted_d_dgm0, indsD0 = torch.sort( dgm0[:,1][dgm0[:,1] > -np.inf], 0)
sorted0, inds0 = torch.sort(lifetimes0, 0, descending=True)
cost = torch.add(
torch.Tensor([0.0]),
torch.mul(torch.sum(torch.abs(sorted0[1:1+10000])), 1.0),
#torch.mul(torch.sum(torch.abs(sorted1[0:0+10000])), 1.0),
)
return cost

Besides the code, I want to use topology loss in segmentation task but there is a slow speed issue of topology loss. Do you have any idea enhancing it?

@whikwon
Copy link
Author

whikwon commented Feb 27, 2020

Your codes 1 and 2 look so different. Could you let me know the difference of them?
If possible, please indicate where I can refer from your paper or blog.

@daresut
Copy link

daresut commented Jul 22, 2021

Hello, I am also interested in getting this to work for batches. @bruel-gabrielsson I will look at the mentioned script in utils and see how far I get.

Thanks for your contribution with this loss functional :).

@daresut
Copy link

daresut commented Jul 23, 2021

I followed the example code here and altered the forward call in class Toploss in code2 to handle batches. I'll have to look at some visualizations to make sure the loss is functioning as expected, but pytorch is not complaining ;).

image

@bruel-gabrielsson
Copy link
Owner

Nice work! Probably could implement some parallelism if you need to speed things up!

@daresut
Copy link

daresut commented Jul 29, 2021

Thanks @bruel-gabrielsson :). Do you mean parallelism on the GPU side or CPU side? One aspect I'm unsure about is: does this loss function push a tensor to the CPU to calculate the PH gradient, then back to the GPU? Or does it all stay on the same device?

Parallelism is def required since my implementation is slow, so thanks for that tip. I'll implement that for sure 👍

Edit: I missed the section in the README where it is stated:

"You can use topologylayer with tensors that are on GPUs. However, because the persistent homology calculation takes place on CPU, there will be some overhead from memory movement."

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants