用该传感器判断是食指还是中指还是其他指头。
2 a9 w5 r) {. B1 T
9 y$ [& T) `! f; G对于我们的三个指头(5个也好)本质上是一种多分类网络问题,我们将输入信号划分成不同的分类。, E" N; |* r6 I
小拇指( D9 u1 K9 Z4 h! d5 v" Y& U
大拇指& h( z2 _4 v: {- R4 c- g
中指(后来用了食指方便): `; ?. h8 n j( Z- s+ m; f3 f
没有指头(空置)
: X. o) R' \" N9 U1 d, c) ]. y& j9 ~! S: w
因此我们利用多分类神经网络来实现判断功能。1 j9 P* ~, e! v* C5 ^1 y
1 I7 h5 S* \ g; \. C q+ A
- ) f2 c/ }( Y+ b" f
- int i = 0;
0 o" E2 @" ^, `7 l- E! X% s( m - void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)( b, Y% T+ i4 H5 P
- {3 w, G8 \ \ a" _) }; H0 L
- maxim_max30102_read_fifo(&red,&ir);
* S, J, d9 B2 B \, C; V4 o8 a6 h4 D - printf("%ld ",ir);0 d% @1 z( I1 C- @0 G! o$ @
- i++;
* t) R N& i# f4 r9 j# @% f - if(i==128)
1 ~2 u: Z! n) o/ z# | b2 v - {8 K/ M s0 q0 N7 K/ [
- i=0;6 ~6 L3 |9 V* W5 T! y
- printf("\n");
% o9 o! o- B( p P/ O2 o - }
* G8 o" t C1 F5 d - }
复制代码
: g5 {! ^( T- C$ O6 w- H信号的输入部分则和上期一样,100HZ的采样率,128的采样长度。
& r. w* x1 R# b! y" b5 E, ]/ X0 A7 ]( f5 _; j L
# s: w/ y7 U! T$ ~ {8 E. N6 W+ U6 a% a s+ Z2 H
创建一个n-Class n分类神经网络。
+ ^+ V$ p. n7 ^
: f# G1 z$ }9 P$ L
/ M, r! E+ c9 q2 z! R( }9 \7 q
, I9 [3 \4 W }- c其他设置都和上期的保持一样,使用通用一轴传感器。$ a' @9 l3 H: ~8 O& t) e# k
- \# q1 h3 s- s. \( L* o5 _' P% q
t( p! m2 L" x+ b
) G* s8 R2 q0 h+ O. l但是信号输入的地方,我们利用串口导入各个类别的数据(这里是不同的指头)
8 q2 V$ s+ H0 T4 g+ }4 A# X
/ X& b2 V( T9 O! ~. q1 u# C
" L. l/ o4 Z( [" Z0 ]: {/ }& u- ^3 {, C9 ~ G! O
需要注意的是,这里的标签即代表着我们的分类,不像之前那样子可以一个类别下面可以使用多组数据。1 F5 C6 d: r6 ]* N
( Z( x4 x* S; [5 x% ~! t
3 d! c1 V/ P9 A4 R% L9 x0 a8 H) P3 G- f1 N9 [: g V* s6 m; q
训练我们的模型,这里可以选择我们的分类(其实这里我觉得要是把某组数据能添加到某个分类就好了,这里让我研究一下)。
3 O: Y" y# M9 k- d! n' B4 i* T' i- n2 |
5 c$ K+ U8 K8 V3 y
6 D2 `2 V: d$ ^% u+ |训练好我们的模型,这里可以关注各指标。
% ]. d' ?5 a# y- w8 A( h- {$ q9 ^3 O# H; _
接着就是验证我们的模型,验证的过程可以参考文章开头的视频。! ~1 {+ L: g$ ?6 H& g: K
/ ^( u3 _( O0 s" }) D ^$ l; z
) _ H1 s8 p, L O* H; z! |0 l
# r6 y* u$ @+ s5 ~/ J$ U部署完我们的模型之后,查看生成的.ZIP文件,其中相比于异常识别多了一个knowledge的头文件。
9 [" B+ q1 X& k3 i1 |8 W9 P3 h( u2 N% \( j9 O0 M9 C
1 B& A% f) g; ~7 q5 F+ g
. k# l4 w* u& ^7 a这里我们需要libneai.a以及两个.h文件
; V( B- F* o2 C' ?. C3 L: Q& q; d2 I- `& y9 U6 Z
STM32中用机器学习实现正确率99.95%的心率异常检测!
4 a* U% l0 E+ k& i% Y% X9 \1 ^9 F7 ?" B4 Y" M8 h/ d3 [
怎么导入文件请查看这篇文章。+ R! _9 g2 f" h
3 s; H% G6 V# @& s* R) x
& D& a1 d8 |8 r v( ^* ~, t5 W
8 }7 r; d5 G0 _/ [$ H; _初始化函数中,我们需要导入一个数组,这个数组就定义在knowledge.h这个文件中。
( e6 z, Z; T% H! @; c; @+ n @
* Q1 p# r& ~& q: L- R4 D1 ^
9 \' N! g4 J5 i
- h% h# x+ T7 x. Q6 B( ~ Q( n
- neai_classification_init(knowledge);
复制代码 2 J( t, f+ z: V0 m9 D0 N0 u
初始化的时候,需要以这个数组为参数。
3 \/ c" z# k% w6 \- l7 l2 y5 [7 z% u( }- l6 p6 m$ z5 ~1 t- g! Q
之后我们在定时器中,采集到128个数据之后进行预测。
" j; W1 W7 l+ C" u0 g3 Z
}# C$ Z6 C; `' }7 ], o- float IRD[128];
0 r0 l5 D2 _4 d5 ~7 j. M - int i = 0;
4 i, m) `8 G5 J5 Z# p; D - int LeranTime= 0;
/ p0 [9 s6 p/ }) N) K9 R. G1 U - const char *id2class[CLASS_NUMBER + 1] = { // Buffer for mapping class id to class name
) t9 [; b# J2 z* Q! k" L - "unknown",% }+ l0 c) T% i4 `" Z$ w" b
- "zhongzhi",
- q- }! V. C/ v. L" W8 ` L- q - "Error",
" J/ ~7 y/ K& C c9 |$ K( E - "xiaomuzhi2",9 ^5 ~5 x2 C$ ]* M
- "damuzhi",
. Q' I1 |+ \* P* z8 c2 `3 T$ q$ f - };
! [" _$ X6 E/ @, S; I" a& B* o - float Output[4];
4 p1 P/ y2 \( H6 ~# c - void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)# B2 y: l, W' Q3 s: y; U
- {: C4 \3 Z. R) q/ |0 A0 G; k
- uint16_t yuce;2 V, z% d' X$ O. x2 z
- maxim_max30102_read_fifo(&red,&ir);
" x8 t. }0 E( e" U - IRD = ir;
2 g( J9 f7 }# w0 v1 y2 i+ d y - i++;
( P" w W6 M3 _6 I7 _! o0 g - //printf("%d ",ir);
; `8 {- O3 c8 v7 H; C - if(i==128)& X7 H& a# R U
- {2 B' s3 N9 G5 |4 L
- ) l/ \5 V5 {7 i j8 F6 Q* s
7 \; @! O# w4 }0 _4 O6 q- neai_classification(IRD,Output,&yuce);
" \# G" A J2 |9 F7 i - 9 A I1 M: i5 L$ K* P) s
- i& q% }* \: X/ f' |, ?8 V8 N8 Q
- printf("\n\n\n");
: S1 `6 |4 T# e: M( B7 p - printf("zhongzhi:%.2f\r\n",Output[0]);/ F7 y; \0 i% {$ ~4 O
- printf("Error:%.2f\r\n",Output[1]);6 Y' Q& B; b: b# H" A
- printf("xiaomuzhi:%.2f\r\n",Output[2]);
& a/ Q# Q/ k8 Z, H4 v) w4 D - printf("damuzhi:%.2f\r\n",Output[3]);
. Y" @# B; O, V7 P2 v' X$ p - LeranTime++;
: ^1 S1 L- C0 O# Y - i = 0;% V) X7 `3 W" U; U% n# O' r; C( q
- }! \- x9 g8 @% y5 X( b
- }
复制代码
+ T! ?2 C5 I; z* J ^8 T这里的 预测函数有三个参数,第一个参数是输入数组,第二参数是输出数组,输出数组中包含着对于各个分类的参数预测值,第三个参数输入一个指针,这个指针会指向预测最大值的索引。+ S. x1 |3 \8 y
( n% U9 C0 w7 {7 V1 E
/ Y7 T9 A" x) ~7 {. e% u" C2 p5 {- u' f0 C
烧入我们的代码,可以看到,空置的时候,Error的预测值是最大的。+ y# ~9 u( h& C, {
1 K. O" o$ L" E3 u7 R8 n% b
( _* K8 v% d9 t5 c" Y4 ~* `( I+ I( s8 A7 d7 I& m
当我们放上中指的时候,检测到中指的概率是最大的。% O7 D% J# ]& L% D9 F6 F
8 [0 g" ?! I7 a; T4 M
) G5 F! l5 ^' [9 u9 Z
1 [% f) |( r" ^小拇指也是可以正常的检测。
% O0 q, z0 ^1 z3 G; N% } E. t9 ?- ]; ~4 a
8 I; u& d& J3 ^# N
$ t1 j3 J8 }! }( I& z% s转载自:电路小白6 ^) O. H, c/ S$ F! i& i
如有侵权请联系删除
3 W3 O! V V: C/ |' Z8 _$ B; O/ F/ e9 K
, ^: l1 \: ^9 A3 g0 x* o
% @$ r; r) l: p
& }3 c: h$ v! ]9 m$ X8 N* a
|