iou的cpu和gpu源码实现

本专栏主要是深度学习/自动驾驶相关的源码实现,获取全套代码请参考

简介

IoU(Intersection over Union)是一种测量在特定数据集中检测相应物体准确度的一个标准,通常用于目标检测中预测框(bounding box)之间准确度的一个度量(预测框和实际目标框)。
在这里插入图片描述

IoU计算的是“预测的边框”和“真实的边框”的交叠率,即它们的交集和并集的比值。最理想情况是完全重叠,即比值为1。

IoU的计算方法如下:

计算两个框的交集面积,即两个框的左、上、右、下四个点的交集。
计算两个框的并集面积,即两个框的左、上、右、下四个点的并集。
计算交集面积和并集面积的比值,即为 IoU 值。
IoU的优点是可以反映预测检测框与真实检测框的检测效果,并且具有尺度不变性,即对尺度不敏感。但是,IoU也存在一些缺点,例如无法反映两个框之间的距离大小(重合度),如果两个框没有相交,则 IoU 值为 0,无法进行学习训练。

源码实现:

cpu版源码实现:

def iou_core(box1: Tensor, box2: Tensor, area_sum: Tensor):overlap_w = torch.min(box1[2],box2[2]) - torch.max(box1[0],box2[0])overlap_h = torch.min(box1[3],box2[3]) - torch.max(box1[1],box2[1])if overlap_w <= 0 or overlap_h <= 0:return 0overlap_area = overlap_h * overlap_wreturn overlap_area / (area_sum - overlap_area)def iou_cpu(box1: Tensor, box2: Tensor):box1_num = box1.size(0)box2_num = box2.size(0)box1_dim = box1.size(1)box2_dim = box2.size(1)if box1_dim != 4 or box2_dim != 4:return -1box1_area = (box1[:, 2] - box1[:, 0]) * (box1[:, 3] - box1[:, 1])box2_area = (box2[:, 2] - box2[:, 0]) * (box2[:, 3] - box2[:, 1])result = torch.zeros(size=(box1_num, box2_num))for i in range(box1_num):for j in range(box2_num):if box1_area[i] >= 0 and box2_area[j] >= 0:result[i, j] = iou_core(box1[i], box2[j], box1_area[i] + box2_area[j])else:result[i, j] = 9999return result

gpu版源码实现:

__device__ float iou_core(const float* box1 ,const float* box2){float box1_x0 = *(box1 + 0);float box1_y0 = *(box1 + 1);float box1_x1 = *(box1 + 2);float box1_y1 = *(box1 + 3);float box2_x0 = *(box2 + 0);float box2_y0 = *(box2 + 1);float box2_x1 = *(box2 + 2);float box2_y1 = *(box2 + 3);if(!(box1_x0 < box1_x1 && box1_y0 < box1_y1 && box2_x0 < box2_x1 && box2_y0 < box2_y1)){return 9999;}float inter_x0 = std::max(box1_x0, box2_x0);float inter_x1 = std::min(box1_x1, box2_x1);float inter_y0 = std::max(box1_y0, box2_y0);float inter_y1 = std::min(box1_y1, box2_y1);float inter_area = (inter_x1 - inter_x0)*(inter_y1-inter_y0);inter_area = std::max(inter_area, 0.0f);float box1_area = (box1_x1 - box1_x0)*(box1_y1-box1_y0);float box2_area = (box2_x1 - box2_x0)*(box2_y1-box2_y0);float iou = inter_area / (box1_area + box2_area - inter_area);printf("iou =%f\n",iou);return iou;
}__global__ void iou_gpu_kernel(const int box1_num,
const float* box1_ptr,
const int box2_num,
const float* box2_ptr,
float* result_ptr){const int box1_idx = blockIdx.x * THREADS_PER_BLOCK + threadIdx.x;const int box2_idx = blockIdx.y * THREADS_PER_BLOCK + threadIdx.y;printf("gpu: box1_idx = %d, box2_idy= %d\n",box1_idx,box2_idx);if(box1_idx>=box1_num || box2_idx>=box2_num){return;}printf("gpu: box1_idx = %d, box2_idy= %d, result_id= %d\n",box1_idx,box2_idx,box1_idx * box2_num + box2_idx);const float* box1 = box1_ptr + box1_idx * 4;const float* box2 = box2_ptr + box2_idx * 4;float iou = iou_core(box1, box2);*(result_ptr + box1_idx * box2_num + box2_idx) = iou;
}void iou_gpu_launch(const int box1_num,
const float* box1_ptr,
const int box2_num,
const float* box2_ptr,
float* result_ptr){dim3 blocks(DIVUP(box1_num, THREADS_PER_BLOCK),DIVUP(box2_num, THREADS_PER_BLOCK));//每个grid的blocksdim3 threads(THREADS_PER_BLOCK,THREADS_PER_BLOCK);//每个block里面的threadprintf("blocks=(%d %d), threads=(%d %d)\n",DIVUP(box1_num, THREADS_PER_BLOCK),DIVUP(box2_num, THREADS_PER_BLOCK),THREADS_PER_BLOCK,THREADS_PER_BLOCK);iou_gpu_kernel<<<blocks,threads>>>(box1_num,box1_ptr,box2_num,box2_ptr,result_ptr);cudaDeviceSynchronize();// waiting for gpu workprintf("gpu done\n");
}

