esp32-s3部署yolox_nano进行目标检测

2023-11-30 17:36

本文主要是介绍esp32-s3部署yolox_nano进行目标检测,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

ESP32-S3部署yolox_nano进行目标检测

      • 一、生成模型部署项目
        • 01 环境
        • 02 配置TVM包
        • 03 模型量化
          • 3.1预处理
          • 3.2 量化
        • 04 生成项目
      • 二、烧录程序

手上的是ESP32-S3-WROOM-1 N8R8芯片,整个链路跑通了,但是识别速度太慢了,20秒一张图,所以暂时还没打算进一步优化程序。
在这里插入图片描述

一、生成模型部署项目

官方指导文件:使用TVM自动生成模型部署项目

先下载onnx模型:yolox_nano.onnx,将下载好的yolox_nano.onnx放置在esp-dl/tutorial/evm_example路径下。

01 环境
  • ESP-IDF 5.0
  • 虚拟机Ubuntu 20.04
  • python环境
    在这里插入图片描述
02 配置TVM包

按官方文档下载完包后,设置环境变量PYTHONPATH

sudo vim ~/.bashrc
# 在文件的最后添加以下行,其中path-to-esp-dl更换为你的文件路径
export PYTHONPATH='$PYTHONPATH:/path-to-esp-dl/tools/tvm/python'
03 模型量化
3.1预处理
~/esp-dl $ cd tutorial/tvm_example
~/esp-dl/tutorial/tvm_example $ python -m onnxruntime.quantization.preprocess --input yolox_nano.onnx --output yolox_nano_opt.onnx
3.2 量化
  • 生成校准数据
import numpy as np
import cv2
import os# 图片路径
path = 'esp-dl/img/calib'# 读取图片并将它们保存为numpy数组
images = []
for filename in os.listdir(path):img = cv2.imread(os.path.join(path, filename))img_resized = cv2.resize(img, (416, 416))img_array = np.transpose(img_resized, (2, 0, 1))img_array = img_array / 255.0if img_array is not None:images.append(img_array)print(filename)# 将numpy数组保存为npy文件
np.save('esp-dl/tutorial/tvm_example/calib_416x416.npy', images)
  • 生成模型输入
import numpy as np
import cv2
import ospath = 'esp-dl/img/input.jpg'img = cv2.imread(path)
img_resized = cv2.resize(img, (416, 416))
img_array = np.transpose(img_resized, (2, 0, 1))
img_array = img_array / 255.0
images = [img_array]np.save('esp-dl/tutorial/tvm_example/input_416x416.npy', images)
  • 生成量化后的模型
~/esp-dl/tutorial/tvm_example $ python ../../tools/tvm/esp_quantize_onnx.py --input_model yolox_nano_opt.onnx --output_model yolox_nano_quant.onnx --calibrate_dataset calib_416x416.npy
Collecting tensor data and making histogram ...
Finding optimal threshold for each tensor using entropy algorithm ...
Number of tensors : 365
Number of histogram bins : 128 (The number may increase depends on the data it collects)
Number of quantized bins : 128
WARNING:root:Please use QuantFormat.QDQ for activation type QInt8 and weight type QInt8. Or it will lead to bad performance on x64.
04 生成项目
~/esp-dl/tutorial/tvm_example $ python ../../tools/tvm/export_onnx_model.py --model_path yolox_nano_quant.onnx --img_path input_416x416.npy --target_chip esp32s3 --out_path "." --template_path "../../tools/tvm/template_project_for_model/"
Model Information:
------------------
Input Name: images
Input Shape: (1, 3, 416, 416)
Input DType: float
Output Name: output
Output Shape: (1, 3549, 85)
Output DType: float
[17:21:47] /home/gansichen/Workspace/projects/local/framework/tvm/src/relay/transforms/convert_layout.cc:99: Warning: Desired layout(s) not specified for op: nn.max_pool2d
[17:21:47] /home/gansichen/Workspace/projects/local/framework/tvm/src/relay/transforms/convert_layout.cc:99: Warning: Desired layout(s) not specified for op: nn.max_pool2d
[17:21:47] /home/gansichen/Workspace/projects/local/framework/tvm/src/relay/transforms/convert_layout.cc:99: Warning: Desired layout(s) not specified for op: nn.max_pool2d
[17:21:47] /home/gansichen/Workspace/projects/local/framework/tvm/src/relay/transforms/convert_layout.cc:99: Warning: Desired layout(s) not specified for op: image.resize2d
[17:21:47] /home/gansichen/Workspace/projects/local/framework/tvm/src/relay/transforms/convert_layout.cc:99: Warning: Desired layout(s) not specified for op: image.resize2d
esp_dl_library_path: /home/zymidea/Desktop/esp32-cam/esp-dl
generated project in: ./new_project

