YOLOV7改进------添加注意力机制
主要包括添加:
项目代码:https://github.com/z1069614715/objectdetection_script
(博主:魔鬼面具)
注意力机制一般加在backbone或者是PAN层。
yolov7结构图,配合yolov7.yaml的文件来结合看!
一、SE注意力模块
1、在github主页中找到SE.py注意力模块
import numpy as np
import torch
from torch import nn
from torch.nn import init
class SEAttention(nn.Module):
def __init__(self, channel=512,reduction=16):
super().__init__()
self.avg_pool = nn.AdaptiveAvgPool2d(1)
self.fc = nn.Sequential(
nn.Linear(channel, channel // reduction, bias=False),
nn.ReLU(inplace=True),
nn.Linear(channel // reduction, channel, bias=False),
nn.Sigmoid()
)
def init_weights(self):
for m in self.modules():
if isinstance(m, nn.Conv2d):
init.kaiming_normal_(m.weight, mode='fan_out')
if m.bias is not None:
init.constant_(m.bias, 0)
elif isinstance(m, nn.BatchNorm2d):
init.constant_(m.weight, 1)
init.constant_(m.bias, 0)
elif isinstance(m, nn.Linear):
init.normal_(m.weight, std=0.001)
if m.bias is not None:
init.constant_(m.bias, 0)
def forward(self, x):
b, c, _, _ = x.size()
y = self.avg_pool(x).view(b, c)
y = self.fc(y).view(b, c, 1, 1)
return x * y.expand_as(x)
if __name__ == '__main__':
input=torch.randn(50,512,7,7)
se = SEAttention(channel=512,reduction=8)
output=se(input)
print(output.shape)
在/yolov7-main/models/下面建一个SE.py文件,并将代码复制进去。
2、打开同一目录下的conmon.py.
首先from models.SE import SEAttertion
其次新建一个类,命名为Conv_SE,如下所示
class Conv_SE(nn.Module):
# Standard convolution
def __init__(self, c1, c2, k=1, s=1, p=None, g=1, act=True): # ch_in, ch_out, kernel, stride, padding, groups
super(Conv_SE, self).__init__()
self.conv = nn.Conv2d(c1, c2, k, s, autopad(k, p), groups=g, bias=False)
self.bn = nn.BatchNorm2d(c2)
self.act = nn.SiLU() if act is True else (act if isinstance(act, nn.Module) else nn.Identity())
self.att = SEAttention(c2)
def forward(self, x):
return self.att(self.act(self.bn(self.conv(x))))
def fuseforward(self, x):
return self.att(self.act(self.conv(x)))
3 打开同一目录下的yolo.py
在此处最后添加上 Conv_SE
4、打开yolov7.yaml,进行注意力机制的修改。
然后再自己想要修改添加注意力机制的的地方修改就可以了,如下图所示。
SPPCSPC_ATT
还是先在Conmon.py中添加下面的代码,然后在yolo.py中最后一个位置加上 “SPPCSPC_ATT”,然后在yolov7.yaml中添加指定需要修改的SPPCSPC部分即可。(注意要from models.SE import SEAttertion)
class SPPCSPC_ATT(nn.Module):
# CSP https://github.com/WongKinYiu/CrossStagePartialNetworks
def __init__(self, c1, c2, n=1, shortcut=False, g=1, e=0.5, k=(5, 9, 13)):
super(SPPCSPC_ATT, self).__init__()
c_ = int(2 * c2 * e) # hidden channels
self.cv1 = Conv(c1, c_, 1, 1)
self.cv2 = Conv(c1, c_, 1, 1)
self.cv3 = Conv(c_, c_, 3, 1)
self.cv4 = Conv(c_, c_, 1, 1)
self.m = nn.ModuleList([nn.MaxPool2d(kernel_size=x, stride=1, padding=x // 2) for x in k])
self.cv5 = Conv(4 * c_, c_, 1, 1)
self.cv6 = Conv(c_, c_, 3, 1)
self.cv7 = Conv(2 * c_, c2, 1, 1)
self.att = SEAttention(c2)
def forward(self, x):
x1 = self.cv4(self.cv3(self.cv1(x)))
y1 = self.cv6(self.cv5(torch.cat([x1] + [m(x1) for m in self.m], 1)))
y2 = self.cv2(x)
return self.att(self.cv7(torch.cat((y1, y2), dim=1)))
然后就完成了,进行正常训练即可。