用该传感器判断是食指还是中指还是其他指头。& r# | p3 y$ D2 [$ ]/ o
7 l) G# ]. W* {6 d _
对于我们的三个指头(5个也好)本质上是一种多分类网络问题,我们将输入信号划分成不同的分类。! H7 r) P( t# g
小拇指2 r" `$ y6 Z A/ @* J# B
大拇指% J% p' @$ Q& \' f/ W4 z! A$ W
中指(后来用了食指方便)
1 u6 r8 l2 g) E2 \. w1 s% F" o" ?+ k没有指头(空置)
0 i. s2 p# @3 Z7 U% V- e- h: z9 X$ q/ J+ |9 s8 }3 D6 g1 o
因此我们利用多分类神经网络来实现判断功能。
; n" P* X4 N3 ^4 j3 a0 k( p+ l$ ^' L c3 p' q, R
- 8 F6 ^; E% Y9 }% C% c; `$ e
- int i = 0;
; [/ l$ j/ O( G- x - void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
# F( \5 j! X9 y# a( S - {! h( J4 F" [0 X3 i6 a
- maxim_max30102_read_fifo(&red,&ir);
0 i* n1 E# G- [6 C6 J - printf("%ld ",ir);% O- \! j3 o9 L8 T4 [ v2 }) v
- i++;. |( g* p! `( D7 n$ z2 T; G
- if(i==128) t& \- v- U K+ A/ w
- {
; _9 t) F( _3 ~* {3 ~( T - i=0;2 U, }" o5 z0 X" t8 Y
- printf("\n");1 V5 R! S3 r) u7 i) l
- }0 }/ u: D- i; Q- @8 k8 \. U2 L( }
- }
复制代码 9 P' ? Z) |8 B* r" n
信号的输入部分则和上期一样,100HZ的采样率,128的采样长度。
' M6 F# V$ _5 q- k: N% D) ?: E) M% z* Y
/ y4 w, F3 |* B9 {
2 F' i- y0 h9 K7 e8 }创建一个n-Class n分类神经网络。4 F4 M- L, O+ o5 Z$ e2 L" ` e
% @8 ?1 O" d2 N. T: T
- K* [" X" U, q. C0 {) D: W
# H% _% C" N" }. C4 \* S+ J
其他设置都和上期的保持一样,使用通用一轴传感器。" x _1 }9 `9 D8 r) U& q
( B }9 C2 E7 k: a+ J5 @# n
( N5 W7 {) v' i
V+ a: ^6 a1 }: ^$ c4 J* V但是信号输入的地方,我们利用串口导入各个类别的数据(这里是不同的指头)
; L' o, R6 }# w9 b9 g7 {2 |' n" g9 c# f4 f
2 U- T) D! g$ M0 t) n1 I$ ^% L0 ]; ? k5 F8 L, s1 j
需要注意的是,这里的标签即代表着我们的分类,不像之前那样子可以一个类别下面可以使用多组数据。( m X# }: b8 q# w
2 ]. P3 Q+ V) a) H, `
6 U+ f5 {, M8 J% ^5 J
; o0 \/ @$ ]7 X8 k; \7 ~; [训练我们的模型,这里可以选择我们的分类(其实这里我觉得要是把某组数据能添加到某个分类就好了,这里让我研究一下)。
# |' u o" h7 q' x7 r' F& }
: `- [8 L3 S8 j/ e, U' n/ b
c- o0 {" T% n+ p. r) R% D8 T F0 `6 G" T& W
训练好我们的模型,这里可以关注各指标。
8 Z* _9 U M- P9 R
% h' h& u \. q. C接着就是验证我们的模型,验证的过程可以参考文章开头的视频。1 f' D" Q# N) _2 r4 j) i# A
; E6 W6 w& S/ q' }' T
4 J* V0 ?1 S6 ]/ Q9 M' z) k
3 h2 U' |8 v( m% {0 \
部署完我们的模型之后,查看生成的.ZIP文件,其中相比于异常识别多了一个knowledge的头文件。; v' ~1 b3 \& @: w
) M# I/ Q! P- P: ` r% q
4 ?7 }7 L3 e) k0 p w# m& M. K- w0 v. p7 d3 L$ h4 f8 B
这里我们需要libneai.a以及两个.h文件 H& t3 i# y h0 U
! d- Q2 t& H6 E3 |
STM32中用机器学习实现正确率99.95%的心率异常检测!
; s" p" ]$ N# c+ V4 F" S' B( g$ @' n7 t9 l/ q' z
怎么导入文件请查看这篇文章。
8 X _- E3 y s1 `* X* a- H* v6 ^2 _0 Z4 p
0 S$ K: i4 @1 P4 R2 v
$ v; i, f l7 o初始化函数中,我们需要导入一个数组,这个数组就定义在knowledge.h这个文件中。
( u% l8 B& H) R5 M6 x2 C
6 l* n0 G8 n/ Q) X! [: A* s; I$ P
9 z3 U/ R: @7 |1 \8 ^1 A' W& E
, N& {4 l( v, c: I; E0 t2 s F8 h- neai_classification_init(knowledge);
复制代码
6 S! b) G c: y, s初始化的时候,需要以这个数组为参数。* w0 T" q8 [ s: U& y+ M3 P; s) j( j ]! @
! E( g+ d. u1 A之后我们在定时器中,采集到128个数据之后进行预测。% x) [& v0 V" R$ C4 ?
. v: k9 K: j8 Z" l2 Y- float IRD[128];
' R3 v5 k" j ?+ x" F - int i = 0;
2 ?, X! K4 r5 G% L j - int LeranTime= 0;6 m" ^& a5 S3 L+ W: \
- const char *id2class[CLASS_NUMBER + 1] = { // Buffer for mapping class id to class name0 I/ y& I0 t( ]. n" k3 C
- "unknown",6 @7 ~ v$ o1 a$ n7 |% @
- "zhongzhi",
+ s1 j2 W) L% @9 m2 t f - "Error",) k' Y1 X1 B/ X- M; f
- "xiaomuzhi2",
$ [; M4 T1 z+ a$ Z- [4 C - "damuzhi",& ^3 z# n" Y( o7 j
- };
$ z! z1 k0 n: v# N - float Output[4];
: h0 P& U+ `! c# h2 e- p6 h3 i - void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
) [9 ~2 ]+ k+ V# y/ T - {: W; x, P( w' o& Y
- uint16_t yuce;0 w% \" q& f* l" c
- maxim_max30102_read_fifo(&red,&ir);
Y! V( I0 F2 d# T# y/ G* x. ` - IRD = ir;
& s% k8 Q2 h+ A* X' [3 V3 n - i++;
5 [$ p6 h4 ]; V - //printf("%d ",ir);
) H, \' M/ @1 Z! V3 c - if(i==128)
7 E1 _$ [/ \; X' |% K3 o - {4 q: E* j$ W) z7 @4 q6 g$ ^
* @, j- N+ ]7 ?- 1 k* c M z, p' I: U9 B; U8 s
- neai_classification(IRD,Output,&yuce);0 M7 [) i/ S% d; @; _- v* s7 G
- ! S5 O; O( t8 r" h( J( p
# S. {# ?* `0 N+ O- printf("\n\n\n");
5 x' ^' Y: {# M; r" a4 e4 B - printf("zhongzhi:%.2f\r\n",Output[0]);' ?2 x# b% \3 {; s- m! I1 `
- printf("Error:%.2f\r\n",Output[1]);3 V4 B$ p( V- z# g; k
- printf("xiaomuzhi:%.2f\r\n",Output[2]);
e4 `$ j0 a2 l' e" E - printf("damuzhi:%.2f\r\n",Output[3]);
8 n$ \/ o9 Q& E/ G) S7 N$ ?) b# q - LeranTime++;( g/ L6 e1 e- P$ Y) D
- i = 0;
]- @3 D' C( r+ D/ Z r$ X& p - }: S9 @( e. \# R$ Y
- }
复制代码 : K2 v1 Q9 i) z( w1 g# x# S' m
这里的 预测函数有三个参数,第一个参数是输入数组,第二参数是输出数组,输出数组中包含着对于各个分类的参数预测值,第三个参数输入一个指针,这个指针会指向预测最大值的索引。$ t. O* E f, u0 B9 j
* W# z" \% F+ `4 f, Z
, ^0 y( @* @' e( f; `+ d6 t. @; [, ?; O
烧入我们的代码,可以看到,空置的时候,Error的预测值是最大的。1 F$ N: ?6 ?, Y2 U" e
# L, @: m$ Y/ {; |
+ T" h- k# \* F$ f
. V( {; i8 O( ~) s5 B9 j- G
当我们放上中指的时候,检测到中指的概率是最大的。
. Q! x9 H. D% B5 b+ I( I3 F+ D1 f& A6 ~% [/ `2 B' m9 `
! _1 b" n0 \( m: v; h# W% ?* {- S" V7 z4 n8 H9 o$ y
小拇指也是可以正常的检测。3 I# z! O: ]3 {: E- ~# g R
* p# U- j) n' ^7 Y: j
( k3 y, l2 f2 [7 g& J7 I t: n
9 i1 y, E! E/ C转载自:电路小白
2 v2 ^7 n' c/ a* ? p如有侵权请联系删除; ?- m4 [! z+ t, P7 M
' w1 ^; B' ]) ?4 Q+ z1 Y# z
- l0 ?" r9 f% ^; P2 N
- W( T. e/ o9 s- q6 \
( v* k! X5 ?5 l4 V: n
|