网络编程
位置:首页>> 网络编程>> Python编程>> Yolov5更换BiFPN的详细步骤总结

Yolov5更换BiFPN的详细步骤总结

作者:迪菲赫尔曼  发布时间:2023-01-17 02:51:22 

标签:yolov5,更换,bifpn

Yolov5如何更换BiFPN?

第一步:修改common.py

将如下代码添加到common.py文件中

# BiFPN
# 两个特征图add操作
class BiFPN_Add2(nn.Module):
   def __init__(self, c1, c2):
       super(BiFPN_Add2, self).__init__()
       # 设置可学习参数 nn.Parameter的作用是:将一个不可训练的类型Tensor转换成可以训练的类型parameter
       # 并且会向宿主模型注册该参数 成为其一部分 即model.parameters()会包含这个parameter
       # 从而在参数优化的时候可以自动一起优化
       self.w = nn.Parameter(torch.ones(2, dtype=torch.float32), requires_grad=True)
       self.epsilon = 0.0001
       self.conv = nn.Conv2d(c1, c2, kernel_size=1, stride=1, padding=0)
       self.silu = nn.SiLU()

def forward(self, x):
       w = self.w
       weight = w / (torch.sum(w, dim=0) + self.epsilon)
       return self.conv(self.silu(weight[0] * x[0] + weight[1] * x[1]))

# 三个特征图add操作
class BiFPN_Add3(nn.Module):
   def __init__(self, c1, c2):
       super(BiFPN_Add3, self).__init__()
       self.w = nn.Parameter(torch.ones(3, dtype=torch.float32), requires_grad=True)
       self.epsilon = 0.0001
       self.conv = nn.Conv2d(c1, c2, kernel_size=1, stride=1, padding=0)
       self.silu = nn.SiLU()

def forward(self, x):
       w = self.w
       weight = w / (torch.sum(w, dim=0) + self.epsilon)  
       # Fast normalized fusion
       return self.conv(self.silu(weight[0] * x[0] + weight[1] * x[1] + weight[2] * x[2]))

第二步:修改yolo.py

parse_model函数中找到elif m is Concat:语句,在其后面加上BiFPN_Add相关语句

Yolov5更换BiFPN的详细步骤总结

elif m is Concat:
   c2 = sum(ch[x] for x in f)
# 添加bifpn_add结构
elif m in [BiFPN_Add2, BiFPN_Add3]:
   c2 = max([ch[x] for x in f])

第三步:修改train.py

将BiFPN_Add2和BiFPN_Add3函数中定义的w参数,加入g1

Yolov5更换BiFPN的详细步骤总结

g = [], [], []  # optimizer parameter groups
   bn = tuple(v for k, v in nn.__dict__.items() if 'Norm' in k)  # normalization layers, i.e. BatchNorm2d()
   for v in model.modules():
       # hasattr: 测试指定的对象是否具有给定的属性,返回一个布尔值
       if hasattr(v, 'bias') and isinstance(v.bias, nn.Parameter):  # bias
           g[2].append(v.bias)
       if isinstance(v, bn):  # weight (no decay)
           g[1].append(v.weight)
       elif hasattr(v, 'weight') and isinstance(v.weight, nn.Parameter):  # weight (with decay)
           g[0].append(v.weight)
       # BiFPN_Concat
       elif isinstance(v, BiFPN_Add2) and hasattr(v, 'w') and isinstance(v.w, nn.Parameter):
           g[1].append(v.w)
       elif isinstance(v, BiFPN_Add3) and hasattr(v, 'w') and isinstance(v.w, nn.Parameter):
           g[1].append(v.w)

导入BiFPN_Add3, BiFPN_Add2

from models.common import BiFPN_Add3, BiFPN_Add2

第四步:修改yolov5.yaml

Concat全部换成BiFPN_Add

注意:BiFPN_Add本质是add操作,因此输入层通道数、feature map要完全对应

2022.8.25 官方也提供了BiFPN,可以尝试用官方的
关于5m加BiFPN的文件我已经更新到了我的Git

来源:https://blog.csdn.net/weixin_43694096/article/details/125148552

0
投稿

猜你喜欢

手机版 网络编程 asp之家 www.aspxhome.com