2024-4-6 21:47:36 [显示全部楼层]
617浏览
查看: 617|回复: 2

[ESP8266/ESP32] Beetle ESP32 C6 ncnn神经网络数字识别

[复制链接]
Beetle ESP32 C6 ncnn神经网络数字识别

# 介绍 Beetle ESP32 C6

Beetle ESP32 C6 ncnn神经网络数字识别图1Beetle ESP32 C6 ncnn神经网络数字识别图2

Beetle ESP32-C6是一款基于ESP32-C6芯片设计的迷你体积的低功耗物联网开发板

* 超小体积,尺寸仅25*20.5mm
* 搭载ESP32-C6芯片,支持Wi-Fi、BLE、Zigbee、Thread通讯协议
* 支持Wi-Fi 6协议,更低延迟,更低功耗
* 超低功耗,deep-sleep 14uA
* 集成锂电池充电功能
* 支持电池电压检测,了解设备电量信息

# 配置编译开发环境

首先按照 https://github.com/espressif/esp-idf 快速上手指引,配置 esp-idf 编译开发环境

设好代理,clone install export 三连即可

```shell
  1. git clone https://github.com/espressif/esp-idf
  2. git submodule update --init --recursive
  3. sh install.sh
  4. source export.sh
复制代码


```

# 编译 ncnn for esp32c6

github 下载 ncnn 最新源码

```shell
  1. git clone https://github.com/Tencent/ncnn.git
复制代码


```

弄一个 esp32c6 cmake toolchain,稍微精简下 ncnn 编译参数

* 禁用 c++ RTTI exception 减小体积
* esp32c6 只有单核心,禁用 openmp 多线程功能
* 不编译 benchncnn 跑分工具(依赖系统环境)
* esp32c6 存储更大,奢侈些就不需要精简算子

```cmake
  1. set(CMAKE_SYSTEM_NAME freertos)
  2. set(CMAKE_SYSTEM_PROCESSOR riscv)
  3. include($ENV{IDF_PATH}/tools/cmake/toolchain-esp32c6.cmake)
  4. set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
  5. set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
  6. set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
  7. set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
  8. set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
  9. # cache flags
  10. set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}" CACHE STRING "c flags")
  11. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}" CACHE STRING "c++ flags")
  12. option(NCNN_DISABLE_RTTI "" ON)
  13. option(NCNN_DISABLE_EXCEPTION "" ON)
  14. option(NCNN_DISABLE_PIC "" ON)
  15. option(NCNN_PLATFORM_API "" OFF)
  16. option(NCNN_RUNTIME_CPU "" OFF)
  17. option(NCNN_THREADS "" OFF)
  18. option(NCNN_OPENMP "" OFF)
  19. option(NCNN_BUILD_BENCHMARK "" OFF)
  20. option(NCNN_BUILD_TESTS "" OFF)
  21. option(NCNN_BUILD_TOOLS "" OFF)
  22. option(NCNN_BUILD_EXAMPLES "" OFF)
复制代码


```

放到 ncnn toolchains 目录中,标准 cmake 三段式编译即可

```shell
  1. mkdir build-esp32
  2. cd build-esp32
  3. cmake -DCMAKE_TOOLCHAIN_FILE=../toolchains/esp32c6.toolchain.cmake ..
  4. make -j4
  5. make install
复制代码


```

Beetle ESP32 C6 ncnn神经网络数字识别图5

# 静态内存加载 mnist 模型

Beetle ESP32 C6 ncnn神经网络数字识别图3

依旧是2层conv+2层pool+1层fc的模型结构,极小的模型可以直接在静态内存区中加载

使用 ncnn 工具将模型文件转换为静态数组,方便把模型直接嵌入到代码中

```shell
  1. ncnn2mem mnist.param mnist.bin mnist.id.h mnist.mem.h
复制代码


```

`mnist.mem.h` 文件就是我们需要的代码,里面包含2个数组,分别对应param和bin的内容

```cpp
  1. #include "ncnn/net.h"
  2. #include "mnist.mem.h"
  3. extern "C" void app_main(void)
  4. {
  5.     ncnn::Net net;
  6.     net.load_param(mnist_param_bin);
  7.     net.load_model(mnist_bin);
  8.     // 省略后续 ncnn 推理代码
  9. }
复制代码


```

详细代码已更新到 https://github.com/nihui/ncnn_on_esp32

# ncnn esp32 避坑

在比较新的 ncnn 版本中默认开启了内存池优化,即推理的中间结果所占用的内存不会返还系统,而是保留给下一次使用,减少系统内存管理开销

为此,内存池会增加内存占用,这在 esp32 这种小内存开发板上容易引起内存不足,导致崩溃

在加载模型前设置 `net.opt.use_local_pool_allocator = false;` 禁用内存池功能

```cpp
  1. #include "ncnn/net.h"
  2. #include "mnist.mem.h"
  3. extern "C" void app_main(void)
  4. {
  5.     ncnn::Net net;
  6.     net.opt.use_local_pool_allocator = false; // 增加这行避免内存错误
  7.     net.opt.use_sgemm_convolution = true; // esp32c6 内存更大,可以开sgemm加速
  8.     net.load_param(mnist_param_bin);
  9.     net.load_model(mnist_bin);
  10.     // 省略后续 ncnn 推理代码
  11. }
复制代码


```

# 效果和性能对比

