YOLO目标检测创新改进与实战案例专栏
专栏目录: YOLO有效改进系列及项目实战目录 包含卷积,主干 注意力,检测头等创新机制 以及 各种目标检测分割项目实战案例
专栏链接: YOLO目标检测创新改进与实战案例
摘要
随着检测器的迅速发展, 边框回归取得了巨大的进步。然而,现有的基于 IoU 的边框回归仍聚焦在通过加入新的损失项来加速收敛,忽视 IoU 损失项其自身的限制。尽管理论上 IoU 损失能够有效描述边框回归状态,在实际应用中,它无法根据不同检测器与检测任务进行自我调整,不具有很强的泛化性。基于以上,我们首先分析了 BBR 模式,得出结论在回归过程区分不同回归样本并且使用不同尺度的辅助边框计算损失能够有效加速边框回归过程。对于高 IoU 样本,使用较小的辅助边框计算损失能够加速收敛,而较大辅助边框适用于低 IoU 样本。接着,我们提出了 Inner-IoU Loss, 其通过辅助边框计算 IoU 损失。针对不同的数据集与检测器,我们引入尺度因子 ratio 控制辅助边框的尺度大小用于计算损失。最后,将 Inner-IoU 集成至现有的基于 IoU 损失函数中进行仿真实验与对比实验。实验结果表明在使用本文所提出方法后检测效果得到进一步提升,验证了本文方法的有效性以及泛化能力。
创新点
• 分析边框回归过程与模式,基于边框回归问题自身特性,提出在模型训练过程中使用较小的辅助边框计算损失对高IoU 样本的回归有增益效果,低IoU样本则与之相反。
• 提出了Inner-IoU Loss ,使用尺度因子ratio控制生成不同尺度的辅助边框用于计算损失。将其应用至现有IoU-based 损失函数中能够获得更快更为有效的回归结果。
方法:
1.边框回归模式分析
IoU 损失函数在计算机视觉任务中具有广泛的应用。在边框回归过程中不但能够评估回归状态的好坏,而且能够通过计算回归损失进行梯度传播从而加速收敛。在这我们讨论回归过程中IoU 变化与边框尺寸的关系,分析边框回归问题的自身特性,解释本文所提出方法的合理性。
图1(a)
图1(b)
如上图所示,其中图1.a 为IoU-Deviation 曲线图,其水平轴与竖直轴分别表示deviation与IoU 值,三种不同颜色曲线对应不同尺度边框的IoU 变化曲线。A,B,C,D,E 分别对应achors and GT 框5 种不同位置关系,其中红色边框代表长宽为10 的anchors, 其对应的GT 框用黑色边框表示。图1.b 为ABS(Grad)-Deviation 曲线图,与图1.a 所不同的是在图1.b 中纵轴表示IoU 梯度的绝对值。我们假设实际边框尺寸为10,尺寸为8 和12 的边框作为其辅助边框。在图a与图b 中A,E 对应低IoU 样本回归状态,B,D 对应高IoU 样本回归状态,由图1可以得到以下结论。
1. 由于辅助边框与实际边框之间仅存在尺度差异,在回归过程中其IoU 值的变化趋势与实际边框的IoU值变化趋势一致,能够反应实际边框回归结果的质量。
2. 对于高IoU 样本,较小尺度的辅助边框的IoU梯度的绝对值大于实际边框IoU 梯度的绝对值。
3. 对于低IoU 样本,较大尺度的辅助边框的IoU梯度的绝对值大于实际边框IoU 梯度的绝对值。基于以上分析,使用较小尺度的辅助边框计算IoU 损失将有助于高IoU 样本回归,达到加速收敛的效果。与之相反使用较大尺度的辅助边框计算IoU 损失能够加速低IoU 样本回归过程。
yoloy融合Inner-IoU
def innerciou(box1, box2, ratio = 1.0, xywh=True, eps=1e-7):
(x1, y1, w1, h1), (x2, y2, w2, h2) = box1.chunk(4, -1), box2.chunk(4, -1)
w1, h1, w2, h2_ = w1 / 2, h1 / 2, w2 / 2, h2 / 2
b1_x1, b1_x2, b1_y1, b1y2 = x1 - w1, x1 + w1, y1 - h1, y1 + h1_
b2_x1, b2_x2, b2_y1, b2y2 = x2 - w2, x2 + w2, y2 - h2, y2 + h2_
#IoU #IoU #IoU #IoU #IoU #IoU #IoU #IoU #IoU #IoU #IoU
inter = (torch.min(b1_x2, b2_x2) - torch.max(b1_x1, b2_x1)).clamp(0) \
(torch.min(b1_y2, b2_y2) - torch.max(b1_y1, b2_y1)).clamp(0)
union = w1 h1 + w2 h2 - inter + eps
iou = inter / union
#Inner-IoU #Inner-IoU#Inner-IoU#Inner-IoU#Inner-IoU#Inner-IoU#Inner-IoU
inner_b1_x1, inner_b1_x2, inner_b1_y1, inner_b1y2 = x1 - w1ratio, x1 + w1*ratio,\
y1 - h1ratio, y1 + h1_ratio
inner_b2_x1,inner_b2_x2, inner_b2_y1, inner_b2y2 = x2 - w2ratio, x2 + w2_ratio,\
y2 - h2*ratio, y2 + h2ratio
inner_inter = (torch.min(inner_b1_x2, inner_b2_x2) - torch.max(inner_b1_x1, inner_b2_x1)).clamp(0) \
(torch.min(inner_b1_y2, inner_b2_y2) - torch.max(inner_b1_y1, inner_b2_y1)).clamp(0)
inner_union = w1ratio h1ratio + w2ratio h2ratio - inner_inter + eps
inner_iou = inner_inter/inner_union
cw = torch.max(b1_x2, b2_x2) - torch.min(b1_x1, b2_x1) # convex width
ch = torch.max(b1_y2, b2_y2) - torch.min(b1_y1, b2_y1) # convex height
c2 = cw 2 + ch 2 + eps # convex diagonal squared
rho2 = ((b2_x1 + b2_x2 - b1_x1 - b1_x2) 2 + (b2_y1 + b2_y2 - b1_y1 - b1_y2) 2) / 4 # center dist 2
v = (4 / math.pi 2) torch.pow(torch.atan(w2 / h2) - torch.atan(w1 / h1), 2)
with torch.no_grad():
alpha = v / (v - iou + (1 + eps))
return inner_iou - (rho2 / c2 + v alpha)
task.py使用与yaml配置
详见: https://blog.csdn.net/shangyanaf/article/details/135904930