零基础的嵌入式机器学习:Edge Impulse训练模型移植STM32F407ZGT6实例

前言

        没有机器学习基础但是想利用嵌入式AI?Edge Impulse绝对是不二之选! 算法自动提供,代码一键生成,移植简单方便,简直是小白的福音!如果你打算涉及嵌入式 机器学习,那就快来看看吧! 

        第一次接触Edge Impulse这个在线的机器学习网站是在OpenMv口罩识别的历程中,根据OpenMv的官方历程来使用Edge Impulse还是很顺利的。但不久之后就发现如果仅仅是基于OpenMv的历程来进行机器学习,就只能完成图像识别而已,而除了图像识别之外的训练模型如果想要导出到STM32的单片机上,则要通过STM32CubeIDE。

STM32CubeIDE

        STM32CubeIDE是意法半导体公司推出的STM32集成开发环境,它允许用户在软件上点选相关选项,完成芯片的选型、外设的配置和时钟的配置等设置,自动生成代码并导出,方便实用。关于STM32CubeIDE的安装和使用教程在这里就不赘述,网上的教程很多。

Edge Impulse模型导出步骤

        如果你现在有一个已经在Edge Impulse训练好的模型,那么你就可以按照以下步骤部署到STM32的MCU上。

        首先在Edge Impulse工程的左侧找到Deployment选项,点选后在右侧选择Cube.MX CMSIS-PACK,然后点击下方的build将PACK包下载下来。

         下载下来后找个地方保存好,路径中不要包含中文字符,否则导入时会报错。

        打开STM32CubeIDE,新建一个STM32(STM32 Project)的工程,选择需要的芯片,我选择的是STM32F407ZGT6,记得编程语言选择C++。点击Finish创建工程。

        选择完毕后,配置好芯片的时钟,在Pinout & Configuration页下点击Software Packs,点击Manage Software Packs。

        点击左下角的From Local...,将之前下载下来的PACK包导入。

         导入完成后,回到Pinout & Configuration页下的Software Packs,点击Select Components

        找到刚刚导入的PACK包,一般有前缀EdgeImpulse标识,下拉找到Core,勾选右边的Selecetion。

         勾选完毕后Pinout & Configuration页,在左侧找到Software Packs,在右侧Mode下方勾选。

         勾选完毕后CTRL+S保存工程,点击YES,这时候会自动生成代码。

        代码生成完毕后在右侧的文件中找到main.c文件。

       

        在main.c中找到USER CODE BEGIN Includes,在BEGIN 和END之间粘贴如下代码:

#include "edge-impulse-sdk/classifier/ei_run_classifier.h"
using namespace ei;

// paste the raw features here
static const float features[] = {
		10,9,8,7,6,5,4,3,2,1
};

int get_feature_data(size_t offset, size_t length, float *out_ptr) {
    memcpy(out_ptr, features + offset, length * sizeof(float));
    return 0;
}

         

        在main.c中找到USER CODE BEGIN 0,在BEGIN 和END之间粘贴如下代码:

#include <stdarg.h>
#include "edge-impulse-sdk/classifier/ei_run_classifier.h"

void vprint(const char *fmt, va_list argp)
{
    char string[200];
    if(0 < vsprintf(string, fmt, argp)) // build string
    {
        HAL_UART_Transmit(&huart1, (uint8_t*)string, strlen(string), 0xffffff); // send message via UART
    }
}

void ei_printf(const char *format, ...) {
    va_list myargs;
    va_start(myargs, format);
    vprint(format, myargs);
    va_end(myargs);
}

       

         在main.c中找到USER CODE BEGIN Init,在BEGIN 和END之间粘贴如下代码: 

  signal_t signal;
  signal.total_length = sizeof(features) / sizeof(features[0]);
  signal.get_data = &get_feature_data;

         

        在main.c中找到USER CODE BEGIN Init,在BEGIN 和END之间粘贴如下代码: 

    ei_impulse_result_t result = { 0 };
	       EI_IMPULSE_ERROR res = run_classifier(&signal, &result, true);
	       ei_printf("run_classifier returned: %d\r\n", res);

	       ei_printf("Predictions (DSP: %d ms., Classification: %d ms., Anomaly: %d ms.): \r\n",
	           result.timing.dsp, result.timing.classification, result.timing.anomaly);

	       // print the predictions
	       ei_printf("[");
	       for (size_t ix = 0; ix < EI_CLASSIFIER_LABEL_COUNT; ix++) {
	           ei_printf_float(result.classification[ix].value);
	   #if EI_CLASSIFIER_HAS_ANOMALY == 1
	           ei_printf(", ");
	   #else
	           if (ix != EI_CLASSIFIER_LABEL_COUNT - 1) {
	               ei_printf(", ");
	           }
	   #endif
	       }
	   #if EI_CLASSIFIER_HAS_ANOMALY == 1
	       ei_printf_float(result.anomaly);
	   #endif
	       ei_printf("]\r\n\r\n\r\n");

	     HAL_Delay(5000);

        完成以上步骤之后,将main.c文件改为C++文件,右键点击main.c文件,选择RENAME,将main.c文件更名为main.cpp。

        最后,编译工程,这个时间会比较久,会持续几分钟,编译完成后将代码烧录到MCU中,通过串口助手即可看到结果:

        以上便是将Edge Impulse上的模型移植到STM32F4上的全部步骤,如果在移植过程中遇到什么问题可以参考Edge Impulse的帮助信息:Edge Impulse帮助信息

  • 9
    点赞
  • 76
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值