cancel
Showing results for 
Search instead for 
Did you mean: 

NanoEdge AI 训练后出现异常数据相似度为零,但工程运行错误。

dw1
Associate II

你好,近期我在使用NanoEdge AI Studio实现异常检测功能,基于三轴加速度计的数据实现。我出现了以下问题:

1.我使用的最新版本5.0.2,在benchmark界面训练模型后,表格Best Library Result 中异常数据的结果为零,就是在表格的底部。但我生成代码需要的文件后运用到工程中其相似度一直输出为91%,即使我大幅度的改变加速度计的值也仍然时91%。

2.在有一次训练时,表格Best Library Result 中异常数据的结果不为零了,大概为68%。我生成需要的额NanoEdge AI.h和library.a以及knowledge.h生成后运用到keil工程中发现能够正常进行学习,并且也可不学习使用knowledge.h的这个数据集进行检测相似度,结果较为明显。只是原本的异常数据其相似度对应的也为68%。

3.我的疑惑在于,对应的模型训练不应该异常数据接近为零,正常数据接近一百吗,可我似乎于认为的不一样。并且同样的数据进行第一次训练的结果可能异常数据不为零,但后面几次训练后一直为零。导致的结果就是,训练结果异常数据为零的模型,在使用官方给的先进行学习一段时间,在进行异常检测运行效果是错误的,相似度一直输出为一个固定值,比如91%。并且运行不事先学习,利用knowledge这个数组作为学习数据,运行结果也是不正确的,但是训练结果异常数据不为零的就可正常运行。但这个结果也不是一直会出现的,偶尔出现。我的数据上传使用的是USB串口上传(USB转TTL、或者蓝牙串口)

 

以下为代码(省略了部分)

#include “NanoEdgeAI.h”
#include “knowledge.h”
#define LEARNING_ITERATIONS 30
浮点数 input_user_buffer[DATA_INPUT_USER * AXIS_NUMBER];输入值的缓冲区


无效 SystemClock_Config(void);
静态 void MPU_Config(void);

void fill_buffer(float input_buffer[])
{
/* 用户开始 */
float acc_mg[3]; // 临时存储单个样本的X/Y/Z数据
uint16_t samples_collected = 0;
uint32_t last_tick = HAL_GetTick();

持续采集直到存满256个样本
while (samples_collected < DATA_INPUT_USER) {
// 1. 精确控制采样间隔(1000Hz = 1ms)
HAL_Delay(1);

//阿拉伯数字。读取加速度数据
if (LSM6DSV16X_Read6AxisData(&lsm6dsv16x_dev_ctx, acc_mg, NULL) & 0x01) {

// 3. 填充到NanoEdge缓冲区(按X,Y,Z顺序交替存储)
input_buffer[samples_collected * AXIS_NUMBER + 0] = acc_mg[0]; // X
input_buffer[samples_collected * AXIS_NUMBER + 1] = acc_mg[1]; // Y
input_buffer[samples_collected * AXIS_NUMBER + 2] = acc_mg[2]; // Z
samples_collected++;
}
}
/* 用户结束 */

}

 


int main(void) (无效)
{

MPU_Config();

HAL_Init();

SystemClock_Config();

MX_GPIO_Init();
MX_I2C1_Init();
MX_USART2_UART_Init();
MX_USART1_UART_Init();
MX_CRC_Init();
/* 用户代码开始 2 */
GPS_Init(&huart1, &huart2);UART1接GPS,UART2接PC
MagIMU_Fusion_Init();
MX_MEMS_Init();

/* 初始化 ------------------------------------------------------------*/
enum neai_state error_code = neai_anomalydetection_init();

if (error_code != NEAI_OK) {
printf(“错误!\r\n”);
/* 如果库在不支持的板子中工作,则会发生这种情况。*/
}
printf(“学习开始!\r\n”);
/* 学习过程 ----------------------------------------------------------*/
for (uint16_t iteration = 0 ; iteration < LEARNING_ITERATIONS ; iteration++) {
fill_buffer(input_user_buffer);
printf(“正在学习 %d/%d!\r\n”,迭代,LEARNING_ITERATIONS);
HAL_Delay(50);
neai_anomalydetection_learn(input_user_buffer);
}
neai_anomalydetection_knowledge(知识);
printf(“学习结束!\r\n”);
uint32_t last_print_time = HAL_GetTick();
uint8_t相似度 = 0;
while (1)
{
1. 填充数据并检测
fill_buffer(input_user_buffer);
neai_anomalydetection_detect(input_user_buffer, &similarity);

//阿拉伯数字。定期打印相似度(避免刷屏)
if (HAL_GetTick() - last_print_time >= 1000) {
last_print_time = HAL_GetTick();


            // 打印带时间戳的相似度信息
            printf("[%lu ms] similarity: %d%%\r\n", 
                 (unsigned long) HAL_GetTick(), 
                  similarity);
        }
        HAL_Delay(100); // 控制检测频

  }
}

