cancel
Showing results for 
Search instead for 
Did you mean: 

How to convert a float array to uint8_t array

KDeni.3
Associate II

Hi, I am trying to implement an audio classifier on stm32f746g-discovery board. I converted my keras model into a tflite file and successfully loaded it in the board.

I used integer only quantization on my model in order to decrease ram usage. I think it needs uint8_t type input. Currently I am having an issue converting float values to uint8_t type.

The model seems to be giving some outputs when I give some uint8_t array as an input but the outputs are nowhere near expected. 

Here is how I try to convert float values to uint8_t: 

 

float array[4290]; 

uint8_t sound[4290];

  for(int i=0; i<4290; i++){

  array[i] = 255*(array[i]-min)/(max-min);

  sound[i] = (int)array[i];

  }

Thanks a lot.

6 REPLIES 6
AScha.3
Chief II

what is "max -.. min " ?

and you know, what max/min level the float can have ??

if not, forget it.

If you feel a post has answered your question, please click "Accept as Solution".

I found max/min values using the code below:

   float max;

  float min;

  max = array[0];

  min = array[0];

  for(int i=0; i<4290; i++){

  if(i>0){

  if(array[i]>max){

  max = array[i];

  }

  if(array[i]<min){

  min = array[i];

  }

  }

AScha.3
Chief II

ok...but:

> I think it needs uint8_t type input.

think ?? didnt you set it , what you use ?

If you feel a post has answered your question, please click "Accept as Solution".

I know that it should be uint8_t type. After using quantization, I'm asking that how can I convert my float array to uint8_t type.

>how

  • just uint8 = float . if in range...if not, you should know, what you want ->
  • convert a known range to uint8 : uint8 = ( float/2000 ) +128; (- offset)
If you feel a post has answered your question, please click "Accept as Solution".
jean-michel.d
ST Employee

Hello KDeni,

Dynamic quantization scheme for the activations is not supported. This implied that the quantization parameter are computed during the quantization process, in your case, during the call of the TFLiteInterpreter with the calibration data. During this process, normally the provided calibration data have been normalized, typically between [0, 1.0] or [-1.0, 1.0]. The same normalization (or pre-processing) process is expected to feed the inference model.

For the conversion (float32 to uint8), you need to know the computed quantization parameters (scale + zero-point) values and to apply the following formula:

q_uint8 = (r_float32 / scale) + zero_point

Netron utility can be used to retreive these values or see the X-CUBE-AI documentation ("Embedded Inference Client API" article) to known how to retreive the scale/offset values from the deployed/generated code).

#define _MIN(x_, y_)  ( ((x_)<(y_)) ? (x_) : (y_) )
#define _MAX(x_, y_) ( ((x_)>(y_)) ? (x_) : (y_) )
#define _CLAMP(x_, min_, max_, type_)  (type_) (_MIN(_MAX(x_, min_), max_))
#define _ROUND(v_, type_)  (type_) ( ((v_)<0) ? ((v_)-0.5f) : ((v_)+0.5f) ) 
 
 scale = 1.0f / scale;
 
  /* Loop */
  for (int i=0; i < in_buffer_size; i++)
  {
    const ai_i32 tmp_ = zp + _ROUND(input_f[i] * scale, ai_i32);
    /* for ai_u8 */
    input_q[i] = _CLAMP(tmp_, 0, 255, ai_u8);
    /* for ai_i8 */
    /* input_q[i] = _CLAMP(tmp_, -128, 127, ai_i8); */
  }

Generally, if the calibration data was normallized between 0 and 1, we have scale = 1 / 255. and zp=0 for uint8_t data type.