最后编译项目,插上开发板,烧写

```shell
  1. idf.py set-target esp32c6
  2. idf.py menuconfig
  3. idf.py build
  4. idf.py flash
复制代码


```

tio 串口访问观测识别结果

```shell
  1. tio /dev/ttyACM0
复制代码


```

可以看到正确识别到了数字7,以及耗时

```
  1. ESP-ROM:esp32c6-20220919
  2. Build:Sep 19 2022
  3. rst:0xc (SW_CPU),boot:0xe (SPI_FAST_FLASH_BOOT)
  4. Saved PC:0x4001975a
  5. SPIWP:0xee
  6. mode:DIO, clock div:2
  7. load:0x40875720,len:0x1804
  8. load:0x4086c110,len:0xe2c
  9. load:0x4086e610,len:0x2e30
  10. entry 0x4086c11a
  11. I (22) boot: ESP-IDF v5.3-dev-2815-gbe06a6f5ff 2nd stage bootloader
  12. I (23) boot: compile time Apr  6 2024 19:48:25
  13. I (24) boot: chip revision: v0.0
  14. I (26) boot.esp32c6: SPI Speed      : 80MHz
  15. I (31) boot.esp32c6: SPI Mode       : DIO
  16. I (36) boot.esp32c6: SPI Flash Size : 2MB
  17. I (41) boot: Enabling RNG early entropy source...
  18. I (46) boot: Partition Table:
  19. I (50) boot: ## Label            Usage          Type ST Offset   Length
  20. I (57) boot:  0 nvs              WiFi data        01 02 00009000 00006000
  21. I (64) boot:  1 phy_init         RF data          01 01 0000f000 00001000
  22. I (72) boot:  2 factory          factory app      00 00 00010000 00100000
  23. I (79) boot: End of partition table
  24. I (83) esp_image: segment 0: paddr=00010020 vaddr=420b0020 size=0eee0h ( 61152) map
  25. I (117) esp_image: segment 1: paddr=0001ef08 vaddr=40800000 size=01110h (  4368) load
  26. I (121) esp_image: segment 2: paddr=00020020 vaddr=42000020 size=aa960h (698720) map
  27. I (407) esp_image: segment 3: paddr=000ca988 vaddr=40801110 size=08374h ( 33652) load
  28. I (424) esp_image: segment 4: paddr=000d2d04 vaddr=40809490 size=00f64h (  3940) load
  29. I (432) boot: Loaded app from partition at offset 0x10000
  30. I (433) boot: Disabling RNG early entropy source...
  31. I (444) cpu_start: Unicore app
  32. I (454) cpu_start: Pro cpu start user code
  33. I (454) cpu_start: cpu freq: 160000000 Hz
  34. I (454) app_init: Application information:
  35. I (457) app_init: Project name:     main
  36. I (461) app_init: App version:      1
  37. I (466) app_init: Compile time:     Apr  6 2024 19:48:22
  38. I (472) app_init: ELF file SHA256:  1c5a8e8fc...
  39. I (477) app_init: ESP-IDF:          v5.3-dev-2815-gbe06a6f5ff
  40. I (484) efuse_init: Min chip rev:     v0.0
  41. I (488) efuse_init: Max chip rev:     v0.99
  42. I (493) efuse_init: Chip rev:         v0.0
  43. I (498) heap_init: Initializing. RAM available for dynamic allocation:
  44. I (505) heap_init: At 4080B3B0 len 00071260 (452 KiB): RAM
  45. I (511) heap_init: At 4087C610 len 00002F54 (11 KiB): RAM
  46. I (517) heap_init: At 50000000 len 00003FE8 (15 KiB): RTCRAM
  47. I (525) spi_flash: detected chip: generic
  48. I (529) spi_flash: flash io: dio
  49. W (532) spi_flash: Detected size(4096k) larger than the size in the binary image header(2048k). Using the size in the binary image header.
  50. I (546) sleep: Configure to isolate all GPIO pins in sleep state
  51. I (552) sleep: Enable automatic switching of GPIO sleep configuration
  52. I (559) coexist: coex firmware version: d96c1e51f
  53. I (565) coexist: coexist rom version 5b8dcfa
  54. I (570) main_task: Started on CPU0
  55. I (570) main_task: Calling app_main()
  56. Loading ncnn mnist model...Done.
  57. Preparing input...Start Mesuring!
  58. Done!
  59. 0: -1.68
  60. 1: 3.07
  61. 2: 12.28
  62. 3: 7.86
  63. 4: -17.84
  64. 5: -9.98
  65. 6: -15.03
  66. 7: 16.44
  67. 8: 0.54
  68. 9: -3.40
  69. I think it is number 7!
  70. Latency, avg: 426.81ms, max: 427.74, min: 426.69. Avg Flops: 1.83MFlops
  71. Restarting now.
复制代码


```

esp32c6 相对于 esp32c3 性能对比

Beetle ESP32 C6 ncnn神经网络数字识别图4

代码已更新到 https://github.com/nihui/ncnn_on_esp32



_深蓝_  高级技师

发表于 2024-4-14 09:39:15

完全看不懂呀!!!
回复

使用道具 举报

sky007  见习技师

发表于 2024-4-15 13:55:23

_深蓝_ 发表于 2024-4-14 09:39
完全看不懂呀!!!

可能本来就不是让我们看懂的吧
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4

© 2013-2024 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail