 So next I'll give the microphone to Bartos, who's going to show you how to map this .h5 model onto SCM32 code. Okay, so in order to do that, please start Cubemix. So all of us, we have IoT boards in front of us, L475MCU is on the top. That's why I propose to start from the new project from access to board selector here, just in the middle of the screen. So please click it. Okay, and you can see the board selector window. And within part number search bar, you can just enter IoT text. And there is very simple selection, the only one board is visible. So just double click on part number, BL47. And let's initialize all peripherals with default mode just to speed up the workshop. We are really limited in time. Okay, this is the MCU view. And the second goal of the initialization is to show you how much external peripherals, how much external components is on the board. We have a Wi-Fi module, we have a Bluetooth, a lot of sensors, including proximity sensor, external QSP memory, etc. Okay, so this is Cubemix. We need additional software, because AI in fact is extension of the Cubemix. So here is a hidden option. I agree with you, it's not so well visible. So please click it. And we can see a lot of external components. To make the screen more clean, I suggest to check this option Artificial Intelligence. And now we can see only two items. Okay, so I will unroll. And we have considered that we have one software package. We have two items, core and application. And if you are already experienced with some protocol stacks like Bluetooth, Lora, Zikbox, whatever, you know that we have protocol stack and protocol stack it is equivalent of core in our case, because core in this case it is AI library, it is an object, so closed library, key message for you, for your customers. And the debug capability of this library is of another key message for you. So we have protocol stack, I mean core, AI library, and we need application on the top, as for Bluetooth, exactly the same configuration. So let's check the core to let Cubemix generate the AI library and select the application and Cubemix is proposing three different applications. System performance, validation and application template. So system performance, it is a simple application to show you the performance, I mean the execution time for the neural network runtime. In the neural network wording terminology, we can say the time of inference. So we can skip this application because there is no connection, there is no feedback to PC and feedback. There is a validation application, so we'll use this application and we will be able to validate the real network running on the real silicon. I will explain later on what does it mean validation. So let's select this validation, application template, this is just empty application consisting of AI library only and some API interface, it is the case of your customers. But now we are really squeezed in time, so we cannot do it from scratch. Within the resources inspector here, you can see additional software item, the next item. And when I click, I can see XQBI, so please click on it. And we need to again check both components, core and application. And please don't ask me why, we need to proceed such a way, but I hope, I'm sure that in the next version it will be fixed, so don't worry. And we will be, we need also the output window to see the debug output. So window outputs and let's increase. Okay, so the user interface is already configured and what's next? How do you think? We will be migrating the neural network model to C code. Okay, so let's add network. But before, let's define the model kind. As Guillaume has mentioned just before a few minutes, the kind of industry standard, it is a TensorFlow and Keras high-level library on the top. So we will select Keras. This is another key message for you, for your customers. And we have ready model because we will simulate the updating, the tuning of the customer network, customer model. And in our case, the customer project, customer model will be taken from function pack. Because in fact, function pack is marketing name, function pack is just a set of examples of application. Okay, so saved model. And then we need to navigate to the model. We can do it in two ways. First one is I would say classic one just by clicking browse and navigating to the particular file. And the second one is by using Windows Explorer and by dragging and drop the file here in this area. So I will show you the second one as a modern one, step by step. Don't worry, but be careful, this is quite tricky part. So there is a root folder on the paper. So please go to this folder. And within this folder you can find STM32, cube function pack, sensing 1, v.2.2.0. Root folder on the paper and then STM32, cube function pack, sensing 1, v.2.2.0. Okay, let's enter this repository. Again, STM32, cube function pack, sensing 1. Then enter middlewares, ST, STM32 AI library, ASC, audio sync classification. Models indeed. And session Keras mode. This is the audio sync classification model. Very simple network, tens of neurons. And we can drag and drop it. Okay, what's next? We have model. And we would like to... It is already trained. It is already trained. Another key message for you, very important. The cube AI, sorry. It is a converter. It converts the pre-trained and the keyword is pre-trained model to C code. So it means that the model is somehow frozen. It cannot learn more, at least today for the current offer. Buy, yes, buy some workstation, GPU, strong computation power machine. Okay, so we have model based on Python. And then we are migrating it to C code. So the very important step is to check if it fits within our microcontroller. So we need to analyze, indeed. Let's analyze. Okay, so we got one strange number and two well-known numbers. The strange number is here, complexity. MACC means multiply and accumulate complexity. It is a number of multiply and accumulate operations to perform the execution, to perform the inference of the model. Why multiply and accumulate? Because behind the neuronal network there is a neuron. And the mathematical neuron model, it is a lot of multiplications. So we are multiplying the input value and weight of the input. And then we are summing it up. That's why multiply and accumulate. And the next two numbers are well-known. So the flash occupation is 30 kilobytes. And the RAM is about 18 kilobytes. It is a very small model, as I mentioned, just for a workshop proposal. But in real life, for sure, you will meet big models or image recognition, some computer vision, et cetera. And customer can complain of the price. Microcontroller or can complain of external flash. But there is a solution. But before, let's validate this model. Okay, so there is an error level, 0.01. And we are far from this border. We got some quite nice numbers. So everything is okay. But next key message for you. This is keyword, relative error. What does it mean that error is relative? It means that we are comparing the results for the ideal model, for the original model running in Python on PC, to simulated model in C, also on our PC. So this is relative error. The base is the original model, the Python running model. And we are doing this validation, this comparison, using random numbers, random input values. This is due to our limited time. Of course it is okay, but a little bit, I would say, better method is to use custom data. We cannot do it now. But in real life, we always have custom data because the key point, the key step for the development of neural network is data set. And this is the value in money. Because the structure of the neural network, the number of neurons, it is also important, but believe me, to gather data set, this, as Guillaume mentioned, for this Augustine classification, for very simple network, the input data set, it is 20 gigabytes of raw wave files. So to gather it, it's a really big job. And very expensive. Okay, let's keep random numbers. So we are okay. But let's assume that the model is really big and we want to provide the customer solution of the price problem. We can compress the model. Let's select compression by form. And analyze again if we are still, if we can fit within the resources. So the complexity didn't change. I think it is expected because we are playing with the same model, but the flash occupation dramatically drops, but almost by 50%. So that's the solution for you. Of course, not always it is almost 50%, but kind of solution. But this model is somehow squeezed. So let's validate it again on the desktop if we are still within the error range or below the error range. We are okay. The numbers are a little bit much worse, but it is still okay. So we can stop and play with the network now. And this is network. It is the equivalent of protocol stack. This is our core. So we need to configure application. Let's go to the platform settings. The application is very simple. The back output is user. So let's select user. And the number of the user is user 1. That's all regarding the network and application of the network. Let's verify the clock configuration. The clock frequency is maximum for this micro. It's 80 megahertz. You can lower it up to you, but I would keep it. And then project manager to configure the... to enter project name. Please follow my name, validate underscore nn and skip this number because for me it is number of the session to separate. So validate underscore nn. Then select the target folder. I need to keep my folder, but on your side please click browse and select any folder. Okay, and let's keep EWRM V8 because you had it already because of security workshop, L5 security workshop. So we'll use IR. And the last step is to extend the heap size by zero. So to change the value of the heap size from 200 up to 2,000. But this is particular setting. It is related to this particular application only. So don't worry, it is not related to the QBAI library because we have set of buffers in RAM. And please be careful to not mix the heap with stack. 2,000 on the SFRS value. That's all. Let's generate code. And open project. Okay. So the project is open. And within project explorer let's start from the application folder and user subfolder. Double click on main.c. I will show you how the application is simple because this is just one line. Let's go to the main loop. The line number 132. So this is one function call. That's all. MXXQBAI process. Library is located under lip folder. And as I said, this is an object without the back capability. What about API to the lip? It is hidden behind the middle words. So let's unroll it. Then middle words, ST. Let's start in the meantime just to save a time. Building F7, please press F7. Okay. So middle words, ST, AI, AI. Okay. And we have two subfolders. Data and source. And we start the explanation from the data subfolder. There is only one file, network data. I will open it. And you can see an array consisting of a lot of numbers. Yes, coefficients, but in neural network, wording, weights, weights, weights. And this is very important part of the application because we can call it as a meta-program. Why? Because most of the functionality is hidden behind those numbers, those weights. This is our program. From the learning process, from the peras. And yes, and the model file, this is, I didn't mention it, the extension of the model file, it is .h5. This is hierarchical data format. This is generic format developed by NASA, according to my knowledge, to store the data from the satellites, the map data. A lot of hierarchical data. And so this is not related to the neural network itself. Okay, so this is our, so the first real value, it is data set, and the second real value, it is here, the weights, the coefficients. And we can migrate, of course, not on this level, but on the Python level, we can migrate already learned layers between models. So for example, model A consists of n layers, and m of layers are exactly the same like in the second model. So we can migrate, I can show you, we can migrate particular layers already learned to the destination model. I can show you such a script after the workshop, if you are interested. It's very simple, just several lines, that's all. Okay, API, application programming interface to the AI library. So the second subfolder of Middleware's source, network.c. And let's open the header file. So line number 23, right click, and open network.h. Okay, and here is the very nice definition. We can see input tensor and output tensor. I know sounds strange, the tensor, but behind the explanation is very simple, it is multi-dimensional array, that's all. And for the input tensor, we have those two numbers, 30 and 32. In fact, our convolutional network is recognizing the pictures, we have pictures. And this is the resolution of the picture. And because we are recognizing pictures, we are transforming from the time domain to the frequency domain, there is some issue, maybe not issue, feature behind. We need to gather data. So the conclusion is that we have time quantum. So every second in this particular case because of preprocessing, because of collecting of the data, every second we can perform the influence of the network. Okay, so this is input tensor, consisting of the resolution of our picture. And this is output tensor, and here is free. We have free classes, indoor, outdoor and in vehicle. Okay, so input and output data structure. And what about the network? We need three steps. We need to allocate the resources for the network model, to allocate the RAM, so we need to create the network. Then we need to init the weights and all the layers. So we need to init the network, and the third step is run the network, that's all. Okay, and those functions you can find below. So network create, and then complementary function network destroy, then network init, and network run, that's all, very simple. So two data structures, input and output and free functions. Let's flash the board. Project, download, download active application. And start terminal. The communication parameters are exactly the same like during first lab, so 115 kilobits per second. I will start from the font setting to make the visible screen. Then new connection. I'm selecting the ester link related with dual comports. And set up serial 115 8-bit character without parity one-stop bit. And I'm pressing reset. And what is the conclusion? It's very simple. We need to close the terminal. To free the comports and to let Cubemix perform the action. So let's come back to the Cubemix, because now we will validate our network on the real silicon using user communication and virtual comports. Let's come back to the Cubemix and pinout and configuration tab. And then network tab within the network stuff. Now we can validate on target. So we are comparing the Python model as a base with real model working on the real silicon. So let's configure the comports again. Comport 8 in my case. And process just started. It takes a little bit more time because we have additional communication. It is 115. In next release, I think it will be possible to increase the speed. So the time is a little bit longer, but we got more data. And now coming back to the convolutional layers. You can see here the time of execution layer-wise. So almost 33 milliseconds for convolutional layer 1, 42 for convolutional layer number 2. And all the rest of the numbers are not so significant. I would say we can skip those numbers. The significant impact is on the convolutional layers because in fact, as I said, it is kind of reduction of the data amount, or we can consider those layers as filters, digital filters. And with digital filters, we have a lot of computations. That's why we got such a timing. And what about error? We are still okay. The number is worse, but we are still okay. So we can use this compressed model and we can offer customer cheaper microcontroller. That's the goal, in fact, of all this action. Okay, so this is the end of this lab. We have 15 minutes, so I will show you, because this application from a practical point of view is useless. We just validated the model. So this is the main goal. And now we need to know how to update the customer project with the new model, which is acceptable. And to do it, I will show you slides. It will be very complicated. You must be very focused. You need to be Windows Explorer experts. That's all. We need to replace four files. That's all. Using Windows Explorer or whatever you like. We need to replace network data, so the file which consists of the coefficients, the weights. And we need an end-related header file. And we need to replace the network.c, end-related header file. It is API, application programming interface. And then rebuild the project. That's all. You can follow me or not, because copy and paste toughies, as when you are doing it first time, can be tricky. So you can follow me or not. I will show you live. We need two instances of the Windows Explorer. So on the right side, I'm putting our destination, so the customer project. So in our case, it is STM32, Cube function pack. So the set of examples, function pack. So again, I'm entering the root folder, then middleware, then ST, then STM32 AI library, ASC. Okay, and we have include and source. Let's keep this view. On the left side, I will put our source. So the previously just generated project, consisting of our new model. So in my case, it is validate NN6. In your case, it is validate NN on the left side. And here again, validate NN, middlewares, ST, AI, AI. Okay, let's keep this view. And let's start the structure of the folders is different. It's good from some point of view and it is problem from another point of view. It's good because it is a simulation of real life. For sure, the folder structures of the customer project will be different than the one generated by QBMX. So we can practice. Let's start from the include files on the destination side. So it is customer project on the right side. And I'm opening double clicking on include. I need to delete the previous job from the previous workshop. So the good practice, you can follow it or not. The good practice is to mark the old model as an old one, just in case. So we can add underscore old extension or whatever you want. Or you can just delete all the stuff up to you. And then we need to locate new just generated header files on our source site. So the QBMX generated project. So within the data, we can see network data dot h. I can copy it and paste. And now I need to locate the network dot h. And it is located within the include folder on the source site. Copy and paste. That's all. So we already replaced the include files, the header files. Then the last step is to replace the source. So I'm entering my destination, customer project, deleting the old stuff from the previous workshop. Then I'm marking the old files as old ones. And on left side of the screen, so the QBMX project, the updated model, I'm looking for the network data dot c. So within the data sub folder, I can find network data dot c. I'm copy pasted. And within source on the QBMX project, I can find network dot c project. Copy and paste to the destination. That's job is done. And now the last technical step is to rebuild the project. So I need to come back to the root folder. And I need to enter the projects. BL475, applications, sensing, EW arm. And I need to start IR. Okay. Just one button, F7. Okay, so I just build the project, and I cannot download it now from the IR level, because as Guillaume mentioned, we have bootloader, dedicated bootloader linked to the particular area of the flash memory, and we have application linked to the different area of the memory. And I will use the script to download to flash the project and sdlink command line. So the script is located in the same folder as the project file. Clean sensing one, but I'm just clicking. And coming back to terminal, we have three minutes, so I will show you. File, new connection, and reset. And now I will use command line as a vintage way. I like it. So blue button. Okay, so you can see that it is still functional. Let's wait several seconds. Please just start talking now, because it is silent and the network model is so simple and not so clever. Okay.