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

Local Response Normalization #4667

Merged
merged 4 commits into from
Jan 16, 2018
Merged

Local Response Normalization #4667

merged 4 commits into from
Jan 16, 2018

Conversation

Kaixhin
Copy link
Contributor

@Kaixhin Kaixhin commented Jan 15, 2018

Functional implementation + module for LRN based on @jiecaoyu's implementation. Let me know if there should be any naming changes/if we want an across/within channel flag like Caffe/what to do with CrossMapLRN2d etc.

Originally AlexNet doesn't seem to do an average (just sums), whilst Caffe does do an average... I've written the docs as a sum as in the original, so will either need to change the docs or implementation depending on which one we want (or even make it another option).

@@ -1153,8 +1153,16 @@ def batch_norm(input, running_mean, running_var, weight=None, bias=None,
)


def local_response_norm(input, size, alpha=1e-4, beta=0.75, k=1):
div = avg_pool3d(input.pow(2).unsqueeze(1), (size, 1, 1),

This comment was marked as off-topic.

def local_response_norm(input, size, alpha=1e-4, beta=0.75, k=1):
div = avg_pool3d(input.pow(2).unsqueeze(1), (size, 1, 1),
stride=1, padding=(size // 2, 0, 0)).squeeze(1)
div.mul_(alpha).add_(k).pow_(beta)

This comment was marked as off-topic.

This comment was marked as off-topic.

from .. import functional as F


class LocalResponseNorm2d(Module):

This comment was marked as off-topic.

This comment was marked as off-topic.

@@ -1153,8 +1153,16 @@ def batch_norm(input, running_mean, running_var, weight=None, bias=None,
)


def local_response_norm(input, size, alpha=1e-4, beta=0.75, k=1):

This comment was marked as off-topic.

Copy link
Contributor

@apaszke apaszke left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

idk what the formula for LRN is, so I haven't checked that, but the code looks good in general

div = div.view(sizes[0], 1, sizes[1], sizes[2], sizes[3] * sizes[4])
div = pad(div, (0, 0, 0, 0, size // 2, (size - 1) // 2))
div = avg_pool3d(div, (size, 1, 1), stride=1).squeeze(1)
div = div.view(sizes[0], sizes[1], sizes[2], sizes[3], sizes[4])

This comment was marked as off-topic.

This comment was marked as off-topic.

@Kaixhin
Copy link
Contributor Author

Kaixhin commented Jan 15, 2018

Pinging @jiecaoyu @fmassa for an additional review (to check the formula/address any points in my initial comment) before merging.

@vadimkantorov
Copy link
Contributor

+1 for clearing up the difference with CrossMapLRN2d (is it across-channels / within-channel thing?)

Specify 'across-channels'
@Kaixhin
Copy link
Contributor Author

Kaixhin commented Jan 15, 2018

@vadimkantorov this is across-channels, same as CrossMapLRN2d (which should be deprecated). The within-channel version seems to be far less common, so I'd go for merging this across-channel version in (which actually now supports 1D, 2D, 3D, 4D etc.), and then adding that as another option with an extra optional flag if someone wants it.

@apaszke The canonical reference is AlexNet, section 3.3, which sums the normalisation bit across channels. However, Torch documents SpatialCrossMapLRN as being a mean over channels, as does Caffe, so I'm changing the implementation and docs back to using the mean to be consistent with most implementations.

@soumith soumith merged commit 2260649 into pytorch:master Jan 16, 2018
@Kaixhin Kaixhin deleted the lrn branch January 16, 2018 03:34
@hdmetor hdmetor mentioned this pull request Jan 16, 2018
@vadimkantorov
Copy link
Contributor

vadimkantorov commented Jan 16, 2018

@Kaixhin Python disallows starting a variable name with a digit (minor docs thing):

>>> 2d_signal = autograd.Variable(torch.randn(32, 5, 24, 24))
>>> 4d_signal = autograd.Variable(torch.randn(16, 5, 7, 7, 7, 7))
>>> 2d_output = lrn(2d_signal)
>>> 4d_output = lrn(4d_signal)

@Kaixhin
Copy link
Contributor Author

Kaixhin commented Jan 16, 2018

@vadimkantorov thanks for noting - have adjusted in #4681 since I forgot to add LRN to the autogenerated docs.

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

Successfully merging this pull request may close these issues.

5 participants