YOLOv5结构改进——dynamicRELU和可变形卷积(DCN)

论文复现

基于深度学习的红外场景目标检测_秦鹏
测试可变形卷积对于网络性能的影响。在成像不够清晰的红外图像中,物体的边缘往往十分模糊,可变形的卷积可以自适应地贴合物体形状,比框状的效果应该会更好。

DCNv2可变形卷积源码和原理
DCNv3

这个链接的DCNv2实现有着极大的计算开销,十分消耗显存。基于这个特点,在网络中部署该模块时,不建议放置在backbone中,因为过大的特征图在DCNv2上会产生更大的计算开销。所以我在部署到YOLOv5时,没有放到backbone中,只放在neck里。
而且有个bug是,在kernel_size大于3时特征图的大小会出现错误。YOLOv5backbone中的第一个卷积就是6*6的,所以不适合部署在backbone中。
其他开源的DCNv2代码多是C++开发和基于cuda。
在有一篇论文提到过,DCNv2最好是用于迁移学习,即加载预训练权重,目前训练精度低可能也有这方面的原因。

DynamicRELU原理

DRelu实验经验总结
实验中绝大部分时间都是卡在这里。检查之后发现,yolov5自己设计的模型可以根据输入x.device()自动调整self里的所有属性的device。但是自定义的DynamicReLU_A模块一直都是cpu上的。因此需要将上面的变量根据x改变device。有一点收获是:知道了模型在定义时,会给模型一个cpu上的空向量来运行以获得stride,模型在训练时也是在运行BaseModel._forward_once()函数。

relu_coefs = z.view(-1, 2 * self.K) * lambdas + init_v
# RuntimeError: Expected all tensors to be on the same device, but found at least two devices, cuda:0 and cpu! (when checking argument for argument tensors in method wrapper_cat
#报错原因是,z与输入x的device相同是cuda0,lambdas和init_v是cpu上的,需要在之前将后两个变量放到cuda0上。

在cpu上运行没有问题,gpu上运行会报错

preds, train_out = model(im) if compute_loss else (model(im, augment=augment), None)
# RuntimeError: 
# 报错原因是:模型本身的权重都是float32的张量,但是在val时输入的张量是float16也即half精度的张量。
im = im.float()
# 手动将im设置为float即可解决。但也有了一个问题:im = im.half() if half else im.float(),为什么我的验证集跑到这里会自动出发half的标志位呢?

如何修改YOLOv5的backbone

修改YOLOv5的网络结构

修改backbone为efficientnet

YOLOv5上的实验结果如下(该实验是在autoDL上的服务器上运行):

网络 mAp50 mAp50_95 epoch
YOLOv5 0.6844 0.3351 45
YOLOv5-pt 0.8026 0.4329 60
YOLOv5-efficientnet 0.670 0.320 60
YOLOv5-dynamicRELUA 0.555 0.264 96(100)
YOLOv5-dynamicRELUB 0.587 0.281 134(200)
YOLOv5-DCN 0.589 199(200)

你可能感兴趣的:(目标检测)