7.4. Chargement d’un modèle

ml.Model lit un fichier de modèle depuis la mémoire flash, l’analyse, alloue la RAM dont le réseau a besoin pendant l’inférence, et renvoie un objet qui contient tout ce que le reste du script doit savoir sur le réseau chargé.

7.4.1. Le constructeur

Le constructeur prend un chemin et un post-processeur optionnel:

model = ml.Model("/rom/blazeface_front_128.tflite",
                 postprocess=BlazeFace())

Les modèles présents sur /rom/ (le système de fichiers résidant en flash) sont lus sur place : les poids du réseau restent en flash et le modèle chargé ne consomme que la taille de l’arène de tenseurs en RAM. Les modèles présents sur /sdcard/ sont copiés en RAM au moment du chargement, de sorte que le coût total est la taille du fichier de modèle plus l’arène de tenseurs. Les deux chemins fonctionnent ; le compromis porte sur la RAM.

Si un fichier .txt voisin portant le même nom de base existe, son contenu est chargé automatiquement dans labels. Le mot-clé postprocess= enregistre un appelable que predict() exécute après chaque inférence.

7.4.2. Propriétés en lecture seule

Un modèle chargé expose un petit ensemble de propriétés en lecture seule qui décrivent le réseau sans que personne ne l’exécute.

Fichier et mémoire.

  • len – taille du fichier de modèle sur disque, en octets.

  • ram – taille de l”arène de tenseurs dont le réseau a besoin pour ses activations intermédiaires pendant l’inférence, en octets.

Tenseurs d’entrée.

  • input_shape – une liste de tuples, un par tenseur d’entrée, donnant la forme que le réseau attend. Les réseaux de vision ont une seule entrée de forme (1, H, W, C).

  • input_dtype – liste de codes de type de données à un seul caractère ('b' int8, 'B' uint8, 'h' int16, 'H' uint16, 'f' float32), un par entrée.

  • input_scale et input_zero_point – les paramètres de quantification qui convertissent entre l’entrée à valeurs réelles sur laquelle le réseau a été entraîné et la représentation entière sur laquelle la caméra opère.

Tenseurs de sortie. Miroir de l’ensemble d’entrée : output_shape, output_dtype, output_scale, output_zero_point. Les réseaux de détection produisent deux ou trois tenseurs de sortie (boîtes, scores de confiance, parfois probabilités de classe) ; les réseaux de classification en produisent un.

Extras. labels est la liste des noms de classe chargée depuis le fichier .txt voisin, ou None. postprocess est le post-processeur enregistré, ou None.

7.4.3. Inspection de BlazeFace

Charger le modèle BlazeFace fourni et afficher chaque propriété donne les valeurs réelles:

import ml
from ml.postprocessing.mediapipe import BlazeFace

model = ml.Model("/rom/blazeface_front_128.tflite",
                 postprocess=BlazeFace())

print("file size:    ", model.len, "bytes")
print("tensor arena: ", model.ram, "bytes")
print("input shape:  ", model.input_shape)
print("input dtype:  ", model.input_dtype)
print("input scale:  ", model.input_scale)
print("input zp:     ", model.input_zero_point)
print("output shape: ", model.output_shape)
print("output dtype: ", model.output_dtype)
print("output scale: ", model.output_scale)
print("output zp:    ", model.output_zero_point)

Les valeurs identifient concrètement l’interface du réseau : un seul tenseur d’entrée int8 (1, 128, 128, 3) et deux sorties int8 – l’une pour les coefficients de régression des boîtes, l’autre pour les scores de confiance par ancre. Les paramètres de quantification décrivent comment ces valeurs int8 correspondent aux flottants réels sur lesquels le réseau a été entraîné ; le post-processeur les utilise pour annuler la quantification avant de décoder les boîtes.

Chaque propriété est la source unique de vérité pour ce qu’elle décrit. Les scripts lisent input_shape pour savoir avec quelle résolution capturer, lisent output_scale et output_zero_point pour décoder les tenseurs manuellement, et lisent labels pour obtenir des noms de classe lisibles par l’humain – jamais codés en dur, jamais supposés.