写的教程反响平平,可能是晦涩难懂,那就直接上代码(极度粗糙的demo)。 接上次的软硬件环境,我采用的STemwin(本来想用littlevgl)自带bmp显示(详细代码可参考某某莱教程)。先看看生成的一些代码。 GUI_Init();# L- X) j# O5 `8 s; f GUI_SetBkColor(GUI_BLUE_98); GUI_Clear(); GUI_DispStringHCenterAt( GUI_GetVersionString() , GUI_GetScreenSizeX()/2, GUI_GetScreenSizeY()/2); SDRes=f_mount(&SDFatFS,(TCHAR*)SDPath,0); if(SDRes!=FR_OK)9 a2 \: Z! }$ `, ?& O; ^ {! N0 W0 p7 Q, }7 @( j. F9 i! z Error_Handler(); } MX_X_CUBE_AI_Process(); /* USER CODE END 2 */% u% X& m3 P3 \' Z. z /* Infinite loop */* X/ p% |% z" d /* USER CODE BEGIN WHILE */1 v0 ^0 F3 {/ t, P) t2 |$ r% [0 ] while (1) {6 z1 _; M7 T5 j6 d( L i /* USER CODE END WHILE */, O" T) |. B0 o: k6 n% X GUI_Delay(10);. {; J8 Z/ V- {8 d4 s /* USER CODE BEGIN 3 */$ ~5 o. L4 f( x+ m" H& \ }3 `- d6 F$ D; X) P 简单的主函数。 / a, ~ N! @5 W( f) N( k 进入MX_X_CUBE_AI_Process();2 p$ e, J5 [8 p: g( M- L 2 a- K! K8 ]: L. \; J ai_buffer ai_input; ai_buffer ai_output;( \# P! N3 P) K; Z F: f( b ai_i32 batch; char str_tmp[16];$ N H" u) U9 _ for(uint8_t i=0; i<10; i++)( {, A5 j' Y1 z: D { sprintf(str_tmp,"%1d.bmp",i);% o9 h5 C7 e6 v# V0 ^* ~: M/ e _ShowBMPEx(str_tmp); LCD_ShowBMP(str_tmp); for(uint16_t i=0; i<AI_LENET_IN_1_SIZE ; i++ ) {/ t5 [ x" @" s: f1 w in_data[i] = *bmpBuffPtr++;9 i8 I. @ K& Y( \& V$ @ }, I; s9 Y, f) R4 ^7 h+ @ ai_input.n_batches = 1;3 u4 c1 f' \+ q6 r ai_input.data = AI_HANDLE_PTR(in_data);7 Q. Q L% Q0 q E% Q" O$ m ai_output.n_batches = 1;9 G6 _0 Z- \) J ai_output.data = AI_HANDLE_PTR(out_data); batch = ai_lenet_run(handel, &ai_input, &ai_output); if (batch != 1) {& @% \: ?5 P+ D9 B; Z- L$ V* f) v err = ai_lenet_get_error(handel); if( err.code ) {% u! H) Z1 h; E, x* K5 O while(1); }+ a8 c q8 L. g, S }) ]4 h0 d+ K0 | uint8_t count=0; for(uint8_t i=0; i<AI_MNETWORK_OUT_1_SIZE; i++)2 i: u5 H+ A7 \! n5 h {: R8 x' y9 B* D; N if( out_data[i] >=0.9f); y( T0 A8 d( P5 s8 u { sprintf(str_tmp,"Num:%d",i); GUI_SetFont(GUI_FONT_32B_ASCII); GUI_DispStringAt(str_tmp,200,0); GUI_SetFont(GUI_FONT_16B_ASCII); count++;* j# c. v0 R/ F3 B- k! ]5 L, j }% F0 `% y* Z! p8 }( a% i! I } if(count!=1)# _# @/ N+ s* ~+ k {# G& e$ N0 m* L" J/ } GUI_SetFont(GUI_FONT_32B_ASCII); GUI_DispStringAt("err",200,0);' z8 H5 k2 @3 } GUI_SetFont(GUI_FONT_16B_ASCII); }: d- L, C% T0 o, D free(bmpBuffPtr); HAL_Delay(2000); } 8 C* d) Y# P7 R/ Y; f' ~ 熟悉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 型 何必不输出 所有的置信度。后面我将继续挖掘。 % T/ N% ?4 E# ]$ ` 流程介绍完毕,下面说一说cubeAI的主要函数。 ai_lenet_create(&handel, NULL);% m) X' n9 ^; z5 ~1 d: U ai_lenet_get_info(handel, &report); ai_network_params params = {& g! n+ d2 [8 N4 | AI_LENET_DATA_WEIGHTS(ai_lenet_data_weights_get()), //权重的获取) N2 R W9 x' x& x0 c5 l AI_LENET_DATA_ACTIVATIONS(activations) // 激活函数8 j" V! L9 O7 T" J1 A/ U/ G }; ai_lenet_init(handel, ¶ms); //lenet的初始化,估计是申请内存什么的,写flash。, T3 h( E V+ e4 x- X err = ai_lenet_get_error(handel);5 s, [4 _5 Q' ]' t' b, w' V+ K9 X batch = ai_lenet_run(handel, &ai_input, &ai_output); //图片输入以及处理完毕的输出,1batch批 9 l' \! z h W3 y8 i: f% ? 总的来说比较简单的demo,其实也可以做复杂一点,先手写然后STemwin存bmp图片,然后利用加权平均得到BMP颜色数据的灰度,输入到lenet,dedaojieguo。效果会比较酷炫。 这模型被压缩很厉害,能有这样的结果以及不错了,最后祝贺一下ST,半导体前15! 期待MP1,玩玩不用压缩的AI。1 C" {, B; v$ u 附件:工程源码。& x$ e0 \, {/ D |
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可以提供哪些软硬件支持
谢谢支持