极客秀
搜索

STM32中用机器学习实现正确率99.95%的心率异常检测!STM32机器学习实例:心率检测!简单的小实例,却是迈向新领域的步伐

之前一直想研究一下NanoEdge AI的实际应用。
STM32上小白也能快速部署机器学习模型工具——NanoEdgeAIStudio初使用体会

本来是想用AD5933做一个负载网络分类模型的,但是不知道为什么我那个AD5933一直在抽风,于是就打算使用手上的血氧传感器来做一个血氧异常检测。
这里我说明一下,虽然可能有很多朋友会觉得:啊这么简单的东西有必要这么麻烦嘛?但是通常对于我们工科人而言, 很多东西都是从简单的一小步慢慢向前走
。这里虽然血氧传感器只是一串一维数据,但是假如我希望判断是中指还是食指还是大拇指呢这种及其相似的数据呢?如果我掏出了一个六轴传感器,一次性处理六组相关数据呢?
虽然从MAX30100的血氧数据中提取出特征数据对于我们而言是很简单的,但是对于计算机来说,他和六轴并没有什么区别!他们的本质不过是一堆带有不同特征的信号,我们只要告诉机器,哪组正确哪组错误,让其自行判断。
因此本文仅以为例,展示一下,欢迎广大观众朋友留言,我可以尝试更多的使用方面。 这里我简单的说明一下, ** 首先我的数据并没有做任何任何的处理 **
,本来我是打算加一个直流滤波的,首先是效果不太好,其次是我都用上机器学习了我为什么还要自己处理数据? **
机器学习本事的目的就是节约我们的脑子,利用机器来提取特征,而不是我们自己去提取特征(直流偏置本身也是一种特征) **
,就算我的信号有其他的误差,我们可以处理一下提高分辨度,但是!对于机器而言,这些本身就是他的特征,我们只需要告诉机器,哪些特征是对的,哪些特征是错的!
训练模型方面,我们使用MAX30102每10ms采样一次,每128次采样作为一组数据上传。


int i = 0;void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){    maxim_max30102_read_fifo(&red,&ir);    printf("%ld ",ir);    i++;    if(i==128)    {      i=0;      printf("n");    }}

这里我们不对数据进行任何处理,因为既然我们选择了机器学习就是为了节省我们对于数据的处理,节省对于特征的提取。

  • 模型训练

我们打开NanoEdge AI Studio,这次的项目我们选择 异常检测

传感器选择通用传感器,轴数为1,芯片型号选择自己所需要的芯片型号。

  • Regualr signals 常规数据
  • Abnormal signals 异常数据

我们通过串口(USB)分别导入正常的信号和异常的信号。

数据集尽可能多且广泛并且经典。

我们总共导入了两百组信号,这些信号包含了大拇指,中指以及稍微靠前的位置和稍微靠后的位置,保证数据集的范围足够的广泛。

异常信号就非常简单,我们放在那里空置信号,晃动信号这里我放在那里测了总共三百多组(打游戏打忘记了)。
然后利用这两组信号进行训练。

我们将异常信号和正常信号全部选上,之后进行训练。

之后查看训练详情,等待模型训练完成。

可以看到,训练完的模型无论是准确率还是RAM大小Flash大小,都相当的合适,接下来我们测试一下我们的模型。

这边可以查看训练过程中的模型。

验证我们的模型。

这里需要注意的是,我们第一次导入数据会先进行训练,异常检测需要有一个学习环节。 官方的手册中推荐了至少十组正常数据进行学习。

我录了21组正常数据进行学习。 然后就可以对模型进行验证。

部署我们的模型,其中需要他的.a文件和.h文件。

这里我们需要使用CubeIDE来编程。因为这里的.a文件是静态文件,静态文件使用keil编程有点麻烦,需要安装GCC编译器,STM32CubeIDE集成好了可以编译.a文件。

在属性中添加静态库的路径。

在库中添加路径,我们的.a文件是libneai.a,这里需要省略lib和后缀.a

导入NanoEdgeAI的库函数。

可以看到这里有三个函数, 初始化函数,学习函数以及预测函数

enum neai_state MyState;

定义一个枚举变量用来存放标志位。

MyState  = neai_anomalydetection_init();//初始化

初始化我们的模型。


float IRD[128];int i = 0;int LeranTime= 0;void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){    uint8_t yuce;    maxim_max30102_read_fifo(&red,&ir);    IRD[i] = ir;    i++;  
    if(i==128)    {      if(LeranTime<10)      {        HAL_GPIO_TogglePin(GPIOF, GPIO_PIN_9);//LED翻转        neai_anomalydetection_learn(IRD);      }      else      {        neai_anomalydetection_detect(IRD, &yuce);        if(yuce>80)        {          HAL_GPIO_WritePin(GPIOF, GPIO_PIN_10, 1);        }        else        {          HAL_GPIO_WritePin(GPIOF, GPIO_PIN_10, 0);        }      }      LeranTime++;      i = 0;    }}

我们在定时器回调函数中调用,上电之后前十次为学习阶段,之后对测量值进行预测,当预期值>80即认为状态正常,则灯灭。
如果预期值<80则报警灯想起。

1.转载请保留原文链接谢谢!
2.本站所有资源文章出自互联网收集整理,本站不参与制作,如果侵犯了您的合法权益,请联系本站我们会及时删除。
3.本站发布资源来源于互联网,可能存在水印或者引流等信息,请用户擦亮眼睛自行鉴别,做一个有主见和判断力的用户。
4.本站资源仅供研究、学习交流之用,若使用商业用途,请购买正版授权,否则产生的一切后果将由下载用户自行承担。
5.联系方式(#替换成@):pm#vimge.com

  相关内容