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

Is there any particular reason for puting Blurpool before the skip-connection layers? #51

Open
freshn opened this issue Feb 22, 2023 · 3 comments

Comments

@freshn
Copy link

freshn commented Feb 22, 2023

Hi. Thanks for your brilliant work on solving the antialiasing problem. I find in the implementation of Antialiased-ResNet50, the order to apply the antialiased layers in the skip connections is different from the one in the main pathway.
The original skip connection is:
...->conv(stride=2)->...
Now it is:
...blurpool(stride=2)->conv(stride=1)->...
But from my understanding, it should be:
...->conv(stride=1)->blurpool(stride=2)->...
And in this way, it is identical to how you deal with the Bottleneck.conv2 and Bottleneck.conv3.
Is there any reason the calculation order is inverse in the skip connections?

@richzhang
Copy link
Contributor

richzhang commented Feb 26, 2023

Hi, I think you're referring to this section: https://github.com/adobe/antialiased-cnns/blob/master/antialiased_cnns/resnet.py#L147-L148, which makes it look like there's blurpool(stride2)->conv(stride1).

Your understanding is correct. It should be conv first. There is actually a conv before it, which was changed from stride 2 to stride 1: https://github.com/adobe/antialiased-cnns/blob/master/antialiased_cnns/resnet.py#L142. So overall, it is conv(stride1) first.

@freshn
Copy link
Author

freshn commented Feb 26, 2023

Thank you for your reply! I understand it is conv(stride1) first in the Bottleneck. What I am confused is the skip connections:

downsample = [BlurPool(filt_size=filter_size, stride=stride, channels=self.inplanes),] if(stride !=1) else []
downsample += [conv1x1(self.inplanes, planes * block.expansion, 1),
, where BlurPool is before conv(stride1).

@richzhang
Copy link
Contributor

Got it, in this case, because there's no non-linearity, the 1x1 conv and NxN blur are interchangeable. It's cheaper to do the blur --> stride --> conv rather than conv --> blur --> stride

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

2 participants