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

BottleneckCSP architecture #781

Closed
SISTMrL opened this issue Aug 18, 2020 · 13 comments
Closed

BottleneckCSP architecture #781

SISTMrL opened this issue Aug 18, 2020 · 13 comments
Labels
question Further information is requested Stale

Comments

@SISTMrL
Copy link

SISTMrL commented Aug 18, 2020

❔Question

I read the code bottleneckcsp in common.py, and it just convert the c channels into c/2 channels through convolution, the code is shown as follows:
`class BottleneckCSP(nn.Module):
# CSP Bottleneck https://github.com/WongKinYiu/CrossStagePartialNetworks
def init(self, c1, c2, n=1, shortcut=True, g=1, e=0.5): # ch_in, ch_out, number, shortcut, groups, expansion
super(BottleneckCSP, self).init()
c_ = int(c2 * e) # hidden channels
self.cv1 = Conv(c1, c_, 1, 1)
self.cv2 = nn.Conv2d(c1, c_, 1, 1, bias=False)
self.cv3 = nn.Conv2d(c_, c_, 1, 1, bias=False)
self.cv4 = Conv(2 * c_, c2, 1, 1)
self.bn = nn.BatchNorm2d(2 * c_) # applied to cat(cv2, cv3)
self.act = nn.LeakyReLU(0.1, inplace=True)
self.m = nn.Sequential(*[Bottleneck(c_, c_, shortcut, g, e=1.0) for _ in range(n)])

def forward(self, x):
    y1 = self.cv3(self.m(self.cv1(x)))
    y2 = self.cv2(x)
    return self.cv4(self.act(self.bn(torch.cat((y1, y2), dim=1))))`

but I read the paper of CSPNet, in the figure, I see the CSPnet just separate the feature map into two part, I think the code above is different from the CSPnet, I couldn't understand
1597759029(1)
Could you tell me the reason, thanks very much!

Additional context

@SISTMrL SISTMrL added the question Further information is requested label Aug 18, 2020
@glenn-jocher
Copy link
Member

@SISTMrL current implementation is correct.

@glenn-jocher
Copy link
Member

@SISTMrL by the way, the best way to visualize the current models is probably with Netron viewing an pytorch model, or better an ONNX exported model.

@SISTMrL
Copy link
Author

SISTMrL commented Aug 19, 2020

@SISTMrL by the way, the best way to visualize the current models is probably with Netron viewing an pytorch model, or better an ONNX exported model.

ok, I'll have a try, thanks!

@abhiagwl4262
Copy link

@glenn-jocher Thanks for wonderful repo. I have few doubts regarding the CSPNet implementation.

As per the paper thehttps://openaccess.thecvf.com/content_CVPRW_2020/papers/w28/Wang_CSPNet_A_New_Backbone_That_Can_Enhance_Learning_Capability_of_CVPRW_2020_paper.pdf , the input should be split into 2 parts which should be processed through 2 branches independently. But in your implementation, Both branches are taking the same input and without any spliting.

Please correct me if I understood something wrong

@glenn-jocher
Copy link
Member

@abhiagwl4262 yes that is correct. The inputs are not split, they are used in two places here, which I believe aligns with the actual CSPNet implementation.

@abhiagwl4262
Copy link

abhiagwl4262 commented Sep 12, 2020

@glenn-jocher You guys have chosen to keep it this way because of mistake or for better performance based on experiment?

@glenn-jocher
Copy link
Member

@abhiagwl4262 we have not tried the alternative methodology your asked about

@abhiagwl4262
Copy link

@glenn-jocher Ohhk. Thanks

@abhiagwl4262
Copy link

@glenn-jocher Hey, Is the input split suggested in CSPNet Paper is same as group convolution(Parallel Convolution) Where we are using groups=2? And What's your intuition behind the pros and cons of that ?

@glenn-jocher
Copy link
Member

@abhiagwl4262 similar but not quite the same I think. If I understand correctly the alternative interpretation of splitting the input channels may create small speed/size improvements at the cost of accuracy improvements, as is nearly always the case with reducing operations.

If in doubt you can update the CSP bottlenecks and train YOLOv5s to compare to the current implementation. The module is here:

yolov5/models/common.py

Lines 49 to 66 in 702c4fa

class BottleneckCSP(nn.Module):
# CSP Bottleneck https://github.com/WongKinYiu/CrossStagePartialNetworks
def __init__(self, c1, c2, n=1, shortcut=True, g=1, e=0.5): # ch_in, ch_out, number, shortcut, groups, expansion
super(BottleneckCSP, self).__init__()
c_ = int(c2 * e) # hidden channels
self.cv1 = Conv(c1, c_, 1, 1)
self.cv2 = nn.Conv2d(c1, c_, 1, 1, bias=False)
self.cv3 = nn.Conv2d(c_, c_, 1, 1, bias=False)
self.cv4 = Conv(2 * c_, c2, 1, 1)
self.bn = nn.BatchNorm2d(2 * c_) # applied to cat(cv2, cv3)
self.act = nn.LeakyReLU(0.1, inplace=True)
self.m = nn.Sequential(*[Bottleneck(c_, c_, shortcut, g, e=1.0) for _ in range(n)])
def forward(self, x):
y1 = self.cv3(self.m(self.cv1(x)))
y2 = self.cv2(x)
return self.cv4(self.act(self.bn(torch.cat((y1, y2), dim=1))))

@github-actions
Copy link
Contributor

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@marziyemahmoudifar
Copy link

What does BottleneckCSP do on the features extracted in the previous layers?

@glenn-jocher
Copy link
Member

@marziyemahmoudifar BottleneckCSP operates on the extracted features from previous layers by applying a series of convolutions and transformations to the input, followed by a bottleneck structure that further refines the features. This process enhances the representational capacity of the network and facilitates the learning of more complex patterns in the feature maps. If you'd like to explore this further, you can refer to the documentation at https://docs.ultralytics.com/yolov5/.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested Stale
Projects
None yet
Development

No branches or pull requests

4 participants