7.4. Carregando um modelo¶
ml.Model lê um arquivo de modelo da flash, faz o seu parsing, aloca a RAM que a rede precisa durante a inferência e retorna um objeto que carrega tudo o que o restante do script precisa saber sobre a rede carregada.
7.4.1. O construtor¶
O construtor recebe um caminho e um pós-processador opcional:
model = ml.Model("/rom/blazeface_front_128.tflite",
postprocess=BlazeFace())
Modelos em /rom/ (o sistema de arquivos residente na flash) são lidos diretamente no lugar: os pesos da rede permanecem na flash e o modelo carregado consome apenas a RAM correspondente ao tensor arena. Modelos em /sdcard/ são copiados para a RAM no momento do carregamento, portanto o custo total é o tamanho do arquivo do modelo mais o tensor arena. Qualquer um dos caminhos funciona; o trade-off é a RAM.
Se existir um arquivo .txt irmão com o mesmo nome base, seu conteúdo é carregado automaticamente em labels. A palavra-chave postprocess= registra um chamável que predict() executa após cada inferência.
7.4.2. Propriedades somente leitura¶
Um modelo carregado expõe um pequeno conjunto de propriedades somente leitura que descrevem a rede sem que ninguém precise executá-la.
Arquivo e memória.
len– tamanho do arquivo de modelo em disco, em bytes.ram– tamanho do tensor arena que a rede precisa para suas ativações intermediárias durante a inferência, em bytes.
Tensores de entrada.
input_shape– uma lista de tuplas, uma por tensor de entrada, indicando o formato que a rede espera. Redes de visão têm uma entrada com formato(1, H, W, C).input_dtype– lista de códigos de dtype de caractere único ('b'int8,'B'uint8,'h'int16,'H'uint16,'f'float32), um por entrada.input_scaleeinput_zero_point– os parâmetros de quantização que convertem entre a entrada com valor real na qual a rede foi treinada e a representação inteira contra a qual a câmera executa.
Tensores de saída. Espelho do conjunto de entrada: output_shape, output_dtype, output_scale, output_zero_point. Redes de detecção produzem dois ou três tensores de saída (caixas, pontuações de confiança e, às vezes, probabilidades de classe); redes de classificação produzem um.
Extras. labels é a lista de nomes de classe carregada do arquivo .txt irmão, ou None. postprocess é o pós-processador registrado, ou None.
7.4.3. Inspecionando o BlazeFace¶
Carregar o modelo BlazeFace que acompanha o produto e imprimir cada propriedade fornece os números reais:
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)
Os números identificam concretamente a interface da rede: um único tensor de entrada (1, 128, 128, 3) int8 e duas saídas int8 – uma para os coeficientes de regressão de caixas e outra para as pontuações de confiança por âncora. Os parâmetros de quantização descrevem como esses valores int8 mapeiam para os floats reais contra os quais a rede foi treinada; o pós-processador os utiliza para desfazer a quantização antes de decodificar as caixas.
Cada propriedade é a única fonte de verdade para aquilo que descreve. Os scripts leem input_shape para saber em que formato capturar, leem output_scale e output_zero_point para decodificar tensores manualmente e leem labels para nomes de classe legíveis por humanos – nunca codificados manualmente, nunca presumidos.