YoloX引入注意力机制,CIoU、DIoU,DW卷积

本文以Bubbliiing的YoloX代码进行注意力机制的增加,原博文参考以下。

https://blog.youkuaiyun.com/weixin_44791964/article/details/120476949?spm=1001.2014.3001.5502

在此感谢b导的视频,以及对我学习过程中的帮助。
在这里插入图片描述

在darknet中引入注意力机制

在darknet.py文件中加入以下代码。

'''注意力模块'''
class ChannelAttention(nn.Module):
    def __init__(self, in_planes, ratio=16):
        super(ChannelAttention, self).__init__()
        self.avg_pool = nn.AdaptiveAvgPool2d(1)
        self.max_pool = nn.AdaptiveMaxPool2d(1)
        self.f1 = nn.Conv2d(in_planes, in_planes // ratio, 1, bias=False)
        self.relu = nn.ReLU()
        self.f2 = nn.Conv2d(in_planes // ratio, in_planes, 1, bias=False)
        self.sigmoid = nn.Sigmoid()
    def forward(self, x):
        avg_out = self.f2(self.relu(self.f1(self.avg_pool(x))))
        max_out = self.f2(self.relu(self.f1(self.max_pool(x))))
        out = self.sigmoid(avg_out + max_out)
        return out
class SpatialAttention(nn.Module):
    def __init__(self, kernel_size=7):
        super(SpatialAttention, self).__init__()
        assert kernel_size in (3, 7), 'kernel size must be 3 or 7'
        padding = 3 if kernel_size == 7 else 1
        self.conv = nn.Conv2d(2, 1, kernel_size, padding=padding, bias=False)
        self.sigmoid = nn.Sigmoid()
    def forward(self, x):
        avg_out = torch.mean(x, dim=1, keepdim=True)
        max_out, _ = torch.max(x, dim=1, keepdim=True)
        x = torch.cat([avg_out, max_out], dim=1)
        x = self.conv(x)
        return self.sigmoid(x)
class CBAM(nn.Module):
    # CSP Bottleneck with 3 convolutions
    def __init__(self, c1, ratio=16, kernel_size=7):  # ch_in, ch_out, number, shortcut, groups, expansion
        super(CBAM, self).__init__()
        self.channel_attention = ChannelAttention(c1, ratio)
        self.spatial_attention = SpatialAttention(kernel_size)
    def forward(self, x):
        out = self.channel_attention(x) * x
        out = self.spatial_attention(out) * out
        return out

class SE(nn.Module):
    def __init__(self, c1, r=16):
        super(SE, self).__init__()
        self.avgpool = nn.AdaptiveAvgPool2d(1)
        self.l1 = nn.Linear(c1, c1 // r, bias=False)
        self.relu = nn.ReLU(inplace=True)
        self.l2 = nn.Linear(c1 // r, c1, bias=False)
        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
### 不同版本 IoU 指标的对比 #### 定义与特点 - **MPDIoU (Modified Point Distance Intersection over Union)** 是一种改进型的距离交并比计算方法,考虑了预测框和真实框之间的几何中心距离以及尺度差异的影响[^2]。 - **EIoU (Enhanced Intersection Over Union)** 考虑到了边界框回归中的三个几何因素:重叠面积、中心点偏差和尺度变化。这使得 EIoU 对于目标检测算法来说更加鲁棒,在处理不同比例的目标时表现更好。 - **CIoU (Complete Intersection Over Union)** 结合了 GIoU 和 DIoU 的优点,并引入了一个额外的因素来衡量两个矩形框之间长宽比的一致性。这种综合考量有助于提高定位精度,尤其是在面对极端纵横比的对象时[^1]。 - **DIoU (Distance-IoU Loss)** 在传统 IoU 基础上加入了两框质心间的欧几里得距离作为惩罚项,从而鼓励预测框更紧密地贴合实际位置,而不仅仅是追求最大化的重叠区域。 #### 性能分析 对于大多数情况下,CIoUDIoU 都能够提供优于原始 IoU 或者其他变体的表现,因为它们不仅关注于最大化重叠部分,还通过加入新的约束条件改善了模型的学习过程。特别是当涉及到具有挑战性的场景如严重遮挡或大角度旋转对象时,这些增强版 IoU 函数可以显著提升检测效果。 相比之下,虽然 MPDIoU 提出了新颖的概念试图解决特定问题,但在广泛的应用测试中可能不如 CIoUDIoU 来得普遍适用;而 EIoU 则因其全面考虑到多种影响因子而在某些复杂环境中展现出独特优势。 ```python def compute_iou(box_a, box_b): """ 计算基础的 IoU """ inter_xmin = max(box_a[0], box_b[0]) inter_ymin = max(box_a[1], box_b[1]) inter_xmax = min(box_a[2], box_b[2]) inter_ymax = min(box_a[3], box_b[3]) intersection_area = max(0., inter_xmax - inter_xmin) * max(0., inter_ymax - inter_ymin) area_box_a = (box_a[2]-box_a[0])*(box_a[3]-box_a[1]) area_box_b = (box_b[2]-box_b[0])*(box_b[3]- intersection_area iou_value = intersection_area / float(union_area) return iou_value def compute_diou(box_a, box_b): """ 计算 DIoU """ iou = compute_iou(box_a, box_b) center_dist_sqrd = ((box_a[0]+box_a[2])/2-(box_b[0]+box_b[2])/2)**2 \ +((box_a[1]+box_a[3])/2-(box_b[1]+box_b[3])/2)**2 diag_len_sqrd = (box_a[2]-box_a[0])**2+(box_a[3]-box_a[1])**2 diou_loss = 1-iou+center_dist_sqrd/diag_len_sqrd return diou_loss def compute_ciou(box_a, box_b): """ 计算 CIoU """ v = (4/(math.pi**2)) * torch.pow(torch.atan(w_true/h_true)-torch.atan(w_pred/h_pred), 2) alpha = v/((1-compute_iou(box_a, box_b))+v) ciou_loss = compute_diou(box_a, box_b)+alpha*v return ciou_loss ```
评论 29
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值