1 ACCEPTED SOLUTION

Accepted Solutions
Julian E.
ST Employee

Hello @dw1,

 

Can you please edit your post to write it in english.

I tried to translate it but I did not understand the issue in the translation.

 

Your code seems correct, my only concern is that you declare: uint8_t相似度 = 0, but use similarity which does not seem to be declared in neai_anomalydetection_detect(input_user_buffer, &similarity); for example.

 

This could be useful:

Reason for abnormal similarity - STMicroelectronics Community

 

Have a good day,

Julian

 


In order to give better visibility on the answered topics, please click on 'Accept as Solution' on the reply which solved your issue or answered your question.

View solution in original post

8 REPLIES 8
Julian E.
ST Employee

Hello @dw1,

 

Can you please edit your post to write it in english.

I tried to translate it but I did not understand the issue in the translation.

 

Your code seems correct, my only concern is that you declare: uint8_t相似度 = 0, but use similarity which does not seem to be declared in neai_anomalydetection_detect(input_user_buffer, &similarity); for example.

 

This could be useful:

Reason for abnormal similarity - STMicroelectronics Community

 

Have a good day,

Julian

 


In order to give better visibility on the answered topics, please click on 'Accept as Solution' on the reply which solved your issue or answered your question.

Subject: Issues with NanoEdge AI Studio Anomaly Detection on Embedded Device

Dear STMicroelectronics Support Team,

I am using NanoEdge AI Studio v5.0.2 to implement an anomaly detection model based on 3-axis accelerometer data. While the benchmark and validation phases showed excellent results (100% accuracy for normal data and ~0% for anomalies), I encountered critical issues when deploying the model to my STM32 microcontroller. Below are the detailed problems and my attempts to resolve them:

Description of the Problem

  1. Mismatch Between Simulation and Embedded Device Results
    • I am using the latest version of NanoEdge AI Studio (5.0.2). During the benchmark training phase, the results are excellent: normal data similarity is almost 100%, and anomaly data similarity is close to 0%. I also validated the model using the "Validation" feature, simulating both learning and detection phases, and the results were as expected.
    • However, when I deploy the trained model on an embedded device (STM32 microcontroller), the results are incorrect. The similarity output is either consistently 0% or a fixed value (e.g., 91%), regardless of the input data. The data upload process via USB is successful, and the simulation tests on the PC side work correctly.
  2. Two Approaches Tried on the Embedded Device
    • Approach 1: Self-Learning and Detection
      • I implemented a learning phase on the device, followed by the detection phase. However, the similarity output remains constant, which is not expected.
    • Approach 2: Using Static Knowledge Array for Detection
      • I also tried using the knowledge array directly for detection without the learning phase. The results are still incorrect, and the similarity output does not reflect the actual data variations.

Code Sample

Below is the relevant code snippet for the learning and detection process on the embedded device:
 
#include "main.h"
#include "crc.h"
#include "i2c.h"
#include "memorymap.h"
#include "usart.h"
#include "gpio.h"
#include "GPS.h"
#include "IMU.h"
#include "app_mems.h"

extern stmdev_ctx_t lsm6dsv16x_dev_ctx;
extern stmdev_ctx_t lis2mdl_dev_ctx;
extern GNSS_Data gnss_data;
float acc_g[3],gyro_rads[3],mag_mG[3];

#include "NanoEdgeAI.h"
#include "knowledge.h"
#define LEARNING_ITERATIONS 20
float input_user_buffer[DATA_INPUT_USER * AXIS_NUMBER]; // Buffer of input values

void SystemClock_Config(void);
static void MPU_Config(void);

