STM32N6 NPU Deployment — Politecnico di Milano  1.0
Documentation for Neural Network Deployment on STM32N6 NPU - Politecnico di Milano 2024-2025
preprocess.py
Go to the documentation of this file.
1 # /*---------------------------------------------------------------------------------------------
2 # * Copyright (c) 2024 STMicroelectronics.
3 # * All rights reserved.
4 # *
5 # * This software is licensed under terms that can be found in the LICENSE file in
6 # * the root directory of this software component.
7 # * If no LICENSE file comes with this software, it is provided AS-IS.
8 # *--------------------------------------------------------------------------------------------*/
9 
10 
20 Authors: Giacomo Colosio, Sebastiano Colosio, Patrizio Acquadro, Tito Nicola Drugman
21 #
22 # @copyright Copyright (c) 2023-2024 STMicroelectronics. All rights reserved.
23 
24 
25 from omegaconf import DictConfig
26 import numpy as np
27 import tensorflow as tf
28 from typing import Tuple
29 import sys
30 import os
31 
32 from common.utils import get_model_name_and_its_input_shape
33 from .data_loader import load_dataset
34 
35 
36 def preprocess(cfg: DictConfig = None) -> Tuple:
37  """
38  Preprocesses the data based on the provided configuration.
39 
40  Args:
41  cfg (DictConfig): Configuration object containing the settings.
42 
43  Returns:
44  Tuple: A tuple containing the following:
45  - data_augmentation (object): Data augmentation object.
46  - augment (bool): Flag indicating whether data augmentation is enabled.
47  - pre_process (object): Preprocessing object.
48  - train_ds (object): Training dataset.
49  - valid_ds (object): Validation dataset.
50  """
51 
52  # Get the model input shape
53  if cfg.general.model_path:
54  _, input_shape = get_model_name_and_its_input_shape(cfg.general.model_path)
55  else:
56  # We are running a training using the 'training' section of the config file.
57  if cfg.training.model:
58  input_shape = cfg.training.model.input_shape
59  else:
60  _, input_shape = get_model_name_and_its_input_shape(cfg.training.resume_training_from)
61 
62  interpolation = cfg.preprocessing.resizing.interpolation
63  aspect_ratio = cfg.preprocessing.resizing.aspect_ratio
64 
65  # Set a default value to 32 for the 'evaluation' mode
66  # in case a 'training' section is not available
67  batch_size = cfg.training.batch_size if cfg.training else 32
68 
69  train_ds, valid_ds, quantization_ds, test_ds = load_dataset(
70  dataset_name=cfg.dataset.name,
71  training_path=cfg.dataset.training_path,
72  validation_path=cfg.dataset.validation_path,
73  quantization_path=cfg.dataset.quantization_path,
74  test_path=cfg.dataset.test_path,
75  validation_split=cfg.dataset.validation_split,
76  nbr_keypoints=cfg.dataset.keypoints,
77  image_size= input_shape[1:] if cfg.general.model_path and cfg.general.model_path.split('.')[-1]=='onnx' else input_shape[:2],
78  interpolation=interpolation,
79  aspect_ratio=aspect_ratio,
80  color_mode=cfg.preprocessing.color_mode,
81  batch_size=batch_size,
82  seed=cfg.dataset.seed)
83 
84  return train_ds, valid_ds, quantization_ds, test_ds
85 
86 
87 def apply_rescaling(dataset: tf.data.Dataset = None, scale: float = None, offset: float = None):
88  """
89  Applies rescaling to a dataset using a tf.keras.Sequential model.
90 
91  Args:
92  dataset (tf.data.Dataset): The dataset to be rescaled.
93  scale (float): The scaling factor.
94  offset (float): The offset factor.
95 
96  Returns:
97  The rescaled dataset.
98  """
99  # Define the rescaling model
100  rescaling = tf.keras.Sequential([
101  tf.keras.layers.Rescaling(scale, offset)
102  ])
103 
104  # Apply the rescaling to the dataset
105  rescaled_dataset = dataset.map(lambda x, y: (rescaling(x), y))
106 
107  return rescaled_dataset
108 
109 
110 
111 def preprocess_input(image: np.ndarray, input_details: dict) -> tf.Tensor:
112  """
113  Preprocesses an input image according to input details.
114 
115  Args:
116  image: Input image as a NumPy array.
117  input_details: Dictionary containing input details, including quantization and dtype.
118 
119  Returns:
120  Preprocessed image as a TensorFlow tensor.
121 
122  """
123 
124  image = tf.image.resize(image, (input_details['shape'][1], input_details['shape'][2]))
125  # Get the dimensions
126  if input_details['dtype'] in [np.uint8, np.int8]:
127  image_processed = (image / input_details['quantization'][0]) + input_details['quantization'][1]
128  image_processed = np.clip(np.round(image_processed), np.iinfo(input_details['dtype']).min,
129  np.iinfo(input_details['dtype']).max)
130 
131  else:
132  image_processed = image
133  image_processed = tf.cast(image_processed, dtype=input_details['dtype'])
134  image_processed = tf.expand_dims(image_processed, 0)
135  return image_processed
136 
Tuple[tf.data.Dataset, tf.data.Dataset, tf.data.Dataset] load_dataset(str dataset_name=None, str training_path=None, str validation_path=None, str quantization_path=None, str test_path=None, float validation_split=None, int nbr_keypoints=None, tuple[int] image_size=None, str interpolation=None, str aspect_ratio=None, str color_mode=None, int batch_size=None, int seed=None)
Definition: data_loader.py:364
tf.Tensor preprocess_input(np.ndarray image, dict input_details)
Definition: preprocess.py:111
Tuple preprocess(DictConfig cfg=None)
Definition: preprocess.py:36
def apply_rescaling(tf.data.Dataset dataset=None, float scale=None, float offset=None)
Definition: preprocess.py:87