二、烧录程序

烧录用的windows系统,将虚拟机中生成的new_project文件夹复制到PC端,打开ESP-IDF CMD

cd new_preject
idf.py set-target esp32s3
idf.py flash monitor

这是按照官方的教程进行烧录,但是模型太大会出现内存溢出esp32-template-project.elf section '.dram0.bss' will not fit in region 'dram0_0_seg' region 'dram0_0_seg' overflowed by 2141320 bytes

~/new_project $ idf.py size-components
...
Total sizes:                                                                               
Used static IRAM:   61042 bytes ( 301198 remain, 16.9% used)                                    .text size:   60015 bytes                                                                  .vectors size:    1027 bytes                                                         
Used stat D/IRAM: 2442376 bytes (-2096520 remain, 706.2% used) Overflow detected!              .data size:   11088 bytes                                                                  .bss  size: 2431288 bytes                                                             
Used Flash size : 3729295 bytes                                                                .text     :  473467 bytes                                                                  .rodata   : 3255572 bytes                                                             
Total image size: 3801425 bytes (.bin may be padded larger) 

在这里插入图片描述

找到new_project/build/project_description.jsonlibtvm_model.a静态文件的源代码。
在这里插入图片描述

官方指导片外RAM

需要调整的是将模型的权重文件保存到flash并将模型的输出存放在PSRAM,操作如下

// 打开/new_project/components/tvm_model/model/codegen/host/src/default_lib0.c// 代码最前面
// 增加一个头文件
#include "E:/Espressif/frameworks/esp-idf-v5.0.4/components/esp_common/include/esp_attr.h"// static struct global_const_workspace 将static改为const
const struct global_const_workspace// 代码最后面
// __attribute__((section(".bss.noinit.tvm"), aligned(16))) 将这句话注释掉
static EXT_RAM_BSS_ATTR uint8_t global_workspace[2422784]; // 增加宏EXT_RAM_BSS_ATTR
// 打开/new_project/main/output_data.h
const static _SECTION_ATTR_IMPL(".ext_ram.bss", __COUNTER__) __attribute__((aligned(16))) float output_data[42588] // 指定该数组存放到外部RAM的.ext_ram.bss段
~/new_project $ idf.py menuconfig

在这里插入图片描述
在这里插入图片描述
修改完毕S键保存,Esc键退出。

修改/new_project/partitions.csv分区表中的factory的大小,原本的3000多K存储模型权重不够,将其增大点,三个区的Offset都清空,生成过程它会自动匹配。

在这里插入图片描述

所有的修改完毕后再重新再看一下各个RAM的使用情况

~/new_project $ idf.py size-components
...
Used static IRAM:   61042 bytes ( 301198 remain, 16.9% used).text size:   60015 bytes.vectors size:    1027 bytes
Used stat D/IRAM:   19592 bytes ( 326264 remain, 5.7% used) .data size:   11088 bytes.bss  size:    8504 bytes 
Used Flash size : 3729203 bytes                                                                .text     :  473455 bytes                                                                  .rodata   : 3255492 bytes                                                             
Total image size: 3801333 bytes (.bin may be padded larger) 
...

在这里插入图片描述

最后重新烧录就能运行成功了。

~/new_project $ idf.py flash monitor

