首先我的数据并没有做任何任何的处理,本来我是打算加一个直流滤波的,首先是效果不太好,其次是我都用上机器学习了我为什么还要自己处理数据?机器学习本事的目的就是节约我们的脑子,利用机器来提取特征,而不是我们自己去提取特征(直流偏置本身也是一种特征),就算我的信号有其他的误差,我们可以处理一下提高分辨度,但是!对于机器而言,这些本身就是他的特征,我们只需要告诉机器,哪些特征是对的,哪些特征是错的!& ^/ m+ B7 M6 w! a
" ~7 J3 q# a3 a$ C; `训练模型方面,我们使用MAX30102每10ms采样一次,每128次采样作为一组数据上传。: T T- [* ^. B( s+ N u9 v
# D7 B2 v4 r; a- F$ ]+ j5 j5 I/ G- int i = 0;
# @: w `" }* S, o8 t6 ^1 Z - void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
5 r4 i+ [9 u3 X - {
1 @8 K' x3 B$ D9 g c/ d - maxim_max30102_read_fifo(&red,&ir);5 T1 g- {- n) T+ I8 j
- printf("%ld ",ir);4 I# C4 a9 D: m9 c
- i++;' i3 a7 u- a/ h j0 U) D
- if(i==128)
( k& y+ [" z$ Q' h, r/ X, ] - {
3 Q% S9 p! F6 i - i=0;1 N! V7 _ B9 P: ]. ]' a
- printf("\n");# U* ?% U2 T; t! ]3 f/ N) B
- }
t% t- t5 e: O - }
复制代码
" G% L2 G) g& g: x, H2 Y- Z9 x这里我们不对数据进行任何处理,因为既然我们选择了机器学习就是为了节省我们对于数据的处理,节省对于特征的提取。 K2 G: {4 G$ m
& t' c5 s9 X7 h8 @( B' U7 d
模型训练1 X: R4 A$ F" K
我们打开NanoEdge AI Studio,这次的项目我们选择异常检测。
0 h" W+ H% R; B' J7 M* q0 c
- I/ \, C& H6 u$ ^
6 k8 b w. c$ R% K3 G2 h* s* f1 X" n
8 {7 t8 X% a) r, }- @5 F9 N- g. _
传感器选择通用传感器,轴数为1,芯片型号选择自己所需要的芯片型号。
6 _3 ^% u' i' V& w- R
- @) R* q$ F* C' M: v2 ^! H* s
4 ~9 h& n& }4 r- T4 G
! j7 X/ g0 }9 Y) }4 a0 i
Regualr signals 常规数据! v. R E" R" s
Abnormal signals 异常数据
6 J, s+ b. R& I) k
* \) W7 T* o5 d- r M D我们通过串口(USB)分别导入正常的信号和异常的信号。
0 ?! P( B6 v, {1 }" N4 Z. r- M
' Q% i5 r% S1 O1 K
, R; l0 a) @, A' |" g( T& y
! t, r6 e+ H& y) g
# Y5 Y1 q1 ?) M
: b) I! ?. E1 K) Z2 [; r6 \! @
数据集尽可能多且广泛并且经典。9 d ~+ x4 d5 J
$ P1 w( }7 u; f( g" U- Q
+ z0 ]9 q, e: y. T3 Z( M
! Y8 t. o" B9 p) L我们总共导入了两百组信号,这些信号包含了大拇指,中指以及稍微靠前的位置和稍微靠后的位置,保证数据集的范围足够的广泛。4 d+ \; E! G& Y5 y
/ u" {, }/ G1 [0 S
# W+ v* r( r9 B, |( g$ a- }
# i. K* |/ D) F异常信号就非常简单,我们放在那里空置信号,晃动信号这里我放在那里测了总共三百多组(打游戏打忘记了)。' Z b$ G, t5 u; b: }5 v1 z- I0 w
: \) H! L. j4 u然后利用这两组信号进行训练。
: L- T$ ~+ l2 U5 b' W& D; P4 [: V4 v3 {$ x0 g
8 N( I; b8 m! q0 V" @- Z
9 b: M( u+ i7 c
我们将异常信号和正常信号全部选上,之后进行训练。
$ S9 T9 [3 j. z8 @- o8 p2 `, }& j0 k" ?3 D
9 q' t _# }$ E6 |, w, a7 ?+ g" A1 @( m9 Z
之后查看训练详情,等待模型训练完成。: @. e/ _3 R- M: C2 k Y
& M2 d* H$ S- @( R' {; T/ \
6 y3 q; i n" d' s
' T4 p$ g: ~0 B6 o( r3 x可以看到,训练完的模型无论是准确率还是RAM大小Flash大小,都相当的合适,接下来我们测试一下我们的模型。; {# X) G! j: f
* n& T" O: k: w% J( l+ t: F) o
7 Z2 I2 @0 R; G. D4 t
; z+ \% H* ?" U4 o% B( @这边可以查看训练过程中的模型。
$ n6 K1 @/ H* a5 L! M5 ^2 e8 k
8 g) O9 Z% c% t$ M
% [! w6 D9 }0 u ]
8 l- Q d- P& [" f8 Y验证我们的模型。5 d' c4 g, D5 O2 q, }& h0 Z
7 W3 o1 A$ Q3 i( l9 W
9 L6 _0 G% _5 D1 H1 M; V9 c8 X2 W& ^: K# p0 l% D
这里需要注意的是,我们第一次导入数据会先进行训练,异常检测需要有一个学习环节。
6 ]0 C" r4 N" S! z a
/ H8 Z" w, A9 p- S- ^( n* E官方的手册中推荐了至少十组正常数据进行学习。
* n* |. L! Z% `) Z+ q9 e- H1 e$ n* y# E8 p7 O: g
9 s* g K2 I- n: @
& O7 b7 {1 n6 E+ K4 o* J我录了21组正常数据进行学习。
8 W& K8 ?8 W/ q9 s- S2 D7 b; K" u5 g, C0 c8 {. W# l& E
然后就可以对模型进行验证。/ `/ s7 w/ Z# L% H4 @& \# |, ^. f
9 s3 _ t: g- k- m& C
4 y, ^; K( a, F8 G
3 u! h8 a9 D2 T/ x
9 L* K6 |: l7 ^: [+ @' \2 D
部署我们的模型,其中需要他的.a文件和.h文件。7 M1 M7 m- Y& J
7 B9 e: U# @6 [: l+ i% t7 q
5 V3 X4 C% B4 a% W
2 d! \4 j9 Q; L; z6 Z0 }6 }, y4 i
这里我们需要使用CubeIDE来编程。因为这里的.a文件是静态文件,静态文件使用keil编程有点麻烦,需要安装GCC编译器,STM32CubeIDE集成好了可以编译.a文件。
* K8 m! y8 u+ o8 T0 o7 P6 _6 n# A( |# L$ m8 ~
' B+ a* X* [+ k [9 Y$ W% d: }+ m4 G4 K/ Z* q7 Z o; K8 F
在属性中添加静态库的路径。6 e+ Y: A2 u& t# U( O9 j' U; C
9 e' i$ t, }; j) s+ n% z
6 `- t6 z0 d. b0 B" ~# z
8 @/ S- O. f# u% a4 [在库中添加路径,我们的.a文件是libneai.a,这里需要省略lib和后缀.a" _9 d% K( }: y0 w6 n/ f/ V- @
! i9 z! B3 p4 H' |
% J+ B8 L0 {, H, p/ w7 q( w) D
% J3 _1 }0 F6 W6 h7 t导入NanoEdgeAI的库函数。% k+ r! v5 Z& ]) M7 d
3 W5 `% [" g6 C6 `
& O! ^% v+ F# S$ Z( a& ]8 i3 q* s3 y S7 D
可以看到这里有三个函数,初始化函数,学习函数以及预测函数。
, S- }1 k! S! g7 f" [1 a- _
8 R; g" K" w$ m4 ^
1 `8 W% V# z0 p定义一个枚举变量用来存放标志位。
! ]& f! c' e4 J9 A& o- MyState = neai_anomalydetection_init();//初始化
复制代码 ; O. T1 n) p& _. l1 Z+ w7 ~6 {
初始化我们的模型。# X ~6 w8 g* u: F J( T! T
- float IRD[128];9 p4 F+ v) w4 z$ I
- int i = 0;4 u# {' a& X- b4 P# q
- int LeranTime= 0;
$ G8 D% `4 \0 N0 `6 a5 G% R9 c - void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
2 x# Z) |: N L7 O- Z, b3 U - {
+ `0 i4 X) n' n. }4 D% | - uint8_t yuce;
- r2 e0 x% S8 }. B2 A - maxim_max30102_read_fifo(&red,&ir);
, r/ E4 ^1 V, `$ ]; z. w - IRD[i] = ir;
! O& v3 X' c3 ]3 f) W2 U1 S) ^* p9 K - i++;
3 l1 e2 n. h0 J& u% {
, P1 y5 K! p8 g8 k- if(i==128)
1 r( N! @' V4 T3 ^5 r - {4 F* s! n6 j$ J. s+ b) b
- if(LeranTime<10)
: b0 W1 [* g9 ~# Y- Q( ~: F - {& O( Z$ f/ ^& g( x$ ]' W: O+ ~
- HAL_GPIO_TogglePin(GPIOF, GPIO_PIN_9);//LED翻转8 x( r4 x, _0 x, e3 B0 V
- neai_anomalydetection_learn(IRD);
+ ]+ ?8 g1 q8 e" ^' M# i. F5 N6 y - }
3 C7 B# G* ]/ Q p - else0 z* w* t" y" Q+ W
- {
' ], f( @/ E8 C0 y/ l8 E5 G - neai_anomalydetection_detect(IRD, &yuce);# y( t: J" ~2 C
- if(yuce>80)
; l3 q( N# C' N1 r - {) k( P, U# N9 Q% I h0 I
- HAL_GPIO_WritePin(GPIOF, GPIO_PIN_10, 1);& [: v3 i) ]1 E4 D7 _, C: c
- }
( a$ @, h/ K7 V3 c2 Q. W - else
. p* x' ]* S S( c - {
' @5 M0 P4 {' S - HAL_GPIO_WritePin(GPIOF, GPIO_PIN_10, 0);$ X* g/ Q' [1 K. t" \/ A y7 ~
- }
0 Q# Y2 O6 ?8 ^% n' P/ L$ s - }7 r; D$ X0 ^# S0 L) i
- LeranTime++;
9 G7 r4 z" I, H; O& R8 Z - i = 0;; |# ~5 r5 ~9 @& z
- }9 w0 [1 n( I2 @" J
- }
复制代码
' |) C' F# ?# e' f0 w2 A7 t2 c# r; u
我们在定时器回调函数中调用,上电之后前十次为学习阶段,之后对测量值进行预测,当预期值>80即认为状态正常,则灯灭。
7 K" y+ t/ P- P/ D: r如果预期值<80则报警灯想起。# k- _1 b5 C6 L
5 N( [% i, i9 J8 V; Z7 g1 Z3 c
9 o# T+ s/ E+ G1 i, S/ i8 o
* Y7 x8 a1 `) ~* z/ i8 T0 F5 _4 G) [
转载自:电路小白9 K: i# o$ l1 Q/ c
如有侵权请联系删除
* }8 ]* u$ i- f% }% J* k) v% j8 w9 _3 \3 x; @# y; G; y
9 O% O+ a6 u+ Z% _6 I& N( I
$ @. g Z$ V' W7 K& T0 y, H0 X |