-
-
Notifications
You must be signed in to change notification settings - Fork 66
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
Adding UNet Model #210
Adding UNet Model #210
Conversation
The PR is ready for code review. I'm still new to flux so apologies for silly mistakes like not following the docstring style or specific design & code principles in Julia ecosystems. |
Metalhead has a JuliaFormatter config, so if your editor supports that I would recommend running it to help with code style adherence. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I doubt there is supposed to be Batchnorm and ReLu layer before the concat + conv layer
@ToucheSir I ran JuliaFormatter.jl using @pri1311 yup ! corrected that. |
@ToucheSir @darsnack Finally made it. It was both challenging & confusing simultaneously as I was continuously getting dimension mismatch error. I knew it very well that it's because of Parallel, and the tensors were propagating through the maxpool which it wasn't supposed to. I tried debugger as well, but there seemed some problem with it. Following helped :
I was successfully able to resolve the error by moving
to before the decoder block. I realized that I have been chaining the layers with decoder, (whilst decoder layers are Chain of concat and decoder conv layers). This was causing error as chaining at this stage would make all tensors flow through concat again, thus dimensionmismatch. Moving it before avoided this case. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great job! I still need to review the architecture details, but here are some initial minor changes.
Gtg for next round of review @darsnack @ToucheSir @pri1311 ! |
This reverts commit ca73586.
Following is the output I get from loading the model:
I believe layers are missing. I am not completely well versed with Flux, but in my knowledge it should display all the layers, even the custom |
src/convnets/unet.jl
Outdated
return Chain(conv1 = Conv(kernel, in_chs => out_chs; pad = (1, 1)), | ||
norm1 = BatchNorm(out_chs, relu), | ||
conv2 = Conv(kernel, out_chs => out_chs; pad = (1, 1)), | ||
norm2 = BatchNorm(out_chs, relu)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any specific reason for using named layers? I don't see it being used anywhere. I haven't seen Metalhead use such a code convention, so a seems a little inconsistent with the code base.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree with this, it looks weird – I think the only place we might need named layers is if we specifically need to index into a Chain
later for use and the name of the layer isn't apparent. Here I don't see that happening.
end | ||
@functor UNet | ||
|
||
function UNet(imsize::Dims{2} = (256, 256), inchannels::Integer = 3, outplanes::Integer = 3, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
function UNet(imsize::Dims{2} = (256, 256), inchannels::Integer = 3, outplanes::Integer = 3, | |
function UNet(imsize::Dims = (256, 256), inchannels::Integer = 3, outplanes::Integer = 3, |
Is there anything in the UNet implementation that would prevent us from generalizing it to 1, 3 or more dimensions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Due to my own ignorance, which dimensions are spatial in the 1 and N>2 cases? Meaning which ones should be downscaled?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as with 2D. Spatial dimensions x channels/features x batch size, so all but the last two assuming the usual memory layout.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@shivance I think the point is that you don't need any changes other than dropping the type restriction to generalize to more dimensions.
But we'd want to have that in the test, so we can save it for another PR if you'd like.
It's funny how many rounds of reviews, architecture changes, this PR has had. Over a month since it's being reviewed 😆 |
Thanks for your patience, I think we're very close! What you're experiencing is a triple learning curve of sorts. Julia is a new language for most contributors and so it takes longer to learn idiomatic code patterns than e.g. already knowing idiomatic Python. Flux is a new library for most contributors and thus folks are less familiar with what's available to use + limitations than they would be with PyTorch/TF. Metalhead is even more domain-specific and more opinionated because it sits at a higher level in the stack. I think a good analogy would be opening a PR contributing a new model to timm after just a month or two of Python experience ;) Some things we can do on our side to flatten the learning curve:
|
Thanks @ToucheSir ! Are we still going with n dimensional unet? |
@ToucheSir Come to think of it, this could be a potential GSoD project! |
Unfortunately, I think GSoCs are not allowed to be solely for documentation (I'll have to double check this). But you can propose it for GSoD! |
@ToucheSir @darsnack I'm willing to open a follow up PR to add N spatial dimensional support. Open for review in current state... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like it is ready to merge modulo one small docstring issue.
PRs can take time (sometimes extenuated by our ability to review frequently). In our case, this is even more true since FluxML is very community-driven. This makes our development extremely distributed, and it is important that PRs are "release ready" before merging. Otherwise, simple changes can get bottlenecked from release due to larger changes that require refactoring/polishing.
Your patience and hard work is very much appreciated. The long review time is not a reflection of your work, just a consequence of the fact that we're all contributing on a volunteer basis. Please don't feel discouraged! Some of the most prolific Julia contributors have high impact PRs that take months to get right. So you're in good company!
end | ||
@functor UNet | ||
|
||
function UNet(imsize::Dims{2} = (256, 256), inchannels::Integer = 3, outplanes::Integer = 3, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@shivance I think the point is that you don't need any changes other than dropping the type restriction to generalize to more dimensions.
But we'd want to have that in the test, so we can save it for another PR if you'd like.
Co-authored-by: Kyle Daruwalla <[email protected]>
@darsnack So I'll leave the signature of imsize as
for now? Or make it
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's leave it as is for now. Good job!
Thanks @darsnack ! |
Thank you @ToucheSir @darsnack ! |
This PR adds the UNet implementation to Metalhead.jl in favor of #112
I've referred official torchhub implementation here and @DhairyaLGandhi 's UNet.jl package.
PR Checklist