现在yolov5的neck用的是PANet,在EfficientDet论文中提出了BiFPN结构,还有更加不错的性能。所以就尝试将yolov5中的PANet层改为BiFPN。
需要修改的地方
- 主要是修改yaml配置文件
我修改的是yolov5x.yaml,将concat层连接不同的layer。有三层BiFPN,最后输出为了和yolov5对应,我没有用在论文里写的p3-p7五个节点,我只用了三个。(这里应该要用relu使w>0,我训练报错就没有用relu) - 修改common.py
class Concat(nn.Module):
# Concatenate a list of tensors along dimension
def __init__(self, c1, c2):
super(Concat, self).__init__()
# self.relu = nn.ReLU()
self.w1 = nn.Parameter(torch.ones(2, dtype=torch.float32), requires_grad=True)
self.w2 = 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.swish = MemoryEfficientSwish()
def forward(self, x):
outs = self._forward(x)
return outs
def _forward(self, x): # intermediate result
if len(x) == 2:
# w = self.relu(self.w1)
w = self.w1
weight = w / (torch.sum(w, dim=0) + self.epsilon)
x = self.conv(self.swish(weight[0] * x[0] + weight[1] * x[1]))
elif len(x) == 3: # final result
# w = self.relu(self.w2)
w = self.w2
weight = w / (torch.sum(w, dim=0) + self.epsilon)
x = self.conv(self.swish(weight[0] * x[0] + weight[1] * x[1] + weight[2] * x[2]))
- 修改yolo.py
channel现在不是直接concat了,而是进行pairwise add操作,所以out-channel不再是sum。
# elif m is Concat:
# c2 = sum([ch[x] for x in f])
elif m is Concat:
c2 = max([ch[x] for x in f])
配置文件的修改在https://github.com/XingZeng307/YOLOv5_with_BiFPN/blob/main/models/yolov5x.yaml
现在算是一个初步的结合吧。还在训练当中,有结果了再贴图。
参考资料
https://github.com/ultralytics/yolov5
https://github.com/zylo117/Yet-Another-EfficientDet-Pytorch/tree/15403b5371a64defb2a7c74e162c6e880a7f462c
Mingxing Tan, Ruoming Pang, and Quoc V Le. EfficientDet: Scalable and efficient object detection. In Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition (CVPR), 2020.
版权声明:本文为qq_35470686原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。