写的教程反响平平,可能是晦涩难懂,那就直接上代码(极度粗糙的demo)。1 x& q8 H- e' f4 i 接上次的软硬件环境,我采用的STemwin(本来想用littlevgl)自带bmp显示(详细代码可参考某某莱教程)。先看看生成的一些代码。 GUI_Init();+ s- |" t6 \$ f" ?/ h1 n GUI_SetBkColor(GUI_BLUE_98); GUI_Clear(); GUI_DispStringHCenterAt( GUI_GetVersionString() , GUI_GetScreenSizeX()/2, GUI_GetScreenSizeY()/2);" G; B. n V( W- G6 U5 t SDRes=f_mount(&SDFatFS,(TCHAR*)SDPath,0); if(SDRes!=FR_OK)! B% g1 K1 i5 q {4 a) i7 Z) }- c% Z% [& Y# U Error_Handler();9 T% _5 n) `6 F6 g5 `8 K5 \ } MX_X_CUBE_AI_Process(); /* USER CODE END 2 */) C" H3 U+ X1 {9 B& ] r /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1)/ L/ a1 j* L# A0 P z- ~ { /* USER CODE END WHILE */ GUI_Delay(10); /* USER CODE BEGIN 3 */ } 7 N# w* z" _: I! \. K5 t: s 简单的主函数。 " [& J" ` c. L6 r) `$ l ) L3 E1 G$ J- Y7 D 进入MX_X_CUBE_AI_Process();' ? p) C4 V' }; h+ o" q : p% Y( w4 d& R' j$ J ai_buffer ai_input; ai_buffer ai_output; ai_i32 batch; char str_tmp[16];. b8 K0 A) @# B4 L& X% _ ~ for(uint8_t i=0; i<10; i++) { sprintf(str_tmp,"%1d.bmp",i); _ShowBMPEx(str_tmp); LCD_ShowBMP(str_tmp);% d( s8 h0 A, d for(uint16_t i=0; i<AI_LENET_IN_1_SIZE ; i++ ) {; l4 R" W! N. K, Z in_data[i] = *bmpBuffPtr++;# `) q+ t, U' g& W. d& k }5 N# l* B: {1 {2 C3 d ai_input.n_batches = 1; ai_input.data = AI_HANDLE_PTR(in_data);$ k$ {" @: x( o, m, l ai_output.n_batches = 1;9 E( Y' A, S8 N* k0 D( }1 w ai_output.data = AI_HANDLE_PTR(out_data);, \9 A4 G8 g( }1 `* {" f batch = ai_lenet_run(handel, &ai_input, &ai_output); # ]% Q; k& D! ~ W' n if (batch != 1) & Y4 |1 d' \4 [6 F3 H2 ^% _ \; n {5 E8 _2 b% L9 D, E err = ai_lenet_get_error(handel);) q' y0 W' E2 p" K/ S- Z+ r+ A if( err.code )6 g, ~) L! a; F' w' g5 P9 E {% @9 n4 f$ m! e. {/ J/ s while(1); } } uint8_t count=0; for(uint8_t i=0; i<AI_MNETWORK_OUT_1_SIZE; i++)% \" o/ [9 Y& Z9 J. \ { if( out_data[i] >=0.9f)1 q! u4 E7 ~( a% v( q+ y { sprintf(str_tmp,"Num:%d",i); GUI_SetFont(GUI_FONT_32B_ASCII); GUI_DispStringAt(str_tmp,200,0); GUI_SetFont(GUI_FONT_16B_ASCII);5 E2 x* W: w" p- g; U! Z# [ count++;# \& ?; U4 C! S h% G( Q5 k } }* q1 N5 P! m1 Y# w if(count!=1)9 V2 B; Z6 z! d4 s0 V+ L {& q- P0 S$ c' [' y$ Q% W GUI_SetFont(GUI_FONT_32B_ASCII); Q8 J3 N) Z5 r' U8 h1 o GUI_DispStringAt("err",200,0);, z2 \5 u" A" h4 q GUI_SetFont(GUI_FONT_16B_ASCII); }2 ]5 R7 l* Z$ f2 K# H6 I free(bmpBuffPtr); HAL_Delay(2000); }' I' D6 c: P+ s) `2 [ 熟悉STemwin的大佬肯定知道我在干嘛,不断的读取SD卡中的bmp文件,然后显示,并且通过ai_lenet_run函数得到识别结果,输出是static ai_float out_data[AI_MNETWORK_OUT_1_SIZE]; 0-9有十个识别结果,这个向量大小是十。调试程序时,输出不像是我在PC ubuntu caffe环境中的输出结果,PC上主要是以softmax得到每个类别的置信度,所以PC上向量肯定全部都有值,置信度最高即为模型结果。在MCU上,输出结果只有零和一。让我很奇怪,既然是ai_float 型 何必不输出 所有的置信度。后面我将继续挖掘。7 q) y/ d9 p! T 流程介绍完毕,下面说一说cubeAI的主要函数。: W0 K8 f* R. @2 l# t: j9 S/ } ai_lenet_create(&handel, NULL);! y" {. ?) Y% ?$ ~/ D ai_lenet_get_info(handel, &report); ai_network_params params = {9 h3 U: Y0 t7 Y, E W AI_LENET_DATA_WEIGHTS(ai_lenet_data_weights_get()), //权重的获取& t2 u% ?8 p1 v+ Y AI_LENET_DATA_ACTIVATIONS(activations) // 激活函数( P; O( q) s E* h8 M };. n& y. B8 Q" X! ` ai_lenet_init(handel, ¶ms); //lenet的初始化,估计是申请内存什么的,写flash。 err = ai_lenet_get_error(handel);( k9 H, c- s% X5 A n" R5 L 6 N! T2 i [& r( t4 x5 Y5 U batch = ai_lenet_run(handel, &ai_input, &ai_output); //图片输入以及处理完毕的输出,1batch批+ j, W) [# c( u- L- u $ T1 t& U5 y3 h% I4 ~4 j 总的来说比较简单的demo,其实也可以做复杂一点,先手写然后STemwin存bmp图片,然后利用加权平均得到BMP颜色数据的灰度,输入到lenet,dedaojieguo。效果会比较酷炫。0 R. [# l$ V/ Y3 Y 这模型被压缩很厉害,能有这样的结果以及不错了,最后祝贺一下ST,半导体前15! 期待MP1,玩玩不用压缩的AI。( C0 ]. Z( }* q2 X$ G# I9 E 附件:工程源码。 9 }9 y- R& C# ~7 `$ i- {7 U1 ^ . k/ u- S0 H5 O: ` |
Minist.rar
下载10.2 MB, 下载次数: 150
【STM32H7S78-DK评测】移植AI框架TensorFlow【DSP指令加速篇】
【STM32H7S78-DK评测】移植AI框架TensorFlow【下篇】
【STM32H7S78-DK评测】移植AI框架TensorFlow Lite【上篇】
【STM32H7S78-DK评测】移植边缘AI推理框架——TFLM(TensorFlow Lite for Microcontrollers)上篇
破解边缘AI硬件与软件挑战,意法半导体解读三大创新要点
意法半导体助力企业产品智能化,加快边缘人工智能应用
STM32不至于芯,2023济南站研讨会
ST机器学习汽车解决方案
Cube.AI和NanoEdge AI具备哪些优秀的功能
边缘AI领域,ST可以提供哪些软硬件支持
谢谢支持