用该传感器判断是食指还是中指还是其他指头。
# y# [4 `- a' v& z; r! i8 i8 N# Z' U$ i7 K7 Y
对于我们的三个指头(5个也好)本质上是一种多分类网络问题,我们将输入信号划分成不同的分类。
/ Z7 ~1 @( d; h& |2 p1 w小拇指
: H! j5 F# z9 @7 W大拇指* N, }2 ~3 Y( m; w/ s+ W6 D" x, W
中指(后来用了食指方便)
9 A! O9 }- y- W3 f( j没有指头(空置)
$ P- Q2 C* P$ m. a4 G) w' y$ c
7 @# b2 D2 O6 {因此我们利用多分类神经网络来实现判断功能。
/ }8 y' A. h. a6 h g% q
* R$ R4 c/ R- B2 v. b* j9 g! Z- 8 Y5 u# t( T9 ^
- int i = 0;6 L/ B" F8 e# p% D2 c
- void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)4 r# C1 \: [4 B1 R0 I
- {5 [! P) u) m; d, n
- maxim_max30102_read_fifo(&red,&ir);, d6 s+ ^# M5 z# D
- printf("%ld ",ir);
7 ?/ W& w1 _/ J5 j3 Q - i++;1 a2 X! W- D4 X+ |4 i
- if(i==128)
7 M7 e9 R" c u$ ? - {( _. j" J, x1 Y/ f: V) U
- i=0;
3 ~2 \' w) ^# l* T5 Z - printf("\n");
% k4 A' U6 k7 e, ] - }
9 g, y1 G4 K8 U/ U1 ?0 w - }
复制代码 ! F0 _6 o) V% W! Q
信号的输入部分则和上期一样,100HZ的采样率,128的采样长度。5 }, u. C2 \4 {5 O" I8 a3 s
: @) x1 q B' p: H: x2 D) |
7 U" N: Q$ s. Y C$ r3 D
6 X) `- `: y( J2 P1 g创建一个n-Class n分类神经网络。
# L+ T& A7 j- P/ ]* V4 H$ J) C0 G! V- X2 M: M& N4 K
+ T# R! [6 U: t' g! c3 V- f0 p2 M8 f
其他设置都和上期的保持一样,使用通用一轴传感器。
% v; w S% [+ s+ r9 z. k8 Q$ ]& H; e9 H b6 o, t- v4 S6 E1 ~
2 `! S4 t9 m% [2 n2 L5 l
1 |# T" K0 y% W: r但是信号输入的地方,我们利用串口导入各个类别的数据(这里是不同的指头)
! @7 a1 M4 ]4 b# j
$ }8 R6 L# ~6 @" K+ g, C4 [4 |! J: R
) D9 k: j5 r. S8 Z7 Y; H# g# Z
q) w6 Z9 H$ D6 T: M; W3 R2 c% Q
需要注意的是,这里的标签即代表着我们的分类,不像之前那样子可以一个类别下面可以使用多组数据。
7 L5 O {1 `! P7 P7 ~ o8 f" w: P; c3 x: D$ m
, c& Y, w8 F* d
]: ]$ U; i$ M: `
训练我们的模型,这里可以选择我们的分类(其实这里我觉得要是把某组数据能添加到某个分类就好了,这里让我研究一下)。
, L7 P% `0 p& I: u( ]0 t; l+ f" W% Z2 s4 U1 j! |
% B0 d, J I4 k4 ? ~+ b) F
$ {; H$ ^7 e, q$ u
训练好我们的模型,这里可以关注各指标。3 N8 T9 R: |3 ]! L
N: S) U _ t9 \: S接着就是验证我们的模型,验证的过程可以参考文章开头的视频。
5 M5 j/ y6 z; F; [
7 R% Y4 [/ D! I. @( T& o
/ K3 ~7 ~* b8 ^2 `5 u) f/ M3 j. e
. n' Q c, B6 H+ \& V' {/ A部署完我们的模型之后,查看生成的.ZIP文件,其中相比于异常识别多了一个knowledge的头文件。
$ B% ^2 W% R( ~# O5 o: ~3 P7 [* d4 T! h) h+ C+ b7 R0 s% O* W4 t
& R/ {, E# x* K+ M
# k9 Z' R3 e6 e) K0 E6 w( A- y5 H" B这里我们需要libneai.a以及两个.h文件
1 ?7 c2 W4 z/ C, K9 [+ e
, P$ A1 ^, n3 ^& L( HSTM32中用机器学习实现正确率99.95%的心率异常检测!
. X5 [- W9 ~4 |+ b8 c( _8 [6 S% X% B$ Y9 P2 z4 c3 ?0 s
怎么导入文件请查看这篇文章。
$ [# j8 T9 G1 {; K2 K& z& g$ {1 Y; W5 e& e2 G2 w
0 x% f9 Q+ x" R5 C5 f0 k) F' \( \2 R# d5 g( @6 N. z: m9 d! N' k
初始化函数中,我们需要导入一个数组,这个数组就定义在knowledge.h这个文件中。
) u [, d" L& E' Y4 ~0 U, L5 K2 R8 j; {- w
3 ?5 l9 v, c* N( J- k: h, l
2 }4 |7 y3 s3 }8 M2 N( f$ @- neai_classification_init(knowledge);
复制代码
# \% G5 i' W4 y7 {# B8 l0 `" t初始化的时候,需要以这个数组为参数。' m/ y# a8 r1 b; j, {- T T
# C0 w# Y) E% X& O: ]. D& l之后我们在定时器中,采集到128个数据之后进行预测。
3 n0 n5 d3 i+ r) i& j; H" P5 D" ^+ n
- float IRD[128];
2 a5 _2 A5 O+ ~2 i( | - int i = 0;5 y }, U- T( l( J( P4 K
- int LeranTime= 0;2 |' H) t' g P3 K: X
- const char *id2class[CLASS_NUMBER + 1] = { // Buffer for mapping class id to class name- ? c2 w' M% ]# u. a( o* v
- "unknown",$ G/ s4 }- ^# N) x) M. V0 }
- "zhongzhi",
& w$ M) o9 N2 c( U' b: | - "Error",
* A9 h3 j# {: r - "xiaomuzhi2",, K% ? a' s8 w
- "damuzhi",2 Q+ @" a8 a+ P @* w3 G; s
- };
) b9 i7 `0 z ]% j - float Output[4];0 [7 {4 {( f/ D! i6 b
- void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)0 G3 a5 v5 E7 @
- {2 z1 c6 i4 w$ }# K+ F: I& Y
- uint16_t yuce;
+ I6 u, G/ P6 V) |! g9 c7 w9 W5 M1 N - maxim_max30102_read_fifo(&red,&ir);
( m" m% K* l0 D - IRD = ir;+ ~! ~3 j1 B: b
- i++;! h, `$ i+ C6 p- r0 V% f
- //printf("%d ",ir);3 J5 y( j2 K" O* m( r5 w) {
- if(i==128)
2 H! x: T* V k) n' D( _ - {
" c }. P/ q8 {% G- q( {! r w/ @ - ; S6 t/ _2 B+ K. j1 o0 S2 J
' v, m2 E. h; Y- neai_classification(IRD,Output,&yuce);
5 E: A" r( A0 z0 v+ Z# x" E# h! h - + u$ m# C) ]2 u
- " o. X0 b, k3 {+ X c7 o
- printf("\n\n\n");) w$ J/ Z4 s k* }
- printf("zhongzhi:%.2f\r\n",Output[0]);
: r2 C1 \4 L2 t. w/ G - printf("Error:%.2f\r\n",Output[1]);
1 b; ]& ?+ T5 w" O - printf("xiaomuzhi:%.2f\r\n",Output[2]);
8 O, K/ K" i. r+ T1 `; A' } - printf("damuzhi:%.2f\r\n",Output[3]);
/ g+ Z; \+ l+ @3 O. g4 v - LeranTime++;" w% Y+ [2 X+ }# v$ J( [8 y/ c( o
- i = 0;
1 ]. C% f% ~5 P2 Y, Z& D - }0 e5 a& Y, J) j' S. q# o, I3 v6 b: `( ]
- }
复制代码
: q0 X6 Z9 M6 d* q这里的 预测函数有三个参数,第一个参数是输入数组,第二参数是输出数组,输出数组中包含着对于各个分类的参数预测值,第三个参数输入一个指针,这个指针会指向预测最大值的索引。
; c. _; {) }$ [! D
- M8 h g, g$ E( I$ _' r2 K: d
' p& ~! n7 k1 h
5 ?6 B- h7 N* o {! i" o1 Y烧入我们的代码,可以看到,空置的时候,Error的预测值是最大的。+ Y Z t4 T& q% @, v
% P; ]4 c6 m& H' | V! Z0 c
i6 J) m" E+ j0 D" |# Y# C' Y% x; e& O
当我们放上中指的时候,检测到中指的概率是最大的。- M) G& Z: f( Z$ a# Y3 a+ A' l. Z5 d
0 ?- @& b7 G# c1 i' k
$ k" i& o3 J/ m: K7 y& ]5 p0 a {6 K/ B: U
小拇指也是可以正常的检测。
! m% f: s" g; e) N9 x+ L: m
6 C/ U* o# ` v' T, M' A6 M( N4 Q' U0 }5 Z9 K5 Y+ ~0 A1 ?
1 l' P* \- g J2 j6 y
转载自:电路小白8 Z4 ~/ }) X) _! g! w$ t+ _; _
如有侵权请联系删除+ y7 J0 P% X8 `9 {: I
6 l+ x2 d$ P( H5 ~0 E2 @8 Z3 ]0 w- @* @) _* F; f
9 G7 Z0 M: u. x: F! K
! E6 j/ T% ]9 d% Y4 n; h |