### YOLOv8 中结合 Wiou 函数与 REPBiFPN 结构的实现与使用
#### 实现背景
在目标检测领域,YOLOv8 是一种高效的实时检测框架。为了进一步提升其性能,可以引入 **Wiou (Weighted Intersection over Union)** 损失函数以及 **REPBiFPN (Reparameterized Bi-directional Feature Pyramid Network)** 的特征融合模块[^1]。
---
#### Wiou 函数的作用
Wiou 函数是一种改进版的 IoU 损失函数,在计算边界框回归损失时考虑了权重分配问题。相比于传统的 IoU 或 GIoU,它能够更好地处理不同大小的目标之间的误差分布[^2]。具体来说:
- 它通过加权的方式调整大目标和小目标的影响程度。
- 这种机制有助于减少因目标尺寸差异而导致的梯度不稳定现象。
以下是 Wiou 函数的一个简单实现示例:
```python
import torch
def wiou_loss(pred_boxes, target_boxes):
"""
计算 Weighted IOU Loss
:param pred_boxes: 预测框张量 [B, 4], 形状为 (cx, cy, w, h)
:param target_boxes: 真实框张量 [B, 4], 形状为 (cx, cy, w, h)
:return: 平均 Wiou loss 值
"""
eps = 1e-7
# 转换到左上角右下角坐标系
pred_x1y1 = pred_boxes[:, :2] - pred_boxes[:, 2:] / 2
pred_x2y2 = pred_boxes[:, :2] + pred_boxes[:, 2:] / 2
target_x1y1 = target_boxes[:, :2] - target_boxes[:, 2:] / 2
target_x2y2 = target_boxes[:, :2] + target_boxes[:, 2:] / 2
# 计算交集区域
inter_top_left = torch.max(pred_x1y1, target_x1y1)
inter_bottom_right = torch.min(pred_x2y2, target_x2y2)
inter_wh = (inter_bottom_right - inter_top_left).clamp(0)
intersection_area = inter_wh[:, 0] * inter_wh[:, 1]
# 计算并集面积
pred_area = pred_boxes[:, 2] * pred_boxes[:, 3]
target_area = target_boxes[:, 2] * target_boxes[:, 3]
union_area = pred_area + target_area - intersection_area + eps
iou = intersection_area / union_area
weighted_iou = (intersection_area + eps) / ((pred_area + target_area) / 2)
return 1 - weighted_iou.mean()
```
上述代码实现了基于预测框和真实框的 Wiou 损失计算逻辑。
---
#### REPBiFPN 的作用
REPBiFPN 是一种增强型双向特征金字塔网络,旨在优化多尺度特征融合的效果。相比传统 FPN 和 PANet,它的主要特点在于重新参数化技术的应用,使得训练过程更加稳定且高效。
以下是 REPBiFPN 的核心思想及其 Python 实现片段:
```python
class RepConv(torch.nn.Module):
"""Reparameterization Convolution Layer"""
def __init__(self, in_channels, out_channels, kernel_size=3, stride=1, padding=1):
super().__init__()
self.conv = torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride, padding)
self.bn = torch.nn.BatchNorm2d(out_channels)
def forward(self, x):
return self.bn(self.conv(x))
class REPBiFPNLayer(torch.nn.Module):
"""Single layer of the reparameterized bidirectional feature pyramid network."""
def __init__(self, num_channels):
super(REPBiFPNLayer, self).__init__()
# Top-down path
self.top_down_conv = RepConv(num_channels, num_channels)
# Bottom-up path
self.bottom_up_conv = RepConv(num_channels, num_channels)
def forward(self, features_list):
top_down_features = []
bottom_up_features = []
# Top-down fusion
for idx in range(len(features_list)-1, 0, -1):
upsampled_feature = torch.nn.functional.interpolate(
top_down_features[-1], scale_factor=2, mode='nearest'
) if len(top_down_features) > 0 else None
fused_feature = features_list[idx] + upsampled_feature \
if upsampled_feature is not None else features_list[idx]
processed_feature = self.top_down_conv(fused_feature)
top_down_features.append(processed_feature)
# Reverse order to start from smallest resolution
top_down_features.reverse()
# Bottom-up fusion
for idx in range(len(top_down_features)):
downsampled_feature = torch.nn.MaxPool2d(kernel_size=2)(bottom_up_features[-1]) \
if len(bottom_up_features) > 0 else None
fused_feature = top_down_features[idx] + downsampled_feature \
if downsampled_feature is not None else top_down_features[idx]
processed_feature = self.bottom_up_conv(fused_feature)
bottom_up_features.append(processed_feature)
return bottom_up_features[::-1]
```
这段代码定义了一个简单的 REPBiFPN 层级结构,其中 `RepConv` 表示重参数化的卷积层,而 `REPBiFPNLayer` 则负责完成自顶向下和自底向上的双路径特征融合。
---
#### 使用方法
要将 Wiou 函数与 REPBiFPN 整合到 YOLOv8 中,需执行以下操作:
1. 替换默认的 CLS 损失函数为 Wiou 损失函数,并确保其他部分保持一致。
2. 修改 backbone 或 neck 部分,用 REPBiFPN 取代原有的 PANet 或 FPN 架构。
3. 更新配置文件中的超参数设置以适配新的组件行为。
例如,在 PyTorch Lightning 的训练脚本中修改如下:
```python
from yolov8 import YOLOModel
model = YOLOModel(backbone="repbifpn", loss_fn="wiou")
trainer.fit(model, datamodule=data_module)
```
---