void fill_buffer(float input_buffer[])
{
/* USER BEGIN */
float acc_mg[3]; 
    uint16_t samples_collected = 0;
    uint32_t last_tick = HAL_GetTick();
    
    // Continuously collect samples until the buffer is full
    while (samples_collected < DATA_INPUT_USER) {
        // 1. Precisely control the sampling interval (1000Hz = 1ms)
        HAL_Delay(1);
            
        // 2. Read accelerometer data
        if (LSM6DSV16X_Read6AxisData(&lsm6dsv16x_dev_ctx, acc_mg, NULL) & 0x01) {
            // 3. Fill the NanoEdge buffer (store in X, Y, Z order alternately)
            input_buffer[samples_collected * AXIS_NUMBER + 0] = acc_mg[0];  // X
            input_buffer[samples_collected * AXIS_NUMBER + 1] = acc_mg[1];  // Y
            input_buffer[samples_collected * AXIS_NUMBER + 2] = acc_mg[2];  // Z
            samples_collected++;
        }
    }
}

int main(void)
{
  MPU_Config();

  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_I2C1_Init();
  MX_USART2_UART_Init();
  MX_USART1_UART_Init();
  MX_CRC_Init();
  GPS_Init(&huart1, &huart2); 
  MagIMU_Fusion_Init();
  MX_MEMS_Init();

  /* Initialization ------------------------------------------------------------*/
  enum neai_state error_code = neai_anomalydetection_init();

  if (error_code != NEAI_OK) {
    printf("error!\r\n");
    /* This happens if the library works into a not supported board. */
  }
  printf("study start!\r\n");
  /* Learning process ----------------------------------------------------------*/
  for (uint16_t iteration = 0 ; iteration < LEARNING_ITERATIONS ; iteration++) {
    fill_buffer(input_user_buffer);
    printf("learning %d/%d!\r\n",iteration,LEARNING_ITERATIONS);
    neai_anomalydetection_learn(input_user_buffer);
  }
  // neai_anomalydetection_knowledge(knowledge); // My second approach using static knowledge array.
 
  printf("study finish!\r\n");
  uint32_t last_print_time = HAL_GetTick();
  uint8_t similarity = 0;

  while (1)
  {
    // 1. Fill buffer and detect
    fill_buffer(input_user_buffer);
    neai_anomalydetection_detect(input_user_buffer, &similarity);

    // 2. Periodically print similarity (to avoid screen flooding)
    if (HAL_GetTick() - last_print_time >= 1000) {
      last_print_time = HAL_GetTick();
            
      // Print similarity information with timestamp
      printf("[%lu ms] similarity: %d%%\r\n", 
             (unsigned long) HAL_GetTick(), 
             similarity);
    }
        
    HAL_Delay(100); // Control detection frequency
  }
}
 

3. Debugging Steps Taken

  1. Data Integrity Check:

    • Verified accelerometer data is correctly sampled (printed raw values match expectations).

  2. Library Initialization:

    • Confirmed neai_anomalydetection_init() returns NEAI_OK.

  3. Timing & Buffer Size:

    • Ensured DATA_INPUT_USER matches the benchmark settings (256 samples).

  4. Knowledge Compatibility:

    • Cross-checked knowledge.h is generated for the same sensor configuration.


4. Request for Assistance

Could you help identify potential root causes? Specific questions:

  1. Are there known issues with NanoEdge AI v5.0.2 and STM32 deployment?

  2. Could the fixed similarity indicate a library initialization or data alignment problem?

  3. Should the learning phase include more iterations or different data preprocessing?

  4. Is there a way to dump internal model states for debugging?

Attached:

  • Full project code (if needed).

  • Benchmark/validation reports.

Thank you for your support!

Best regards,
dw1,

 

Hello @dw1 ,

Please review how to post a thread in this community. Especially the language used and the code sharing. 

Please refer to the following posts:

How to write your question to maximize your chances to find a solution

How to insert source code

If your question was not answered, why did you mark the solution?

 

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

Hello @dw1,

 

Thanks for the translation.

I see that you accepted my last message as solution. Did it solve the issue?

 

Here is complementary information:

  • Are there known issues with NanoEdge AI v5.0.2 and STM32 deployment?

Not known at least

  • Could the fixed similarity indicate a library initialization or data alignment problem?

It may be of various reasons, but based on experience, it is generally due to an issue in the user code.

  • Should the learning phase include more iterations or different data preprocessing?

In your case, this part is correct

  • Is there a way to dump internal model states for debugging?

No, but you can look at the neai_state return by every nanoedge function to see if you get any error.

I explained it here: Reason for abnormal similarity - STMicroelectronics Community

 

Have a good day,

Julian


In order to give better visibility on the answered topics, please click on 'Accept as Solution' on the reply which solved your issue or answered your question.

