你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

基于STM32用机器学习实现心率异常检测经验分享

[复制链接]
攻城狮Melo 发布时间:2024-5-25 17:10
首先我的数据并没有做任何任何的处理,本来我是打算加一个直流滤波的,首先是效果不太好,其次是我都用上机器学习了我为什么还要自己处理数据?机器学习本事的目的就是节约我们的脑子,利用机器来提取特征,而不是我们自己去提取特征(直流偏置本身也是一种特征),就算我的信号有其他的误差,我们可以处理一下提高分辨度,但是!对于机器而言,这些本身就是他的特征,我们只需要告诉机器,哪些特征是对的,哪些特征是错的!$ p6 U3 I# Z3 k) q3 V( K3 ~

% Q) h3 ]: u% v' {* `- Y
训练模型方面,我们使用MAX30102每10ms采样一次,每128次采样作为一组数据上传。
4 j* y$ @6 j" [& n4 \
( A& Q9 z: N2 @6 g
  1. int i = 0;& }  t+ P/ y3 u$ R
  2. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim): Q7 g. q  o& e0 Q
  3. {( z" z' Q6 h# a2 F+ u; I, E" e4 v3 V) C* r
  4.     maxim_max30102_read_fifo(&red,&ir);
    3 b5 [: [6 g& g& x. L. G( h. o
  5.     printf("%ld ",ir);! z) S) U: G1 o2 Y4 x0 J
  6.     i++;
    2 b, b- A  \! m- {% }/ m
  7.     if(i==128)
    - f  z! z( \5 u3 X  z8 L
  8.     {
    4 @$ O, K/ U* C
  9.       i=0;
    & P2 G- F, c2 i/ B. u; ?$ r
  10.       printf("\n");
    / `- b# k. x: N
  11.     }
    % t4 l  q. K6 j: s  r+ ^  h1 n
  12. }
复制代码

9 C) _- j& P+ W# Y这里我们不对数据进行任何处理,因为既然我们选择了机器学习就是为了节省我们对于数据的处理,节省对于特征的提取。
; t  K. R4 p+ `
7 p# B2 i/ ~; i: Z( a. X! E; m
模型训练) ^# ~- A" f' F: P
我们打开NanoEdge AI Studio,这次的项目我们选择异常检测。4 @% v  b1 M/ P
( T6 w( m' p- a7 s; B
微信图片_20240525170819.png
: |5 i* B: N( }+ k( N1 k: \! S* B, a  c  e/ e0 t. [
微信图片_20240525170822.png
, @, [5 s1 x& K: U) p
' r0 [8 i! V* }, {, c+ `; n* g
传感器选择通用传感器,轴数为1,芯片型号选择自己所需要的芯片型号。
4 d% R: e7 I, Z1 u# b
" J2 {, u2 V$ @ 微信图片_20240525170825.png 7 O5 I. s' u( o
; s+ `4 w& Z  A  a3 S, I
Regualr signals 常规数据
1 l% A1 I4 i& ]; _* I# V+ gAbnormal signals 异常数据
; F2 I, h4 h4 f" ~: r1 \8 f2 G$ N4 l( k% s( p1 i4 p
我们通过串口(USB)分别导入正常的信号和异常的信号。
; L  [* C9 V9 p" K+ N7 \1 M( I0 c9 G2 |2 Z/ z2 h4 q' ]% G* E5 |
微信图片_20240525170827.png , X9 o9 |% T8 T

5 f/ ^4 F4 q! u
微信图片_20240525170830.png 4 v# X5 `9 E; k

. o8 _' p" D% O5 X) R数据集尽可能多且广泛并且经典。! n& p# J1 s7 i  D# O6 }

) J- \; i0 r; v8 N* D) b 微信图片_20240525170833.png 7 Y; u, I- A. j* V  h
/ M( P$ v5 J& G
我们总共导入了两百组信号,这些信号包含了大拇指,中指以及稍微靠前的位置和稍微靠后的位置,保证数据集的范围足够的广泛。
% _% ?7 O. v2 A# q
( s1 w! P: k" h1 m 微信图片_20240525170836.png 4 _, `$ P% h0 I: x" K

1 {: Z- H1 z' r- w* |. r异常信号就非常简单,我们放在那里空置信号,晃动信号这里我放在那里测了总共三百多组(打游戏打忘记了)。
  h  R0 j7 f  }# [$ ^+ d5 D6 G* e
3 [% E1 A1 Z% k3 \" n
然后利用这两组信号进行训练。  |2 U( c6 m2 h0 Q  T

- p3 S, i" d5 ^
微信图片_20240525170838.png ; O$ E& Q7 V* D4 A
8 ~6 N/ b* _; [8 ?
我们将异常信号和正常信号全部选上,之后进行训练。
/ `% \% m; ]/ w4 g' N, D1 }6 I; q+ O+ h1 f: ^+ i* M8 {
微信图片_20240525170841.png
8 J/ b6 F) M+ J) I+ Y" I

" s9 r' s7 P& n( E3 h0 D之后查看训练详情,等待模型训练完成。
. J1 {; |1 u! q; [, r  V. l6 V: Z; L" f  O* l& Z
微信图片_20240525170846.png
3 ]3 l& h9 a5 `! y7 V

7 z: x) ~9 \* {  E可以看到,训练完的模型无论是准确率还是RAM大小Flash大小,都相当的合适,接下来我们测试一下我们的模型。; P& Y& `3 l: z- i* c! Z* K3 @7 G
! K7 Q& H: v' F" {. Z# ?1 g, ]5 m
微信图片_20240525170849.png 4 {7 K1 g' s4 C1 B# X

+ @5 E, T: h( G9 @" C  ?这边可以查看训练过程中的模型。- M9 E# d! A% {+ V% t
$ {* Z& _7 p0 Y2 _$ L
微信图片_20240525170852.png . e5 Z4 h1 N# a/ N6 f$ R
7 x: G1 F+ ^: a: l! \
验证我们的模型。* w% A3 r# N1 }2 ?0 ?# k) t
* ?) o' ~3 h  @1 d( R; g: v
微信图片_20240525170855.png 7 `- H: F8 s3 @8 ]
2 K' L- v3 H9 Q2 D- A7 \2 m
这里需要注意的是,我们第一次导入数据会先进行训练,异常检测需要有一个学习环节。) Z% X4 X4 G$ P7 T/ s% |7 f$ Y8 g

2 t8 q6 k: A& Q9 D5 Y
官方的手册中推荐了至少十组正常数据进行学习。
) a' G. |9 L! X5 U
5 C) P# @# L5 {* ^3 } 微信图片_20240525170858.png
, w( h& x9 b# X; b- D# O

# h0 P, ]: j) l- R* I- k- p- k我录了21组正常数据进行学习。5 n* E0 `: i1 V) G8 M

. Z/ q7 c. I% z: c" t) I# m
然后就可以对模型进行验证。
. y. }0 N! @8 q5 j6 c5 y! D1 V* {/ \4 c  \, X8 x
微信图片_20240525170901.png 4 c+ M" `& Z/ F- p  ?3 e& Z) I- W. b
5 j) H' e1 n) n( ?* U
/ \  g4 @, j3 Q6 U% {- {1 M
部署我们的模型,其中需要他的.a文件和.h文件。4 n9 M, Q3 |. X" P$ T6 {! z/ G4 C

4 }* @& A' D* M8 q! ] 微信图片_20240525170904.png 6 ?( Q0 O1 U2 l" W  e: t4 K6 r

: g) |0 e# u! u: ?这里我们需要使用CubeIDE来编程。因为这里的.a文件是静态文件,静态文件使用keil编程有点麻烦,需要安装GCC编译器,STM32CubeIDE集成好了可以编译.a文件。! b1 r6 Z1 {9 Y4 q) h

. F9 |. q8 d7 Z" J: ~ 微信图片_20240525170906.png
. t  c& L9 t1 l& v4 D; j9 x9 a

7 P  K+ K! k( U. U& J! C8 a  Z  e1 |在属性中添加静态库的路径。
4 i2 G; A0 |' ~( \2 x3 a/ t7 e
+ E+ k+ P6 z9 F' } 微信图片_20240525170909.png
; k* Y& a% H, E

( A$ r" W6 p5 s3 K1 Y# W在库中添加路径,我们的.a文件是libneai.a,这里需要省略lib和后缀.a
  K; T' x3 {/ B* T1 z/ m1 r% y0 G. v
" Y; X! ]2 }* |% A 微信图片_20240525170913.png
) J* z; `3 }- F6 b7 ~6 ?

; \$ E0 [& ~! i0 ^3 n% S0 v& R导入NanoEdgeAI的库函数。- `' z6 G7 U, \. Q3 a( f% `
! H2 r4 p: r( A5 @" M; ~
微信图片_20240525170922.png 0 ^5 ]3 T. k$ N$ J5 g* G! \! l

! p1 ^! ~. q- d4 L! k8 e  x可以看到这里有三个函数,初始化函数,学习函数以及预测函数。
/ c( E3 r" p: L6 ~' S& a$ k8 h7 q! y+ H" _, b
  1. enum neai_state MyState;
复制代码
* Y" [2 ~& M1 n
定义一个枚举变量用来存放标志位。
4 D0 J5 ]; t# B( {( r4 K
  1. MyState  = neai_anomalydetection_init();//初始化
复制代码
! O( W# y. r. ^7 s4 y
初始化我们的模型。
8 E8 p! \* ?' J( Z
  1. float IRD[128];
    ; g5 c0 K8 S2 X: B+ X
  2. int i = 0;
    . n" \& R& \# b% H( c# _0 \# \' ~( O
  3. int LeranTime= 0;( J( W$ |7 J! _8 o: ~
  4. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)! w4 c6 h; S% l2 y2 U, g
  5. {( g0 b3 s  z$ i5 I3 {# @  \2 O
  6.     uint8_t yuce;6 ]0 n& `7 x% d. T- R
  7.     maxim_max30102_read_fifo(&red,&ir);
    1 T5 H; o9 f& H& k9 Y5 P$ l
  8.     IRD[i] = ir;. Y& p% i( G2 a% z- F
  9.     i++;
    8 C3 p: r! u, T$ ]

  10. 6 L# v/ e# D6 `4 ~1 }
  11.     if(i==128)! e: O% p0 X4 O+ R/ ~
  12.     {
    ' y% s+ ^: G- e7 i& T) t
  13.       if(LeranTime<10)- c4 o6 m  |1 `' x1 {/ S1 q% a* N3 Z
  14.       {
    * m" b/ n0 _; Z3 a* Z9 K6 Q
  15.         HAL_GPIO_TogglePin(GPIOF, GPIO_PIN_9);//LED翻转2 ~- f0 H. t2 e; g( L0 [- @
  16.         neai_anomalydetection_learn(IRD);
    . ?  H( c5 d+ {% ]' V4 m
  17.       }
    ! S, _6 f, a" B. b5 H
  18.       else8 X) v3 G, E* o  z2 l1 ^
  19.       {
    ' }7 y- S& h; Q/ o  L3 L3 W0 a: @+ q
  20.         neai_anomalydetection_detect(IRD, &yuce);
    8 \* _! |8 s2 c# _( }
  21.         if(yuce>80)
    : m2 Z% N- E3 ?  O
  22.         {) g8 G0 ~8 B/ N# u, k) Y, m; F
  23.           HAL_GPIO_WritePin(GPIOF, GPIO_PIN_10, 1);
    ) ~" h& ]( r5 {% }2 Y
  24.         }- }7 x4 M4 ^, G- P8 f+ V
  25.         else4 x) C; _9 Q' H3 J
  26.         {
    / L* N9 S! \( `0 E8 O& a
  27.           HAL_GPIO_WritePin(GPIOF, GPIO_PIN_10, 0);
    7 Z; i; h% M+ N. u
  28.         }  z- {" R+ ?+ ]9 J* H/ @
  29.       }
    7 b' }5 A0 ~" H2 ?) Z3 U  I
  30.       LeranTime++;
    ! `0 y/ ]$ c  S
  31.       i = 0;
      ~& H- |7 H, E1 x
  32.     }& R- z9 i  E- G7 ~  @8 ~+ |; y  j
  33. }
复制代码

, S3 s$ r# |0 H0 e" A+ [
  w2 ^' }9 H8 M7 S我们在定时器回调函数中调用,上电之后前十次为学习阶段,之后对测量值进行预测,当预期值>80即认为状态正常,则灯灭。1 I2 \# ~% V4 i) B( K  i
如果预期值<80则报警灯想起。& E' {/ e0 k, I

2 F) E6 }9 m3 Y8 a) R) X
  ?  X7 [% S9 F+ c7 ^8 G. q2 I9 K/ z
转载自:电路小白
) M' o6 f5 q: V5 T+ K7 p5 A# G如有侵权请联系删除
, Z3 g4 y* U: z$ F9 j
0 T+ _9 b' c; z3 B% L* W8 W- g. H5 b: m2 K! m- C% G

  s- Z! i! W" B9 g; c( S/ |: a
收藏 评论0 发布时间:2024-5-25 17:10

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版