2024-04-07 02:33 AM
My binary classification algorithm has one input (270 data) and one output, I refer to section 6.4 of the code(AI:How to perform motion sensing on STM32L4 IoTnode - stm32mcu (stmicroelectronics.cn))
Question 1:
but the output category is always wrong, I don't know if the input data is wrong or the output result function is wrong
I used a dummy dataset 【test_buf】 as my input data, and I know that the category of the current 【test_buf】 is class1 (H2), but it always output class0(CO)
Question 2:
How can I tell if the algorithm is doing calculations on the input data
Is the algorithm effective?
Attach my code, please check, I would appreciate your help!!!!!! thanks!
/**
******************************************************************************
* @file app_x-cube-ai.c
* @author X-CUBE-AI C code generator
* @brief AI program body
******************************************************************************
* @attention
*
* Copyright (c) 2024 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/*
* Description
* v1.0 - Minimum template to show how to use the Embedded Client API
* model. Only one input and one output is supported. All
* memory resources are allocated statically (AI_NETWORK_XX, defines
* are used).
* Re-target of the printf function is out-of-scope.
* v2.0 - add multiple IO and/or multiple heap support
*
* For more information, see the embeded documentation:
*
* [1] %X_CUBE_AI_DIR%/Documentation/index.html
*
* X_CUBE_AI_DIR indicates the location where the X-CUBE-AI pack is installed
* typical : C:\Users\<user_name>\STM32Cube\Repository\STMicroelectronics\X-CUBE-AI\7.1.0
*/
# ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#if defined ( __ICCARM__ )
#elif defined ( __CC_ARM ) || ( __GNUC__ )
#endif
/* System headers */
# include <stdint.h>
# include <stdlib.h>
# include <stdio.h>
# include <inttypes.h>
# include <string.h>
# include "app_x-cube-ai.h"
# include "main.h"
# include "ai_datatypes_defines.h"
# include "network.h"
# include "network_data.h"
extern uint16_t ai_process_buf[270];
/* USER CODE BEGIN includes */
/* USER CODE END includes */
/* IO buffers ----------------------------------------------------------------*/
#if !defined(AI_NETWORK_INPUTS_IN_ACTIVATIONS)
AI_ALIGNED(4) ai_i8 data_in_1[AI_NETWORK_IN_1_SIZE_BYTES];
ai_i8* data_ins[AI_NETWORK_IN_NUM] = {
data_in_1
};
#else
ai_i8* data_ins[AI_NETWORK_IN_NUM] = {
NULL
};
#endif
#if !defined(AI_NETWORK_OUTPUTS_IN_ACTIVATIONS)
AI_ALIGNED(4) ai_i8 data_out_1[AI_NETWORK_OUT_1_SIZE_BYTES];
AI_ALIGNED(4) ai_i8 data_out_2[AI_NETWORK_OUT_2_SIZE_BYTES];
ai_i8* data_outs[AI_NETWORK_OUT_NUM] = {
data_out_1,
data_out_2
};
#else
ai_i8* data_outs[AI_NETWORK_OUT_NUM] = {
NULL,
NULL
};
#endif
/* Activations buffers -------------------------------------------------------*/
AI_ALIGNED(32)
static uint8_t pool0[AI_NETWORK_DATA_ACTIVATION_1_SIZE];
ai_handle data_activations0[] = { pool0 };
/* AI objects ----------------------------------------------------------------*/
static ai_handle network = AI_HANDLE_NULL;
float aiInData[AI_NETWORK_IN_1_SIZE];
float aiOutData[AI_NETWORK_OUT_1_SIZE];
////ai_u8 activations[AI_NETWORK_DATA_ACTIVATIONS_SIZE];
const char* activities[AI_NETWORK_OUT_1_SIZE] = {
"CO" , "H2"
};
//static ai_buffer* ai_input;
//static ai_buffer* ai_output;
ai_buffer* ai_input;
ai_buffer* ai_output;
static void ai_log_err(const ai_error err, const char* fct)
{
/* USER CODE BEGIN log */
if (fct)
printf("TEMPLATE - Error (%s) - type=0x%02x code=0x%02x\r\n", fct,
err.type, err.code);
else
printf("TEMPLATE - Error - type=0x%02x code=0x%02x\r\n", err.type, err.code);
do { } while (1);
/* USER CODE END log */
}
static int ai_boostrap(ai_handle* act_addr)
{
ai_error err;
/* Create and initialize an instance of the model */
err = ai_network_create_and_init(&network, act_addr, NULL);
if (err.type != AI_ERROR_NONE)
{
ai_log_err(err, "ai_network_create_and_init");
return -1;
}
ai_input = ai_network_inputs_get(network, NULL);
ai_output = ai_network_outputs_get(network, NULL);
#if defined(AI_NETWORK_INPUTS_IN_ACTIVATIONS)
/* In the case where "--allocate-inputs" option is used, memory buffer can be
* used from the activations buffer. This is not mandatory.
*/
for (int idx=0; idx < AI_NETWORK_IN_NUM; idx++) {
data_ins[idx] = ai_input[idx].data;
}
#else
for (int idx = 0; idx < AI_NETWORK_IN_NUM; idx++)
{
ai_input[idx].data = data_ins[idx];
}
#endif
#if defined(AI_NETWORK_OUTPUTS_IN_ACTIVATIONS)
/* In the case where "--allocate-outputs" option is used, memory buffer can be
* used from the activations buffer. This is no mandatory.
*/
for (int idx=0; idx < AI_NETWORK_OUT_NUM; idx++) {
data_outs[idx] = ai_output[idx].data;
}
#else
for (int idx = 0; idx < AI_NETWORK_OUT_NUM; idx++)
{
ai_output[idx].data = data_outs[idx];
}
#endif
return 0;
}
//ai_input = (ai_buffer*)malloc(sizeof(ai_buffer));
float test_buf[270] = { 0.5, 0, 0, 0.5, 0, 0, 0.5, 0, 0, 0.5, 0, 0, 0.5, 2, 1, 0.5, 5, 2, 0.5, 7, 3, 0.5, 7, 3, 0.5, 7, 3, 0.5, 10, 4, 0.5, 10, 4, 0.5, 12, 5, 0.5, 12, 5, 0.5, 12, 5, 0.5, 12, 5, 0.5, 12, 5, 0.5, 12, 5, 0.5, 12, 5, 0.5, 12, 5, 0.5, 12, 5, 0.5, 10, 4, 0.5, 10, 4, 0.5, 10, 4, 0.5, 10, 4, 0.5, 10, 4, 0.5, 10, 4, 0.5, 10, 4, 0.5, 10, 4, 0.5, 10, 4, 0.5, 15, 6, 0.5, 15, 6, 0.5, 15, 6, 0.5, 25, 10, 0.5, 25, 10, 0.5, 42, 17, 0.5, 67, 27, 1.6, 67, 27, 1.6, 102, 41, 1.6, 145, 58, 1.6, 195, 78, 1.6, 195, 78, 3.5, 247, 99, 3.5, 247, 99, 3.5, 305, 122, 3.5, 362, 145, 3.5, 420, 168, 3.5, 420, 168, 3.5, 477, 191, 3.5, 477, 191, 7.4, 540, 216, 7.4, 602, 241, 7.4, 602, 241, 7.4, 670, 268, 14.0, 742, 297, 14.0, 820, 328, 14.0, 820, 328, 14.0, 907, 363, 14.0, 1000, 400, 24.3, 1000, 400, 24.3, 1105, 442, 24.3, 1105, 442, 24.3, 1212, 485, 24.3, 1327, 531, 24.3, 1327, 531, 39.7, 1442, 577, 39.7, 1557, 623, 39.7, 1665, 666, 39.7, 1665, 666, 39.7, 1767, 707, 61.6, 1767, 707, 61.6, 1767, 707, 61.6, 1857, 743, 61.6, 1857, 743, 61.6, 1937, 775, 61.6, 2005, 802, 61.6, 2005, 802, 91.5, 2065, 826, 91.5, 2130, 852, 91.5, 2202, 881, 91.5, 2202, 881, 91.5, 2290, 916, 130.0, 2392, 957, 130.0, 2392, 957, 130.0, 2497, 999, 130.0, 2595, 1038, 130.0, 2595, 1038, 177.2, 2672, 1069, 177.2, 2672, 1069, 177.2, 2725, 1090, 177.2, 2755, 1102 };
//double out_data[2];
int out_buf[2];
int ai_run(const void* in_data, void* out_data)
{
ai_i32 batch;
/* 1 - Update IO handlers with the @ of the data payload */
/* 2 - Initialize input/output buffer handlers */
ai_input[0].data = AI_HANDLE_PTR(in_data);
ai_output[0].data = AI_HANDLE_PTR(out_data);
/* 3 - Perform the inference */
batch = ai_network_run(network, &ai_input[0], &ai_output[0]);
if (batch != 1)
{
ai_log_err(ai_network_get_error(network),
"ai_network_run");
return -1;
}
return 0;
}
//****************************************************************************//
/* USER CODE BEGIN 2 */
int acquire_and_process_data(ai_i8* data[])
{
/* fill the inputs of the c-model
for (int idx=0; idx < AI_NETWORK_IN_NUM; idx++ )
{
data[idx] = ....
}
*/
/*
for(int i=0;i<270;i++)
{
data[i]=(ai_i8 *)&ai_process_buf[i];
//ai_i8 my_buf = (ai_i8)ai_process_buf[i];
}*/
//printf("acquire_and_process_data\r\n");
return 0;
}
int post_process(ai_i8* data[])
{
/* process the predictions
for (int idx=0; idx < AI_NETWORK_OUT_NUM; idx++ )
{
data[idx] = ....
}
*/
return 0;
}
/**/
static uint32_t argmax(const float * values, uint32_t len)
{
float max_value = values[0];
uint32_t max_index = 0;
for (uint32_t i = 1; i < len; i++) {
if (values[i] > max_value) {
max_value = values[i];
max_index = i;
}
}
return max_index;
}
/**/
/* USER CODE END 2 */
/* Entry points --------------------------------------------------------------*/
extern uint16_t ai_process_buf[270];
void MX_X_CUBE_AI_Init(void)
{
/* USER CODE BEGIN 5 */
printf("\r\nTEMPLATE - initialization\r\n");
ai_boostrap(data_activations0);
/* USER CODE END 5 */
}
void MX_X_CUBE_AI_Process(void)
{
/* USER CODE BEGIN 6 */
int res = -1;
printf("TEMPLATE - run - main loop\r\n");
if (network)
{
/* 1 - acquire and pre-process input data */
res = acquire_and_process_data(data_ins);
/* 2 - process the data - call inference engine */
if (res == 0)
res = ai_run((const void*)test_buf, (void*)out_buf);
//res = ai_run((const void*)test_buf, aiOutData);
/* 3- post-process the predictions */
if (res == 0)
{
//res = post_process(data_outs);
for (uint32_t i = 0; i < AI_NETWORK_OUT_1_SIZE; i++) {
printf("%f ", aiOutData[i]);
}
uint32_t class = argmax(aiOutData, AI_NETWORK_OUT_1_SIZE);
printf(": %d - %s\r\n", (int) class, activities[class]);
}
#if 0
do {
/* 1 - acquire and pre-process input data */
res = acquire_and_process_data(data_ins);
/* 2 - process the data - call inference engine */
if (res == 0)
res = ai_run();
/* 3- post-process the predictions */
if (res == 0)
res = post_process(data_outs);
} while (res==0);
#endif
}
if (res)
{
ai_error err = { AI_ERROR_INVALID_STATE, AI_ERROR_CODE_NETWORK };
ai_log_err(err, "Process has FAILED");
}
/* USER CODE END 6 */
}
#ifdef __cplusplus
}
#endif
2024-04-09 09:48 AM
Hi Sunjing,
Not easy to review your code, however, I think that in MX_X_CUBE_AI_Process() function, the second parameter to call ai_run() is not correct, you need to pass "aiOutData" instead "out_buf" to be able to read the generated results.
if (network)
{
/* 1 - acquire and pre-process input data */
res = acquire_and_process_data(data_ins);
/* 2 - process the data - call inference engine */
if (res == 0)
res = ai_run((const void*)test_buf, (void*)aiOutData); <- fix here
//res = ai_run((const void*)test_buf, aiOutData);
/* 3- post-process the predictions */
if (res == 0)
{
br,
Jean-Michel