耗时测试:

import torch
from iou import iou_gpu, iou_cpu
from utils import TicTocdevice = torch.device('cuda:0')
input1 = torch.Tensor([[0, 0, 1, 1],[0, 2, 1, 3],[0.2, 0, 1, 1],[0.1, 2, 1, 3],[0.11, 0, 1, 1],[0, 2.4, 1, 3],[0.2, 0.1, 1, 1],[0.7, 2.5, 1, 3],[0, 0, 6, 1],[1.5, 2, 1, 3]]).to(device)
input2 = torch.Tensor([[0.5, 0, 1.5, 1],[0, 0.5, 1, 1.5],[0.5, 0.5, 1.5, 1.5],[0, 0.5, 1, 2.5]]).to(device)tictic = TicToc('iou fun')
for i in range(1000):result = iou_gpu(input1, input2)
tictic.toc()
tictic.tic()
for i in range(1000):result2 = iou_cpu(input1.to('cpu'), input2.to('cpu'))
tictic.toc()
pass

具体流程说明:

IoU的计算方法如下:
计算两个框的交集面积,即两个框的左、上、右、下四个点的交集。
计算两个框的并集面积,即两个框的左、上、右、下四个点的并集。
计算交集面积和并集面积的比值,即为 IoU 值。
在实际应用中,通常设定 IoU 的阈值,例如 0.5 或 0.7 等,当 IoU 值大于阈值时,认为预测成功。通过调整阈值,可以得到不同的模型,再通过不同的评价指标(如 ROC 曲线、F1 值等)来确定最优模型。

如需获取全套代码请参考

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/644212.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言|算术操作符相关题目

下面代码的结果是&#xff1a;( ) #include <stdio.h> int main() {int a, b, c;a 5;c a;b c, c, a, a;b a c;printf("a %d b %d c %d\n:", a, b, c);return 0; }A.a 8 b 23 c 8 B.a 9 b 23 c 8 C.a 9 b 25 c 8 D.a 9 b 24 c 8 解析&…

SSM项目集成Spring Security 4.X版本(使用spring-security.xml 配置文件方式)

目录 前言 实战开发&#xff1a; 一、Spring Security整合到SSM项目 1. pom文件引入包 2. web.xml 配置 3. 添加 spring-security.xml 文件 二、Spring Security实战应用 1. 项目结构 2. pom文件引入 3. web.xml 配置 4. Spring 配置 applicationContext.xml 5. sp…

Gartner:浪潮信息居全球服务器份额第二,中国第一

近日&#xff0c;国际权威研究机构高德纳&#xff08;Gartner&#xff09;公布《2023年第3季度全球服务器市场追踪报告》&#xff0c;2023Q3全球服务器出货量为280.6万台&#xff0c;同比下降17.0%&#xff0c;销售额为329.3亿美元&#xff0c;同比增长9.6%。浪潮信息服务器蝉联…

2-SAT问题相关理论和算法

前言 SAT 问题简介 SAT是可满足性、适定性(Satisfiability)问题的简称。一般形式为k-适定性问题或k-可满足性问题&#xff0c;简称 k-SAT。 何为布尔可满足性问题&#xff1f;给定一条真值表达式&#xff0c;包含逻辑变量、逻辑与、逻辑或以及非运算符&#xff0c;如&#x…

BioTech - 量子化学与分子力场

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/135787607 量子化学是应用量子力学的规律和方法来研究化学问题的一门学科&#xff0c;主要关注分子的结构、性质和反应过程。 量子化学的理论方法…

Redis解决方案:NOAUTH Authentication required(连接jedis绑定密码或修改redis密码)

Redis解决方案&#xff1a;NOAUTH Authentication required&#xff08;连接jedis绑定密码或修改redis密码&#xff09; Java使用jedis连接redis时出现错误NOAUTH Authentication required 一、问题报错和原因 本地设置了redis的密码&#xff0c;但在远程连接时并没有输入密…

定向减免!函数计算让 ETL 数据加工更简单

业内较为常见的高频短时 ETL 数据加工场景&#xff0c;即频率高时延短&#xff0c;一般费用大头均在函数调用次数上&#xff0c;推荐方案一般为攒批处理&#xff0c;高额的计算成本往往令用户感到头疼&#xff0c;函数计算推出定向减免方案&#xff0c;让 ETL数据加工更简单、更…

浅谈手机APP测试(流程)

前言 APP测试是一个广泛的概念&#xff0c;根据每个app的应用场景不一样&#xff0c;测试的方向也略微的不同&#xff0c;在测试过程中需要灵活应用自身所知的测试手段。 今天就跟大家简单聊聊手机APP测试的一些相关内容。 APP开发流程 &#xff08;1&#xff09; 拿到需求分…

