参考教程来自b站:BV1uN411K7x3
参考代码:GitHub - ZhugeKongan/Attention-mechanism-implementation: Self-attention、Non-local、SE、SK、CBAM、DANet
Step1:加入新增网络结构
修改models/common.py,在common.py内添加SE类,直接将下面的代码粘贴进去
class SE(nn.Module):
def __init__(self, in_chnls, ratio):
super(SE, self).__init__()
self.squeeze = nn.AdaptiveAvgPool2d((1, 1))
self.compress = nn.Conv2d(in_chnls, in_chnls // ratio, 1, 1, 0)
self.excitation = nn.Conv2d(in_chnls // ratio, in_chnls, 1, 1, 0)
def forward(self, x):
out = self.squeeze(x)
out = self.compress(out)
out = F.relu(out)
out = self.excitation(out)
return x*F.sigmoid(out)
这时我们会发现有个F会报错,所以在common.py头部进行导包
import torch.nn.functional as F
Step2:修改现有模型结构配置文件
修改models/yolov5s*.yaml
首先复制一份yolov5s.yaml文件,命名为yolov5s*.yaml,此处我更名为yolov5s_se.yaml
然后修改backbone,此处将SE添加在第10层,所以原来的第10层及以后每一层都会往后顺延一层,即head中的14 10 17 20 23层变为15 11 18 21 24层。
Step3:设定网络结构的传参细节
修改models/yolo.py
找到parse_model()函数,在函数中间添加判断,如图:
elif m is SE:
c1 = ch[f]
c2 = args[0]
if c2 != no: # if not output
c2 = make_divisible(c2 * gw, 8)
args = [c1, args[1]]
Step4:训练时指定模型结构配置文件
修改train.py ,改成刚才修改好的yolov5s_se.yaml
现在,就可以开始运行了。
一些问题及解决方法:
报错1:UnicodeDecodeError: 'gbk' codec can't decode byte 0xac in position 1159: illegal multibyte sequence
UnicodeDecodeError: 'gbk' codec can't decode byte 0xac in position 1159: illegal multibyte sequence
解决方法:根据提示找到报错的第一行代码,在该文件中把所有的open都改成utf-8解码。
例如:我把train.py中所有的open后面都加上了utf-8解码,一共6处。
报错2:TypeError: __init__() takes 3 positional arguments but 5 were given
TypeError: __init__() takes 3 positional arguments but 5 were given
解决方法:在yolo.py文件中,找到parse_model()方法,把手动写进的两个SE删除就可以了。