Subject: Follow-up Inquiry on neai_anomalydetection_learn Function Return Values

Dear Technical Support Team,

I am writing to follow up on my previous inquiry regarding the return values of the neai_anomalydetection_learn function during the self-learning phase, as the issue remains unresolved.

Current Observation:
The function consistently returns either 126 or 127 in my implementation.

Key Questions for Clarification:

  1. Successful Completion Criteria:

    • Does a single return value of 0 (NEAI_OK) conclusively indicate that the self-learning process is complete?

    • Or is it required to achieve NEAI_OK for a minimum number of iterations (e.g., as defined by MINIMUM_ITERATION_CALLS_FOR_EFFICIENT_LEARNING) to validate successful learning?

  2. Error Code Interpretation:

    • What are the precise meanings of return codes 126 and 127?

    • Do these codes signify a complete learning failure, or do they suggest that the learning process should be continued/retried?

Additional Context:

  • I have verified the sensor data quality and ensured proper initialization.

  • The issue persists despite adjusting iteration counts and input parameters.

I would greatly appreciate your expert guidance to resolve this matter. Please let me know if you require any additional details from my side.

Thank you for your time and support.

Best regards,

dw1,

Julian E.
ST Employee

Hello @dw1 ,

 

Error code 126 and 127 are as follow (I will edit the doc to add the error numbers):

enum neai_state {
	NEAI_OK = 0,
	NEAI_INIT_FCT_NOT_CALLED = 123,
	NEAI_BOARD_ERROR = 124, 
	NEAI_KNOWLEDGE_BUFFER_ERROR = 125,
	NEAI_NOT_ENOUGH_CALL_TO_LEARNING = 126,
	NEAI_MINIMAL_RECOMMENDED_LEARNING_DONE = 127,
	NEAI_UNKNOWN_ERROR = 128
};
#endif

 

I believe you print neai_state in your loop.

It is normal to get 126 until you reach LEARNING_ITERATIONS

 

Getting a single value of 0 (NEAI_OK) is enough.

 

Which IDE are you using?

You issue is still the similarity being wrong, just to be sure I understand correctly.

 

Can you share the nanoedge library and tell me what board you are using so that we can try to replicate.

 

Have a good day,

Julian


In order to give better visibility on the answered topics, please click on 'Accept as Solution' on the reply which solved your issue or answered your question.

Dear Julian,

I hope this email finds you well. I'm reaching out for your expertise regarding an anomaly detection implementation using the LSM6DSV16X accelerometer on an STM32H743VIT6 platform with Keil uVision 5.

 

Current Implementation:

  1. Data Collection:

    • Sampling at 100Hz (10ms intervals)

    • Collecting 3-axis accelerometer data in batches of 200 samples (3×200 values)

    • Using direct sensor reads via LSM6DSV16X_Read6AxisData()

  2. NanoEdge AI Integration:

    • Initialized with neai_anomalydetection_init()

    • Pre-loaded knowledge base using neai_anomalydetection_knowledge()

    • Continuous detection via neai_anomalydetection_detect()

Observed Issue:

The similarity output remains consistently at 0% despite motion variations. My test setup includes:

  • Verified sensor data streaming via UART (attached sample output)

  • Proper buffer formatting (interleaved X,Y,Z samples)

  • Successful library initialization (returns NEAI_OK)

    Core Questions:

     

  • For NanoEdge AI, I uploaded 100 datasets each with 3*200 samples for normal and abnormal data respectively. Is this dataset size too small? (Normal data shows significant but slightly slower up-and-down fluctuations, while abnormal data includes small fluctuations and static states.)
  • Are there any special restrictions when using pre-trained knowledge bases?
  • Could the reason for Similarity always being 0 be errors in the sampled data, such as sampling frequency or format issues?
Data Collection Function:
void fill_buffer(float input_buffer[]) {
    float acc_mg[3];  // Temporary storage for X/Y/Z samples
    uint16_t samples_collected = 0;
    uint32_t last_tick = HAL_GetTick();
    
    // Continuous collection until 200 samples are stored
    while (samples_collected < DATA_INPUT_USER) {
        // 1. Precise sampling interval control
        HAL_Delay(10);
            
        // 2. Read accelerometer data
        if (LSM6DSV16X_Read6AxisData(&lsm6dsv16x_dev_ctx, acc_mg, NULL) & 0x01) {
            // 3. Fill NanoEdge buffer (interleaved X,Y,Z order)
            input_buffer[samples_collected * AXIS_NUMBER + 0] = acc_mg[0];  // X
            input_buffer[samples_collected * AXIS_NUMBER + 1] = acc_mg[1];  // Y
            input_buffer[samples_collected * AXIS_NUMBER + 2] = acc_mg[2];  // Z
            samples_collected++;
        }
    }
}
UART Data Transmission Function:
#define SAMPLE_BUFFER_SIZE 200  // 200 samples per axis

