【DL】P, AP, mAP

本文详细介绍了目标检测领域的评价标准,包括Precision(精度)、Average Precision(平均精度)和mean Average Precision(所有类别的平均精度)。通过PR曲线的新方式理解mAP的计算,并纠正了关于精度的旧错误理解。内容涵盖单个类别精度的计算、多个类别平均精度的求和以及最终的mAP计算方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Backto ML Index

这几个评价标准, 通常都是用在 CV 领域.

new way, 基于 PR 曲线的理解

目标检测中衡量识别精度的指标是mAP(mean average precision)。多个类别物体检测中,每一个类别都可以根据recall和precision绘制一条曲线,AP就是该曲线下的面积,mAP是多个类别AP的平均值.

old way, 错误的理解


这是师爷之前理解和计算方法, 把 Precision 当做 Recall 来计算了. 也记录在此, 做一个教训.

P: Precision 精度

一个模型的准确率指的是对 一张图像而言, 正确预测的某个类别的数量除以这张图像中这个类别的总数

P C = N ( TruePositives ) C N ( TotalObjects ) C P_C = \frac {N(\text{TruePositives})_C}{N(\text{TotalObjects})_C} PC=N(TotalObjects)CN(TruePositives)

#include "ti_msp_dl_config.h" #include "tjc_usart_hmi.h" #include <stdio.h> #include <stdint.h> #include <stdbool.h> #include <string.h> // 添加memset头文件 #include <ti/driverlib/dl_uart.h> #include <ti/devices/msp/msp.h> #include <ti/driverlib/driverlib.h> #include <ti/driverlib/dl_common.h> // 红外协议时序宏 (单位:微秒) #define LEADER_HIGH 9000 // 引导码高电平9ms #define LEADER_LOW 4500 // 引导码低电平4.5ms #define BIT_HIGH 560 // 数据位高电平560μs #define BIT_ONE_LOW 1690 // 逻辑"1"低电平1690μs #define BIT_ZERO_LOW 560 // 逻辑"0"低电平560μs #define TOLERANCE 150 // 时序容差±150μs #define SYSTEM_CLOCK 32000000 //// 32MHz // 安全参数 #define MAX_RETRY 3 // 最大重试次数 #define LOCK_TIME 15000 // 锁定时间(ms) #define TIME_WINDOW 3000 // 时间容错窗口(±3000ms) // 淘晶驰屏定义 #define TJC_PAGE_MAIN 0 #define TJC_TEXT_STATUS "t0" #define TJC_TEXT_TIME "t1" #define TJC_BUTTON_RESET "b0" #define FRAME_LENGTH 7 #define CONFIG_UART_0_BAUDRATE 115200 // 必须与屏幕波特率一致 // 全局变量结构体 - 使用默认内存分配 typedef struct { volatile uint32_t delay_value; volatile uint8_t retry_count; volatile uint32_t last_fail_time; volatile uint32_t rtc_counter; volatile uint32_t now_time; volatile uint32_t display_last_time; // 显示相关变量 volatile uint32_t display_counter; } GlobalVars; volatile GlobalVars globals; // 使用普通全局变量 volatile uint32_t delay_times = 0; volatile uint8_t uart_data = 0; volatile uint32_t now_time = 0; /******************** 淘晶驰串口屏驱动 ********************/ void tjc_send_cmd(const char *cmd) { // 发送命令主体 const char *p = cmd; while(*p) { while(!DL_UART_isTXFIFOEmpty(UART_0_INST)); // 等待发送完成 DL_UART_transmitData(UART_0_INST, *p++); } // 发送TJC协议结束符(0xFF 0xFF 0xFF) for(uint8_t i = 0; i < 3; i++) { while(!DL_UART_isTXFIFOEmpty(UART_0_INST)); DL_UART_transmitData(UART_0_INST, 0xFF); } } void tjc_set_text(const char *obj_name, const char *text) { char cmd[128]; snprintf(cmd, sizeof(cmd), "%s.txt=\"%s\"", obj_name, text); tjc_send_cmd(cmd); } void tjc_change_page(uint8_t page_id) { char cmd[16]; snprintf(cmd, sizeof(cmd), "page %d", page_id); tjc_send_cmd(cmd); } void tjc_beep(uint16_t duration_ms) { char cmd[16]; snprintf(cmd, sizeof(cmd), "beep %u", duration_ms); tjc_send_cmd(cmd); } /******************** 系统基础功能 ********************/ void delay_us(uint32_t us) { globals.delay_value = us; while(globals.delay_value != 0); } void SysTick_Handler(void) { if(globals.delay_value > 0) globals.delay_value--; globals.rtc_counter++; // 简单的RTC计数器(每毫秒增加1) globals.now_time = globals.rtc_counter; // 更新全局时间 } uint32_t get_timestamp(void) { return globals.rtc_counter; } /******************** 红外解码功能(8位) ********************/ bool validate_dynamic_code(uint8_t rx_code) { uint32_t current_seed = get_timestamp(); for(int offset = -TIME_WINDOW; offset <= TIME_WINDOW; offset++) { uint32_t seed = current_seed + offset; uint32_t calc_code = (seed * 0x5DEECE66D) & 0xFFFFFFFF; // 比较低8位 if(rx_code == (calc_code & 0xFF)) return true; } return false; } uint8_t ir_receive_packet(void) { uint8_t data = 0; uint32_t start_time = 0; uint32_t duration = 0; // 1. 检测引导码 while(DL_GPIO_readPins(GPIOA, DL_GPIO_PIN_9) == 1); // 等待高电平结束 start_time = get_timestamp(); while(DL_GPIO_readPins(GPIOA, DL_GPIO_PIN_9) == 0); // 等待低电平结束 duration = get_timestamp() - start_time; // 检查引导码低电平部分是否符合要求(转换为毫秒) if(duration < (LEADER_HIGH/1000 - TOLERANCE/1000) || duration > (LEADER_HIGH/1000 + TOLERANCE/1000)) return 0xFF; // 2. 检测引导码高电平部分 start_time = get_timestamp(); while(DL_GPIO_readPins(GPIOA, DL_GPIO_PIN_9) == 1); duration = get_timestamp() - start_time; if(duration < (LEADER_LOW/1000 - TOLERANCE/1000) || duration > (LEADER_LOW/1000 + TOLERANCE/1000)) return 0xFF; // 3. 接收8位数据 for(int i = 0; i < 8; i++) { start_time = get_timestamp(); while(DL_GPIO_readPins(GPIOA, DL_GPIO_PIN_9) == 0); duration = get_timestamp() - start_time; // 检查数据位高电平部分 if(duration < (BIT_HIGH/1000 - TOLERANCE/1000) || duration > (BIT_HIGH/1000 + TOLERANCE/1000)) return 0xFF; start_time = get_timestamp(); while(DL_GPIO_readPins(GPIOA, DL_GPIO_PIN_9) == 1); duration = get_timestamp() - start_time; // 判断逻辑位 if(duration >= (BIT_ONE_LOW/1000 - TOLERANCE/1000) && duration <= (BIT_ONE_LOW/1000 + TOLERANCE/1000)) { data |= (1 << (7 - i)); // 设置逻辑"1" } else if(duration >= (BIT_ZERO_LOW/1000 - TOLERANCE/1000) && duration <= (BIT_ZERO_LOW/1000 + TOLERANCE/1000)) { // 逻辑"0"不需要设置,默认为0 } else { return 0xFF; // 无效时序 } } return data; } /******************** 系统初始化 ********************/ void init_system(void) { // 初始化全局变量 memset((void*)&globals, 0, sizeof(GlobalVars)); // 添加SysTick初始化(1ms中断) DL_SYSTICK_config(32000); DL_SYSTICK_enableInterrupt(); // 添加这行 // 设置SysTick中断优先级 NVIC_SetPriority(SysTick_IRQn, 3); DL_GPIO_initDigitalInput(DL_GPIO_PIN_9); // 启用全局中断 __enable_irq(); // 初始化串口屏 // 增强版初始化序列 delay_us(1000000); // 等待1秒 // 软重启屏幕 tjc_send_cmd("rest"); delay_us(1500000); // 等待1.5秒 tjc_set_text(TJC_TEXT_STATUS, "等待红外信号"); tjc_set_text(TJC_TEXT_TIME, "系统启动完成"); } /******************** 主业务逻辑 ********************/ void security_fsm(void) { // 1. 检测锁定状态 if(globals.retry_count >= MAX_RETRY) { if(get_timestamp() - globals.last_fail_time < LOCK_TIME) { tjc_set_text(TJC_TEXT_STATUS, "锁定中,请稍候"); return; } globals.retry_count = 0; } // 2. 尝试接收数据包 uint8_t rx_code = ir_receive_packet(); if(rx_code == 0xFF) { tjc_set_text(TJC_TEXT_STATUS, "信号接收失败"); tjc_beep(200); return; } // 3. 动态解码验证 if(validate_dynamic_code(rx_code)) { tjc_set_text(TJC_TEXT_STATUS, "认证成功"); tjc_beep(100); delay_us(50000); // 50ms延迟 tjc_beep(100); globals.retry_count = 0; } else { char msg[30]; snprintf(msg, sizeof(msg), "失败(剩余%d次)", MAX_RETRY - globals.retry_count - 1); tjc_set_text(TJC_TEXT_STATUS, msg); tjc_beep(500); globals.retry_count++; globals.last_fail_time = get_timestamp(); } } // 搭配滴答定时器实现的精确ms延时 void delay_ms(unsigned int ms) { delay_times = ms; while (delay_times != 0) ; } /******************** 主函数 ********************/ int main(void) { SYSCFG_DL_init(); // 初始化系统 init_system(); // 清除中断标志 NVIC_ClearPendingIRQ(UART_0_INST_INT_IRQN); // 使能串口中断 NVIC_EnableIRQ(UART_0_INST_INT_IRQN); SYSCFG_DL_init(); // 初始化显示变量 globals.display_last_time = globals.now_time; globals.display_counter = 0; uint8_t recv; recv= ir_receive_packet(); while(1) { // 每秒更新显示 if(globals.now_time - globals.display_last_time >= 1000) { globals.display_last_time = globals.now_time; globals.display_counter++; char str[50]; snprintf(str, sizeof(str), "t1.txt=\"运行:%d秒\"", globals.display_counter); tjc_send_cmd(str); } // 红外信号检测 security_fsm(); // 低功耗等待 __WFI(); } } Memory map prevented reading 0x20208040这个问题怎么办
最新发布
07-07
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值