用该传感器判断是食指还是中指还是其他指头。
1 @& H4 o V# u9 _ w/ T& h# W7 y: Y/ J% c9 T( H
对于我们的三个指头(5个也好)本质上是一种多分类网络问题,我们将输入信号划分成不同的分类。
: C9 q2 j1 G; @' f小拇指
6 D; `( x3 ]- p5 f' Y, c5 h2 X0 K大拇指, O) D4 T1 [& G1 T/ w
中指(后来用了食指方便): I' q' e! @5 X7 p& _! l# m7 {
没有指头(空置). m* z& Y) W) |/ {6 t' [$ V# @5 T
9 J9 F' _ X2 Z) p
因此我们利用多分类神经网络来实现判断功能。6 W5 |; H9 U, c F& p( t
7 T, S% ~8 R" J
$ ^1 m; S4 f( v4 B0 ]3 J- int i = 0;7 f: I6 r4 L9 N* Y |
- void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
" @- D. }0 y3 P0 X1 f/ C - {9 v6 j' s3 V/ h5 [
- maxim_max30102_read_fifo(&red,&ir);" ~% u" ?' q5 U5 W; g& a/ v: J, m( O
- printf("%ld ",ir);! k$ @) z1 p; o: m9 |
- i++;
1 q8 d* c5 Y f# l3 P - if(i==128)$ `* a8 W6 }% h
- {# i. A7 \+ t" J5 P& q6 ? N
- i=0;
" O, S* W( k1 x+ u - printf("\n");
& {4 C& {; S1 W! L4 j1 I - }
! d& J( J( s' W |) x: } - }
复制代码
" g# b+ V# w8 M8 [" Z& }信号的输入部分则和上期一样,100HZ的采样率,128的采样长度。, ?) u7 c' l) ^! p3 L0 s# b
6 O) [6 x* {# F, D& O
- K6 C5 z% `' I6 E- z8 T; }
. g( I5 _4 m. T6 D' N! ^ X
创建一个n-Class n分类神经网络。
1 K( n4 ]4 \; p& [$ z0 A: F( F& l
7 H3 m4 p, [" @
2 T1 [( o, J; o' E% N' ~
* N1 ~; R( W& g" m其他设置都和上期的保持一样,使用通用一轴传感器。# S- ^4 B: P6 ^8 q& }% c* ]( J$ C
' F. t" S9 d2 e0 q
. @" X1 q$ F% @& l/ e2 m+ p, p" x
但是信号输入的地方,我们利用串口导入各个类别的数据(这里是不同的指头)9 K* m& f; h1 o' i( J: E0 ^/ n1 r' s; }
* |! c5 z2 z' y! K2 M
0 r4 J* U# p7 H' X/ o, g9 \' ]- b: D# W! c T5 j$ |1 F5 p
需要注意的是,这里的标签即代表着我们的分类,不像之前那样子可以一个类别下面可以使用多组数据。
5 e3 z. H. |; b7 L! D3 I
m/ r0 o- z E, c: G# _6 o
5 }: `5 ~" T6 n3 g$ E2 {$ }: ^( A. f) ?+ b, `1 h
训练我们的模型,这里可以选择我们的分类(其实这里我觉得要是把某组数据能添加到某个分类就好了,这里让我研究一下)。
% ?+ O5 Z7 j* Z2 L! O0 Q4 @# _/ f# M. o y0 Q3 ]1 n3 a
# m* w% d. _7 U8 G! W+ |6 P$ D0 Y s7 Y8 i1 k; {
训练好我们的模型,这里可以关注各指标。
( z4 o1 h6 q/ D
+ E6 C: Y% k' H# E接着就是验证我们的模型,验证的过程可以参考文章开头的视频。
* Z# T1 _2 c' n8 t3 ~0 Q
0 e; w! Z5 |. C+ X9 c
- B' s8 S2 l" t2 I' e
) T. a; x/ W2 K- J! ?部署完我们的模型之后,查看生成的.ZIP文件,其中相比于异常识别多了一个knowledge的头文件。, w/ E$ N" S+ ]& f6 W
; U6 S$ g: u/ |7 c6 ^+ i7 T i
# t9 r( ~9 b+ n" k+ f0 ]) _3 Q# C `% X0 B% T2 P) e
这里我们需要libneai.a以及两个.h文件
* r; w2 P) `, \5 V# t9 ]1 p: k" {: W4 ?/ m$ i
STM32中用机器学习实现正确率99.95%的心率异常检测!
6 a; f2 m% G, l9 d
1 Z$ Q; W0 B* }! R E- j- q怎么导入文件请查看这篇文章。
; H5 X: t, ?5 p) _
% j- B% X# `6 Q9 i X- B& k
! o2 e3 b, J) i! X+ h
1 X5 q) y" c( Y# x初始化函数中,我们需要导入一个数组,这个数组就定义在knowledge.h这个文件中。! G/ K: F# e3 F( B O( V5 T
( q, R% u; b8 {/ d, ^
9 j6 N4 M F5 W0 U4 ], H2 G- o% q, W' m7 D' K$ v
- neai_classification_init(knowledge);
复制代码 4 e" [. L9 N8 ^+ z$ |
初始化的时候,需要以这个数组为参数。
% K$ n0 ~1 @ g, g. H) G" |/ ]
. Q; u+ E8 o& M+ @; P% Q2 p之后我们在定时器中,采集到128个数据之后进行预测。. v# j1 m4 M5 ?9 d4 j a5 A9 {
. g9 y& s' ~/ j- float IRD[128];3 z6 Z5 } A6 P# I! E2 F+ w2 d* E
- int i = 0;$ D D& J; y$ @+ _ b' r* D
- int LeranTime= 0; ^+ {1 {$ M+ k; q5 P2 M
- const char *id2class[CLASS_NUMBER + 1] = { // Buffer for mapping class id to class name5 j4 b2 `; g: ?# L$ \( T
- "unknown",
, e9 l9 P* E. ~7 I0 m7 z5 M( e - "zhongzhi",
; L5 S' d. y4 x h" t- Q - "Error",3 k' b& ~( Z! H- r
- "xiaomuzhi2"," e, l2 f# c3 S t# e" n
- "damuzhi",
# G- ^! s- q- l8 n4 | - };: S9 S- B; e# r
- float Output[4];
) m3 `' D8 Y* [4 A - void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)$ I; Z3 e. R' A
- {+ k8 t8 ^4 }- [8 Q5 \8 U4 s$ o
- uint16_t yuce;
4 u2 A7 O- r9 T. ^& y z0 c - maxim_max30102_read_fifo(&red,&ir);# R, U( \: x. C
- IRD = ir;
9 o4 p8 W+ L6 |" ] - i++;
# `) X( O8 e( i6 C& s+ i - //printf("%d ",ir);+ ^% _, M2 F( I9 j
- if(i==128)
$ j. j |" ^* n, t4 O# m - {
3 ]9 h4 s8 v6 F$ w9 a" x; m) l
# D/ I" L0 A$ c! V- : j" g, T. p L4 `
- neai_classification(IRD,Output,&yuce);
7 J; |2 y" L+ c2 P - & V2 [7 b h" \' O
" F8 N- H, f* g- printf("\n\n\n");
5 K) ?, q. @4 v* r4 N4 M- O - printf("zhongzhi:%.2f\r\n",Output[0]);& S1 V$ m! l) G8 D [9 Y. N) w7 L
- printf("Error:%.2f\r\n",Output[1]);- ]$ `6 e4 |* L" ]: T! v
- printf("xiaomuzhi:%.2f\r\n",Output[2]);
& e( f, W# e' X/ b! T8 x& @1 @" G - printf("damuzhi:%.2f\r\n",Output[3]);+ L9 q- _& } ?* j
- LeranTime++;# U' V8 C' c9 g
- i = 0;7 P1 F0 a; }) K& A, O1 @
- }
+ n1 L1 y p$ M F/ ? - }
复制代码
5 |: }) u; V" P" J+ r3 u这里的 预测函数有三个参数,第一个参数是输入数组,第二参数是输出数组,输出数组中包含着对于各个分类的参数预测值,第三个参数输入一个指针,这个指针会指向预测最大值的索引。
1 i! m, ~ s! Z, q# a4 ?7 ?1 W
4 _6 Q$ s3 Q: M; z" Z
* R" i2 u/ Q$ R9 b7 b
1 U( K* o1 {' l" G3 u! L1 B
烧入我们的代码,可以看到,空置的时候,Error的预测值是最大的。
$ Z1 H( q) x# M, _6 J9 H/ h( f7 @1 n0 {% w
$ R+ d/ ?' f# @- X8 V9 |
" K% N5 L5 q$ Z- R7 T当我们放上中指的时候,检测到中指的概率是最大的。1 a; C- i2 T) x% G% R' ~. F- f% V2 m
O% n- z; Z* g/ i" [
1 E* j- s5 r: \* L/ E3 h2 ]3 I
0 D: M4 Y' [8 @- V& f% c
小拇指也是可以正常的检测。6 P c6 F4 o' x6 G+ V/ o
2 k L- B9 R& w- {/ ^' T
q6 k! ]' e5 n k' L( {* C" s [" ^+ b$ G0 {
转载自:电路小白8 a) }+ s u( [3 h# ?; Z
如有侵权请联系删除1 F+ r* e; l0 ?, s5 r
$ n0 i, ?, u, u) A* P/ ~) D
! X# m) [! q# \. w3 n
, M: R. e7 V8 W% o% k7 M1 \/ a0 \, [
) M5 D% S' e. q+ M$ x- Q; T a3 z |