// Global buffer (stores 200 samples)
float accel_buffer[SAMPLE_BUFFER_SIZE][3]; // [i][0]=X, [i][1]=Y, [i][2]=Z
uint16_t sample_count = 0;

void Send_Accel_Data_To_NanoEdge(UART_HandleTypeDef *huart) {
    float acc_mg[3];
    #define UART_BUF_SIZE 300  // Increased buffer size
    char uart_buf[UART_BUF_SIZE];
    uint16_t buf_pos = 0;
    uint8_t ret;

    // 1. Collect 200 samples
    while (sample_count < SAMPLE_BUFFER_SIZE) {
        ret = LSM6DSV16X_Read6AxisData(&lsm6dsv16x_dev_ctx, acc_mg, NULL);
        if (ret & 0x01) {
            accel_buffer[sample_count][0] = acc_mg[0];
            accel_buffer[sample_count][1] = acc_mg[1];
            accel_buffer[sample_count][2] = acc_mg[2];
            sample_count++;
            HAL_Delay(10);
        }
    }

    // 2. Format and transmit data
    for (int i = 0; i < SAMPLE_BUFFER_SIZE; i++) {
        int written = snprintf(&uart_buf[buf_pos], sizeof(uart_buf) - buf_pos,
                             "%.3f,%.3f,%.3f,",
                             accel_buffer[i][0],
                             accel_buffer[i][1],
                             accel_buffer[i][2]);
        
        if (written < 0) {
            // Handle formatting error
            break;
        }
        buf_pos += written;

        // Conservative transmission condition
        if (buf_pos > sizeof(uart_buf) - 30) {
            HAL_UART_Transmit(huart, (uint8_t*)uart_buf, buf_pos, HAL_MAX_DELAY);
            buf_pos = 0;
            HAL_Delay(1);  // Ensure transmission completion
        }
    }

    // 3. Send remaining data
    if (buf_pos > 0) {
        HAL_UART_Transmit(huart, (uint8_t*)uart_buf, buf_pos, HAL_MAX_DELAY);
    }
    HAL_UART_Transmit(huart, (uint8_t*)"\r\n", 2, HAL_MAX_DELAY);

    // 4. Reset counter
    sample_count = 0;
}
//main
int main(void) {
    // Initialization code omitted for brevity...
    
    enum neai_state error_code = neai_anomalydetection_init();
    if (error_code != NEAI_OK) {
        printf("Initialization error!\r\n");
    }
    
    printf("Knowledge loading start!\r\n");
    enum neai_state learn_status = neai_anomalydetection_knowledge(knowledge);
    printf("learn_status=%d\r\n", learn_status);
    
    uint32_t last_print_time = HAL_GetTick();
    uint8_t similarity = 0;
    
    while (1) {
        // 1. Fill buffer and perform detection
        fill_buffer(input_user_buffer);
        neai_anomalydetection_detect(input_user_buffer, &similarity);
        
        // 2. Periodic similarity output (every 1s)
        if (HAL_GetTick() - last_print_time >= 1000) {
            last_print_time = HAL_GetTick();
            printf("[%lu ms] similarity: %d%%\r\n", 
                 (unsigned long)HAL_GetTick(), 
                 similarity);
        }
        HAL_Delay(100); // Control detection frequency
    }
}
The attachments include:
  1. NanoEdge library
  2. Regular signals
  3. Abnormal signals

I would greatly appreciate your insights on potential implementation issues. Thank you for your time and support.

Best regards,
dw1.

Hello @dw1,

 

We believe that the issue is coming from keil. We had issues in the past with keil but we added code that should detect when using an arm compilation tool chain.

What is your compilation toolchain? Do you get any warning during compilation?

I don't see the similarity variable declaration in your main. Do you use the one from the nanoedge.h?

 

Have a good day,

Julian

 


In order to give better visibility on the answered topics, please click on 'Accept as Solution' on the reply which solved your issue or answered your question.