在这里插入图片描述

这篇关于esp32-s3部署yolox_nano进行目标检测的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/437913

相关文章

使用IDEA部署Docker应用指南分享

《使用IDEA部署Docker应用指南分享》本文介绍了使用IDEA部署Docker应用的四步流程:创建Dockerfile、配置IDEADocker连接、设置运行调试环境、构建运行镜像,并强调需准备本... 目录一、创建 dockerfile 配置文件二、配置 IDEA 的 Docker 连接三、配置 Do

Python进行JSON和Excel文件转换处理指南

《Python进行JSON和Excel文件转换处理指南》在数据交换与系统集成中,JSON与Excel是两种极为常见的数据格式,本文将介绍如何使用Python实现将JSON转换为格式化的Excel文件,... 目录将 jsON 导入为格式化 Excel将 Excel 导出为结构化 JSON处理嵌套 JSON:

一文解密Python进行监控进程的黑科技

《一文解密Python进行监控进程的黑科技》在计算机系统管理和应用性能优化中,监控进程的CPU、内存和IO使用率是非常重要的任务,下面我们就来讲讲如何Python写一个简单使用的监控进程的工具吧... 目录准备工作监控CPU使用率监控内存使用率监控IO使用率小工具代码整合在计算机系统管理和应用性能优化中,监

如何使用Lombok进行spring 注入

《如何使用Lombok进行spring注入》本文介绍如何用Lombok简化Spring注入,推荐优先使用setter注入,通过注解自动生成getter/setter及构造器,减少冗余代码,提升开发效... Lombok为了开发环境简化代码,好处不用多说。spring 注入方式为2种,构造器注入和setter

MySQL进行数据库审计的详细步骤和示例代码

《MySQL进行数据库审计的详细步骤和示例代码》数据库审计通过触发器、内置功能及第三方工具记录和监控数据库活动,确保安全、完整与合规,Java代码实现自动化日志记录,整合分析系统提升监控效率,本文给大... 目录一、数据库审计的基本概念二、使用触发器进行数据库审计1. 创建审计表2. 创建触发器三、Java

MySQL 主从复制部署及验证(示例详解)

《MySQL主从复制部署及验证(示例详解)》本文介绍MySQL主从复制部署步骤及学校管理数据库创建脚本,包含表结构设计、示例数据插入和查询语句,用于验证主从同步功能,感兴趣的朋友一起看看吧... 目录mysql 主从复制部署指南部署步骤1.环境准备2. 主服务器配置3. 创建复制用户4. 获取主服务器状态5

MySQL深分页进行性能优化的常见方法

《MySQL深分页进行性能优化的常见方法》在Web应用中,分页查询是数据库操作中的常见需求,然而,在面对大型数据集时,深分页(deeppagination)却成为了性能优化的一个挑战,在本文中,我们将... 目录引言:深分页,真的只是“翻页慢”那么简单吗?一、背景介绍二、深分页的性能问题三、业务场景分析四、

SpringBoot结合Docker进行容器化处理指南

《SpringBoot结合Docker进行容器化处理指南》在当今快速发展的软件工程领域,SpringBoot和Docker已经成为现代Java开发者的必备工具,本文将深入讲解如何将一个SpringBo... 目录前言一、为什么选择 Spring Bootjavascript + docker1. 快速部署与

golang程序打包成脚本部署到Linux系统方式

《golang程序打包成脚本部署到Linux系统方式》Golang程序通过本地编译(设置GOOS为linux生成无后缀二进制文件),上传至Linux服务器后赋权执行,使用nohup命令实现后台运行,完... 目录本地编译golang程序上传Golang二进制文件到linux服务器总结本地编译Golang程序

linux解压缩 xxx.jar文件进行内部操作过程

《linux解压缩xxx.jar文件进行内部操作过程》:本文主要介绍linux解压缩xxx.jar文件进行内部操作,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、解压文件二、压缩文件总结一、解压文件1、把 xxx.jar 文件放在服务器上,并进入当前目录#