用该传感器判断是食指还是中指还是其他指头。0 L3 A. N2 Q9 U
# a! f3 l1 `- k- _6 Z8 T对于我们的三个指头(5个也好)本质上是一种多分类网络问题,我们将输入信号划分成不同的分类。' T4 P. S3 [5 f
小拇指$ i) P( F8 x& O: C6 s8 a* i
大拇指
9 e/ B. g8 g. |3 |5 g; ]. e9 D! B; o" f中指(后来用了食指方便)
2 X, M7 x; G" `. f3 M" |没有指头(空置)
( H7 {. O& U2 o- X9 R- I
9 F- U% X4 \ K; a* S9 h9 d因此我们利用多分类神经网络来实现判断功能。
6 T Q; d# f1 W3 @) V: z' m: A! K* |0 W* K4 c9 \
- 3 ^" p1 I6 ~: q# [! F0 P; k
- int i = 0;; X9 R" W( Q+ m7 a' U" j5 P. Y
- void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)5 T; K' _& \1 G/ V1 Q) F$ l
- {
4 Q/ O6 u/ Q$ c( r; r: \4 o - maxim_max30102_read_fifo(&red,&ir);
& x, [% `5 T/ m, g - printf("%ld ",ir);7 z4 h# G! X' D. l* q5 u
- i++;
; N; e/ E5 T7 z/ s1 r2 Z1 C# c - if(i==128)2 G8 d$ U) L: c- X0 ?: Z1 [
- {
' }7 b- Z# M+ i* Z; |8 `8 B" e4 W Z - i=0;
0 m9 c) y8 p" m+ X - printf("\n");6 p3 P: R6 f: Q( S, h
- }
& U: v: l) m" k - }
复制代码
( G% o R+ j) }信号的输入部分则和上期一样,100HZ的采样率,128的采样长度。
0 N$ O2 w* ?1 G9 N- }* x- V. H+ j( S% }9 Z
% `/ G( H9 t) a# n
( \4 P! K, C' D, d
创建一个n-Class n分类神经网络。2 F3 K& x9 j9 t6 F, B* ^ w6 f4 t
4 c$ E0 [7 @- S! [2 P
: o, e4 w' ]6 H/ a) @
/ t& _4 ~6 Z3 b. O其他设置都和上期的保持一样,使用通用一轴传感器。. X! I" ]1 S: [# D& P- | y7 Y
4 F3 F, x. p, o9 m! f0 p0 p
( Y* v- t* t4 J" e g3 x9 A {6 O% V: ~+ `1 J- M
但是信号输入的地方,我们利用串口导入各个类别的数据(这里是不同的指头)
" L3 G: v3 s; }3 J8 h; l# n. U/ K& M
( N" j; b# Z. U/ p9 e' @
+ B7 [" u( d0 s. s0 m, S& h! b4 ]) [需要注意的是,这里的标签即代表着我们的分类,不像之前那样子可以一个类别下面可以使用多组数据。
1 n; J m M+ h( @7 H5 G: D
# Z/ h9 u% [+ P& T2 V8 D
7 a) I) d. J7 K/ N+ i: @3 r( r6 C
$ B$ r9 m* Z+ p8 O$ d% k1 Y训练我们的模型,这里可以选择我们的分类(其实这里我觉得要是把某组数据能添加到某个分类就好了,这里让我研究一下)。
' n, ~/ z( l) ? E2 i+ |% ^. b1 C" B7 |$ |5 _
A( C7 m0 {! V8 n P+ w7 {( t9 a5 h
" T: W* s5 q: [. A4 }+ D, p
训练好我们的模型,这里可以关注各指标。
/ {7 w0 U9 Y" }: n' ?
6 N2 R! K% I( D7 U9 l& Y7 A: @接着就是验证我们的模型,验证的过程可以参考文章开头的视频。
: G, ~4 F7 W8 ?+ B1 V4 `8 c6 m1 {0 T- E" Z
3 {% T! R& c* v* X. h# i0 K- D1 G
7 o" b" Q! ~- Q2 J9 S部署完我们的模型之后,查看生成的.ZIP文件,其中相比于异常识别多了一个knowledge的头文件。
2 K* E( U D$ h2 X6 t" b0 F3 Q
/ j& d( ~' V; m5 a9 V
) S3 Z4 D4 y! Y* G- H% L& ~9 R6 a$ `* u* ? l1 w% w
这里我们需要libneai.a以及两个.h文件! `( q, o' q1 G3 o! g
/ R3 @9 Y- g( Z; tSTM32中用机器学习实现正确率99.95%的心率异常检测!
* D$ y G) J7 B# N3 r: M% u0 L& Q* V7 G6 T1 f; R+ ^$ u+ T
怎么导入文件请查看这篇文章。1 M* D6 i* R! [
& p, P+ l: _" U+ {& q# I
9 R T* _; d& \! C ^8 E+ f: b' w0 X1 P( d: x6 |
初始化函数中,我们需要导入一个数组,这个数组就定义在knowledge.h这个文件中。
6 L# V: m- F( h3 g
$ a+ }0 U9 i+ n4 E
+ U; X4 R" o) Z% r
: M' O8 C0 j/ s
- neai_classification_init(knowledge);
复制代码
! h3 l3 x; N; G, N+ U* p& U初始化的时候,需要以这个数组为参数。
6 y, C: W* W: e0 E- q* c+ K, Q' k7 O" a4 k
之后我们在定时器中,采集到128个数据之后进行预测。
- m& t# \2 h/ y. \
$ [: U6 q' B U4 q9 O3 Q- float IRD[128];
4 [; d, k9 H9 o: ]7 ~8 g( ^ - int i = 0;8 U4 K) I B! I/ c" N# Y
- int LeranTime= 0;
3 L9 c5 \- ?# z- N - const char *id2class[CLASS_NUMBER + 1] = { // Buffer for mapping class id to class name. ]7 _; C" D( V
- "unknown",
- A+ h& A) E6 i1 c - "zhongzhi",
0 R4 n' V7 T2 y+ @1 e2 ~ - "Error",
: I" {# ]" r b8 K! y ~9 V - "xiaomuzhi2",
b# z8 l: ]5 |) E9 ], [ - "damuzhi",3 j3 k9 r3 A9 `0 O. W' P) \, Z; I) b
- };0 a m8 F& S- ?' w2 E/ y
- float Output[4];
0 Y- A! l# P' g3 @& D - void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim). }4 e5 A' w9 a) t8 v
- {! C% [' {8 `. r) x* D" \8 K
- uint16_t yuce;
% N5 F+ R0 i, W - maxim_max30102_read_fifo(&red,&ir);2 \2 {0 v# J+ Z5 U3 B
- IRD = ir; p4 y& t. I( |0 t
- i++;
% G* ^) S0 ]5 q- F$ v) r - //printf("%d ",ir);
8 h/ @1 u, z: E - if(i==128)2 i. c# A/ b$ o( `
- {
! O) X, Y- T& e) F9 a) n3 [
/ E5 i" P5 g! \; S' k# f
" L0 ~; U* H# ~- neai_classification(IRD,Output,&yuce);$ d$ V0 l8 f2 z9 I5 [
- " |" a- Z+ b; O4 F! P* E) R
3 H7 P0 \* F4 ]3 [0 N* P3 N5 f- printf("\n\n\n");
" n: N2 r# t3 ~. ?1 ~ - printf("zhongzhi:%.2f\r\n",Output[0]); ?( \* ^, {' t7 `5 o/ {1 h7 p
- printf("Error:%.2f\r\n",Output[1]);" C( k( j2 K' ]# l
- printf("xiaomuzhi:%.2f\r\n",Output[2]);' g9 _9 U4 a8 Z8 _ z
- printf("damuzhi:%.2f\r\n",Output[3]);
0 u8 U n. n ]% `/ z9 K. o o7 ? - LeranTime++;; d6 k. @3 F& i# M/ x' A* [8 o
- i = 0;6 g5 u( E( ~ ?
- }, L0 Y% z& i9 a
- }
复制代码 F$ V! _1 I1 j
这里的 预测函数有三个参数,第一个参数是输入数组,第二参数是输出数组,输出数组中包含着对于各个分类的参数预测值,第三个参数输入一个指针,这个指针会指向预测最大值的索引。% W4 I( C& ?" n' E3 w5 B' K; C
1 w" [' x1 L$ N! Z& b
, t- Q3 J: {1 E. P
6 ]" a: A1 W! R. Q5 z; X
烧入我们的代码,可以看到,空置的时候,Error的预测值是最大的。7 a2 z" t9 N# |
8 W/ B& z/ t7 V4 ]) A
, C& Z `7 @8 _9 @" h: x1 {) t
3 Q% O7 l8 C) r3 E; C( a7 `当我们放上中指的时候,检测到中指的概率是最大的。
2 Y4 L- D# B& i) G
, O+ f$ K6 c" E9 {+ \; b' j
# `$ i6 ]: E" L" x `& {. }/ I
8 {2 _4 O* }. d6 P9 M5 \& M小拇指也是可以正常的检测。* o. n! o' @4 H; p
- j3 q" |# o9 w* t# ]; H2 y- h Q; Q( n! r5 f
5 h" ?9 U9 [( X0 Z2 [3 [5 S E( B
转载自:电路小白
( p; j- K" { N- L5 V0 I( X* z如有侵权请联系删除
6 P# g3 o. }. c: ?% s- u) I' p3 A$ V( {2 c
( K! C' r+ L, K' K( S2 {+ ]
0 K0 n' L6 t w' D8 O B/ P
5 Z A: {+ U8 ?& p' @ |