湖南网站优化服务,南山住房和建设局网站,优秀的网站设计分析,站点创建成功前言#xff1a;Hello大家好#xff0c;我是小哥谈。为提高算法模型在不同环境下的目标识别准确率#xff0c;提出一种基于改进 YOLOv5 深度学习的识别方法#xff08;SE-NMS-YOLOv5#xff09;#xff0c;该方法融合SE#xff08;Squeeze-and-Excitation#xff09;注… 前言Hello大家好我是小哥谈。为提高算法模型在不同环境下的目标识别准确率提出一种基于改进 YOLOv5 深度学习的识别方法SE-NMS-YOLOv5该方法融合SESqueeze-and-Excitation注意力机制模块和改进非极大值抑制对数据集进行训练和测试。研究表明SE-NMS-YOLOv5 目标识别方法有效地解决了不同场景下的检测准确率低的问题提升了检测和识别的整体效果。 目录
1.基础概念
2.添加位置
3.添加步骤
4.改进方法
步骤1common.py文件修改
步骤2yolo.py文件修改
步骤3创建自定义yaml文件
步骤4修改自定义yaml文件
步骤5验证是否加入成功
步骤6更改NMS
步骤7修改默认参数 1.基础概念
SE注意力机制
SENet是由Momenta和牛津大学的胡杰等人提出的一种新的网络结构目标是通过显式的建模卷积特征通道之间的相互依赖关系来提高网络的表示能力。在2017年最后一届ImageNet 比赛classification任务上获得第一名。SENet网络的创新点在于关注channel之间的关系希望模型可以自动学习到不同channel特征的重要程度。为此SENet提出了Squeeze-and-Excitation (SE)模块。
SE模块首先对卷积得到的特征图进行Squeeze操作得到channel级的全局特征然后对全局特征进行Excitation操作学习各个channel间的关系也得到不同channel的权重最后乘以原来的特征图得到最终特征。本质上SE模块是在channel维度上做attention或者gating操作这种注意力机制让模型可以更加关注信息量最大的channel特征而抑制那些不重要的channel特征。另外一点是SE模块是通用的这意味着其可以嵌入到现有的网络架构中。
SENet结构图如下图所示
步骤1squeeze操作将各通道的全局空间特征作为该通道的表示形成一个通道描述符
步骤2excitation操作学习对各通道的依赖程度并根据依赖程度的不同对特征图进行调整调整后的特征图就是SE block的输出。 EIoU-NMS
EIoU-NMS是一种新的非极大值抑制算法它是YOLOv5中提出的一种改进算法。EIoU-NMS是在DIoU-NMS的基础上进行改进的。EIoU-NMS的主要思想是将检测框之间的距离嵌入到嵌入空间中然后计算嵌入空间中的距离来代替传统的IoU计算。这种方法可以更好地处理检测框之间的重叠情况从而提高目标检测的准确性。 2.添加位置
本文的改进是基于YOLOv5-6.0版本关于其网络结构具体如下图所示 为了使网络能够更好地拟合通道之间的相关性增加更重要的通道特征的权重引入了SE模块注意力机制是一种神经网络资源分配方案用于将计算资源分配给更重要的任务
本文的改进是将SE注意力机制添加在主干网络中具体添加位置如下图所示 关于NMS的改进直接体现在代码中所以本节课改进后的网络结构图具体如下图所示 3.添加步骤
针对本文的改进具体步骤如下所示
步骤1common.py文件修改
步骤2yolo.py文件修改
步骤3创建自定义yaml文件
步骤4修改自定义yaml文件
步骤5验证是否加入成功
步骤6更改NMS
步骤7修改默认参数 4.改进方法
步骤1common.py文件修改
在common.py中添加SE注意力机制模块所要添加模块的代码如下所示将其复制粘贴到common.py文件末尾的位置。
SE注意力机制模块代码
# SE
class SE(nn.Module):def __init__(self, c1, c2, ratio16):super(SE, self).__init__()#c*1*1self.avgpool nn.AdaptiveAvgPool2d(1)self.l1 nn.Linear(c1, c1 // ratio, biasFalse)self.relu nn.ReLU(inplaceTrue)self.l2 nn.Linear(c1 // ratio, c1, biasFalse)self.sig nn.Sigmoid()def forward(self, x):b, c, _, _ x.size()y self.avgpool(x).view(b, c)y self.l1(y)y self.relu(y)y self.l2(y)y self.sig(y)y y.view(b, c, 1, 1)return x * y.expand_as(x)
步骤2yolo.py文件修改
首先在yolo.py文件中找到parse_model函数这一行加入SE。具体如下图所示 步骤3创建自定义yaml文件
在models文件夹中复制yolov5s.yaml粘贴并重命名为yolov5s_SE_ENMS.yaml。具体如下图所示 步骤4修改自定义yaml文件
本步骤是修改yolov5s_SE_ENMS.yaml根据改进后的网络结构图进行修改。
由下面这张图可知当添加SE注意力机制之后后面的层数会发生相应的变化需要修改相关参数。 备注层数从0开始计算比如第0层、第1层、第2层...... 综上所述修改后的完整yaml文件如下所示
# YOLOv5 by Ultralytics, GPL-3.0 license# Parameters
nc: 80 # number of classes
depth_multiple: 0.33 # model depth multiple
width_multiple: 0.50 # layer channel multiple
anchors:- [10,13, 16,30, 33,23] # P3/8- [30,61, 62,45, 59,119] # P4/16- [116,90, 156,198, 373,326] # P5/32# YOLOv5 v6.0 backbone
backbone:# [from, number, module, args][[-1, 1, Conv, [64, 6, 2, 2]], # 0-P1/2[-1, 1, Conv, [128, 3, 2]], # 1-P2/4[-1, 3, C3, [128]],[-1, 1, Conv, [256, 3, 2]], # 3-P3/8[-1, 6, C3, [256]],[-1, 1, Conv, [512, 3, 2]], # 5-P4/16[-1, 9, C3, [512]],[-1, 1, Conv, [1024, 3, 2]], # 7-P5/32[-1, 3, C3, [1024]],[-1, 1, SE, [1024]],[-1, 1, SPPF, [1024, 5]], # 9]# YOLOv5 v6.0 head
head:[[-1, 1, Conv, [512, 1, 1]],[-1, 1, nn.Upsample, [None, 2, nearest]],[[-1, 6], 1, Concat, [1]], # cat backbone P4[-1, 3, C3, [512, False]], # 13[-1, 1, Conv, [256, 1, 1]],[-1, 1, nn.Upsample, [None, 2, nearest]],[[-1, 4], 1, Concat, [1]], # cat backbone P3[-1, 3, C3, [256, False]], # 17 (P3/8-small)[-1, 1, Conv, [256, 3, 2]],[[-1, 15], 1, Concat, [1]], # cat head P4[-1, 3, C3, [512, False]], # 20 (P4/16-medium)[-1, 1, Conv, [512, 3, 2]],[[-1, 11], 1, Concat, [1]], # cat head P5[-1, 3, C3, [1024, False]], # 23 (P5/32-large)[[18, 21, 24], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5)]步骤5验证是否加入成功
在yolo.py文件里将配置改为我们刚才自定义的yolov5s_SE_ENMS.yaml。
修改1位置位于yolo.py文件165行左右具体如图所示 修改2位置位于yolo.py文件363行左右具体如下图所示 配置完毕之后点击“运行”结果如下图所示 由运行结果可知与我们前面更改后的网络结构图相一致证明添加成功了✅
步骤6更改NMS
本文需要更改NMS为EIoU-NMS。
将下面非极大值抑制NMS核心代码复制粘贴到 utils / general.py 的末尾位置。当复制粘贴后会有报错提示具体如下图所示
# NMS实现代码
def NMS(boxes, scores, iou_thres, GIoUFalse, DIoUTrue, CIoUFalse, EIoUFalse, SIoUFalse):B torch.argsort(scores, dim-1, descendingTrue)keep []while B.numel() 0:index B[0]keep.append(index)if B.numel() 1: breakiou bbox_iou(boxes[index, :], boxes[B[1:], :], GIoUGIoU, DIoUDIoU, CIoUCIoU, EIoUEIoU, SIoUSIoU)inds torch.nonzero(iou iou_thres).reshape(-1)B B[inds 1]return torch.tensor(keep)def soft_nms(bboxes, scores, iou_thresh0.5, sigma0.5, score_threshold0.25):order scores.argsort(descendingTrue).to(bboxes.device)keep []while order.numel() 1:if order.numel() 1:keep.append(order[0])breakelse:i order[0]keep.append(i)iou bbox_iou(bboxes[i], bboxes[order[1:]]).squeeze()idx (iou iou_thresh).nonzero().squeeze()if idx.numel() 0:iou iou[idx]new_scores torch.exp(-torch.pow(iou, 2) / sigma)scores[order[idx 1]] * new_scoresnew_order (scores[order[1:]] score_threshold).nonzero().squeeze()if new_order.numel() 0:breakelse:max_score_index torch.argmax(scores[order[new_order 1]])if max_score_index ! 0:new_order[[0, max_score_index],] new_order[[max_score_index, 0],]order order[new_order 1]return torch.LongTensor(keep) 然后解决报错提示需要导入下列代码
from utils.metrics import box_iou, fitness, bbox_iou
最后在utils / general.py中找到non_max_suppression函数大约885行左右将non_max_suppression函数中的代码 替换为 i NMS(boxes, scores, iou_thres, class_nmsEIoU)
步骤7修改默认参数
在train.py文件中找到parse_opt函数然后将第二行 --cfg 的default改为 models/yolov5s_SE_ENMS.yaml然后就可以开始进行训练了。 结束语关于更多YOLOv5学习知识可参考专栏《YOLOv5从入门到实战》