2024年,IT行业下一个就业风口在哪?

搜狐&#xff1a;我宣布与华为达成鸿蒙全面合作&#xff01; 美团&#xff1a;我宣布与华为达成鸿蒙全面合作&#xff01; 360 &#xff1a;我宣布与华为达成鸿蒙全面合作&#xff01; 高德&#xff1a;我宣布与华为达成鸿蒙全面合作&#xff01; 新浪&#xff1a;我宣布与华为…

一站式解决钉钉开票与金蝶云星辰对接问题,让企业管理更轻松!

客户介绍 某企业服务有限公司专注于为企业提供全方位、高质量的企业服务&#xff0c;致力于于企业管理咨询、企业形象策划、市场营销策划、财务管理咨询等方面。该公司拥有一支经验丰富、专业化的团队&#xff0c;他们深入了解企业需求&#xff0c;为客户提供个性化的解决方案…

MoEs学习

和多任务学习的mmoe很像哦&#xff08;有空再学习一下&#xff09;moe layer的起源&#xff1a;Switch Transformers paper MoE moe由两个结构组成&#xff1a; Moe Layer &#xff1a;这些层代替了传统 Transformer 模型中的前馈网络 (FFN) 层。MoE 层包含若干“专家”(例如…

如何使用阿里云CDN服务?

如何使用阿里云CDN服务 一、开通阿里云CDN服务 注册自己阿里云账号&#xff0c;找到CDN服务&#xff0c;进行加速即可 二、配置域名信息 1、各配置参数的含义 添加加速域名&#xff1a; 如果需要使用CDN加速指定网站上的业务&#xff0c;则需要将该网站作为源站&#xff0…

“豚门”、“吗喽”,为啥品牌宣传瞄上网红动物?

近期&#xff0c;新茶饮品牌喜茶联名红山动物园&#xff0c;凭借可爱周边拿捏无数消费者&#xff0c;再往前一段时间&#xff0c;还有奈雪联名“吗喽”表情包&#xff0c;为什么品牌宣传会瞄上网红动物&#xff0c;今天媒介盒子就来和大家聊聊。 一、 萌元素引起用户情绪共鸣 …

蓝桥杯---三羊献瑞

观察下面的加法算式: 其中,相同的汉字代表相同的数字,不同的汉字代表不同的数字。 请你填写“三羊献瑞”所代表的4位数字(答案唯一),不要填写任何多余内容。 答案 代码 public class _03三羊献瑞 {public static void main(String[] args) {//c 生 b 瑞 g 献 d 辉…

如何系统学习机器学习?

要系统学习机器学习&#xff0c;首先需要掌握一些基础编程技能&#xff0c;如Python。其次&#xff0c;学习基础的数学概念&#xff0c;如线性代数、概率论和统计学。然后&#xff0c;选择一些优质的在线课程和教材进行深入学习。最后&#xff0c;通过实践项目来巩固所学知识。…

html火焰文字特效

下面是代码&#xff1a; <!DOCTYPE html> <html><head><meta charset"UTF-8"><title>HTML5火焰文字特效DEMO演示</title><link rel"stylesheet" href"css/style.css" media"screen" type&quo…

2024.1.23 GNSS 零散知识 学习笔记

1.天线种类 2.接收机 2.四大导航系统的介绍 3.卫星高度与轨道卫星种类 4.GNSS有哪些应用 5.在空间保持静⽌或匀速直线运动(⽆加速度)的坐标系称为惯性坐标系。 6.地⼼惯性坐标系实际上并没有满⾜能成为惯性坐标系的条件&#xff1a; ⾸先&#xff0c;地球及其质⼼都在围绕太阳…

[计算机提升] 切换(域)用户

4.14 切换(域)用户 4.14.1 为什么要切换用户 在Windows系统中&#xff0c;切换用户的主要目的是为了实现多用户共享同一台计算机的便利和安全。当多个人需要使用同一台计算机时&#xff0c;每个人可以登录自己的用户账户&#xff0c;这样可以避免互相干扰和混淆数据。 以下是…

《深入解析Java虚拟机:从JVM体系结构到垃圾回收算法》

文章目录 JVM体系结构JVM的组成 类加载器Class Loader类加载器的作用双亲委派机制JVM自带三个类加载器Bootstrap ClassLoader-根加载器ExtClassLoader-扩展加载器AppClassLoader-应用类加载器 Java历史-沙箱安全机制沙箱概念沙箱的作用本地代码和远程代码沙箱安全机制模型JDK1 …

C语言快速排序(非递归)图文详解

前言&#xff1a; 上一期分析了快速排序的三种写法&#xff0c;这三种写法有一个相同点&#xff0c;都是采用递归形式来实现的&#xff0c;那么有没有非递归的方法实现呢&#xff1f;答案是当然有&#xff0c;用非递归的方法实现快速排序&#xff0c;其实可以借助数据结构中的栈…