Visualizza su TensorFlow.org | Esegui in Google Colab | Visualizza l'origine su GitHub | Scarica quaderno |
Un SavedModel contiene un programma TensorFlow completo, inclusi parametri addestrati (ad esempio, tf.Variable
s) e calcolo. Non richiede l'esecuzione del codice di costruzione del modello originale, il che lo rende utile per la condivisione o la distribuzione con TFLite , TensorFlow.js , TensorFlow Serving o TensorFlow Hub .
Puoi salvare e caricare un modello nel formato SavedModel utilizzando le seguenti API:
- API
tf.saved_model
di basso livello. Questo documento descrive in dettaglio come utilizzare questa API.- Salva:
tf.saved_model.save(model, path_to_dir)
- Carica:
model = tf.saved_model.load(path_to_dir)
- Salva:
- API
tf.keras.Model
di alto livello. Fare riferimento alla guida al salvataggio e alla serializzazione di keras . - Se vuoi solo salvare/caricare pesi durante l'allenamento, fai riferimento alla guida ai punti di controllo .
Creazione di un modello salvato da Keras
Per una rapida introduzione, questa sezione esporta un modello Keras pre-addestrato e serve con esso le richieste di classificazione delle immagini. Il resto della guida inserirà i dettagli e discuterà altri modi per creare modelli salvati.
import os
import tempfile
from matplotlib import pyplot as plt
import numpy as np
import tensorflow as tf
tmpdir = tempfile.mkdtemp()
physical_devices = tf.config.list_physical_devices('GPU')
for device in physical_devices:
tf.config.experimental.set_memory_growth(device, True)
file = tf.keras.utils.get_file(
"grace_hopper.jpg",
"https://storage.googleapis.com/download.tensorflow.org/example_images/grace_hopper.jpg")
img = tf.keras.utils.load_img(file, target_size=[224, 224])
plt.imshow(img)
plt.axis('off')
x = tf.keras.utils.img_to_array(img)
x = tf.keras.applications.mobilenet.preprocess_input(
x[tf.newaxis,...])
Downloading data from https://storage.googleapis.com/download.tensorflow.org/example_images/grace_hopper.jpg 65536/61306 [================================] - 0s 0us/step 73728/61306 [====================================] - 0s 0us/step
Utilizzerai un'immagine di Grace Hopper come esempio in esecuzione e un modello di classificazione delle immagini pre-addestrato Keras poiché è facile da usare. Anche i modelli personalizzati funzionano e verranno trattati in dettaglio in seguito.
labels_path = tf.keras.utils.get_file(
'ImageNetLabels.txt',
'https://storage.googleapis.com/download.tensorflow.org/data/ImageNetLabels.txt')
imagenet_labels = np.array(open(labels_path).read().splitlines())
Downloading data from https://storage.googleapis.com/download.tensorflow.org/data/ImageNetLabels.txt 16384/10484 [==============================================] - 0s 0us/step 24576/10484 [======================================================================] - 0s 0us/step
pretrained_model = tf.keras.applications.MobileNet()
result_before_save = pretrained_model(x)
decoded = imagenet_labels[np.argsort(result_before_save)[0,::-1][:5]+1]
print("Result before saving:\n", decoded)
Downloading data from https://storage.googleapis.com/tensorflow/keras-applications/mobilenet/mobilenet_1_0_224_tf.h5 17227776/17225924 [==============================] - 0s 0us/step 17235968/17225924 [==============================] - 0s 0us/step Result before saving: ['military uniform' 'bow tie' 'suit' 'bearskin' 'pickelhaube']
La previsione migliore per questa immagine è "uniforme militare".
mobilenet_save_path = os.path.join(tmpdir, "mobilenet/1/")
tf.saved_model.save(pretrained_model, mobilenet_save_path)
2021-10-27 01:24:27.831628: W tensorflow/python/util/util.cc:348] Sets are not currently considered sequences, but this may change in the future, so consider avoiding using them. INFO:tensorflow:Assets written to: /tmp/tmpbf9fpzwt/mobilenet/1/assets
Il percorso di salvataggio segue una convenzione utilizzata da TensorFlow Serving in cui l'ultimo componente del percorso ( 1/
qui) è un numero di versione per il modello: consente a strumenti come Tensorflow Serving di ragionare sulla relativa freschezza.
Puoi caricare di nuovo SavedModel in Python con tf.saved_model.load
e vedere come è classificata l'immagine dell'ammiraglio Hopper.
loaded = tf.saved_model.load(mobilenet_save_path)
print(list(loaded.signatures.keys())) # ["serving_default"]
['serving_default']
Le firme importate restituiscono sempre dizionari. Per personalizzare i nomi delle firme e le chiavi del dizionario di output, vedere Specifica delle firme durante l'esportazione .
infer = loaded.signatures["serving_default"]
print(infer.structured_outputs)
{'predictions': TensorSpec(shape=(None, 1000), dtype=tf.float32, name='predictions')}
L'esecuzione dell'inferenza da SavedModel fornisce lo stesso risultato del modello originale.
labeling = infer(tf.constant(x))[pretrained_model.output_names[0]]
decoded = imagenet_labels[np.argsort(labeling)[0,::-1][:5]+1]
print("Result after saving and loading:\n", decoded)
Result after saving and loading: ['military uniform' 'bow tie' 'suit' 'bearskin' 'pickelhaube']
Esecuzione di un modello salvato in TensorFlow Serving
I SavedModel sono utilizzabili da Python (ne parleremo più avanti), ma gli ambienti di produzione in genere utilizzano un servizio dedicato per l'inferenza senza eseguire codice Python. È facile da configurare da un modello salvato utilizzando TensorFlow Serving.
Consulta l' esercitazione REST di TensorFlow Serving per un esempio end-to-end di tensorflow.
Il formato SavedModel su disco
Un SavedModel è una directory contenente firme serializzate e lo stato necessario per eseguirle, inclusi valori di variabili e vocabolari.
ls {mobilenet_save_path}
assets saved_model.pb variables
Il file saved_model.pb
memorizza il programma TensorFlow, o modello, e una serie di firme con nome, ciascuna delle quali identifica una funzione che accetta input tensoriali e produce output tensoriali.
SavedModels può contenere più varianti del modello (più v1.MetaGraphDefs
, identificate con il flag --tag_set
su saved_model_cli
), ma questo è raro. Le API che creano più varianti di un modello includono tf.Estimator.experimental_export_all_saved_models
e in TensorFlow 1.x tf.saved_model.Builder
.
saved_model_cli show --dir {mobilenet_save_path} --tag_set serve
The given SavedModel MetaGraphDef contains SignatureDefs with the following keys: SignatureDef key: "__saved_model_init_op" SignatureDef key: "serving_default"
La directory delle variables
contiene un punto di controllo dell'addestramento standard (consultare la guida ai punti di controllo dell'addestramento ).
ls {mobilenet_save_path}/variables
variables.data-00000-of-00001 variables.index
La directory degli assets
contiene i file utilizzati dal grafico TensorFlow, ad esempio i file di testo utilizzati per inizializzare le tabelle del vocabolario. Non è utilizzato in questo esempio.
SavedModels può avere una directory assets.extra
per tutti i file non utilizzati dal grafico TensorFlow, ad esempio informazioni per i consumatori su cosa fare con SavedModel. TensorFlow stesso non utilizza questa directory.
Salvataggio di un modello personalizzato
tf.saved_model.save
supporta il salvataggio di oggetti tf.Module
e le sue sottoclassi, come tf.keras.Layer
e tf.keras.Model
.
Diamo un'occhiata a un esempio di salvataggio e ripristino di un tf.Module
.
class CustomModule(tf.Module):
def __init__(self):
super(CustomModule, self).__init__()
self.v = tf.Variable(1.)
@tf.function
def __call__(self, x):
print('Tracing with', x)
return x * self.v
@tf.function(input_signature=[tf.TensorSpec([], tf.float32)])
def mutate(self, new_v):
self.v.assign(new_v)
module = CustomModule()
Quando si salva un tf.Module
, tutti gli attributi tf.Variable
, i metodi tf.function
tf.function e i tf.Module
trovati tramite traversal ricorsivo vengono salvati. (Vedi il tutorial Checkpoint per ulteriori informazioni su questo attraversamento ricorsivo.) Tuttavia, tutti gli attributi, le funzioni e i dati Python vengono persi. Ciò significa che quando viene salvata una tf.function
, non viene salvato alcun codice Python.
Se non viene salvato alcun codice Python, in che modo SavedModel sa come ripristinare la funzione?
In breve, tf.function
funziona tracciando il codice Python per generare una ConcreteFunction (un wrapper richiamabile attorno a tf.Graph
). Quando salvi un tf.function
, stai davvero salvando la cache di ConcreteFunctions di tf.function
.
Per saperne di più sulla relazione tra tf.function
e ConcreteFunctions, vedere la guida tf.function .
module_no_signatures_path = os.path.join(tmpdir, 'module_no_signatures')
module(tf.constant(0.))
print('Saving model...')
tf.saved_model.save(module, module_no_signatures_path)
Tracing with Tensor("x:0", shape=(), dtype=float32) Saving model... Tracing with Tensor("x:0", shape=(), dtype=float32) INFO:tensorflow:Assets written to: /tmp/tmpbf9fpzwt/module_no_signatures/assets
Caricamento e utilizzo di un modello personalizzato
Quando carichi un SavedModel in Python, tutti gli attributi tf.Variable
, i metodi tf.function
tf.function e tf.Module
vengono ripristinati nella stessa struttura di oggetti del tf.Module
salvato originale.
imported = tf.saved_model.load(module_no_signatures_path)
assert imported(tf.constant(3.)).numpy() == 3
imported.mutate(tf.constant(2.))
assert imported(tf.constant(3.)).numpy() == 6
Poiché non viene salvato alcun codice Python, la chiamata a tf.function
con una nuova firma di input avrà esito negativo:
imported(tf.constant([3.]))
ValueError: Could not find matching function to call for canonicalized inputs ((,), {}). Only existing signatures are [((TensorSpec(shape=(), dtype=tf.float32, name=u'x'),), {})].
Messa a punto di base
Sono disponibili oggetti variabili ed è possibile eseguire il backprop tramite le funzioni importate. Questo è sufficiente per mettere a punto (cioè riqualificare) un SavedModel in casi semplici.
optimizer = tf.optimizers.SGD(0.05)
def train_step():
with tf.GradientTape() as tape:
loss = (10. - imported(tf.constant(2.))) ** 2
variables = tape.watched_variables()
grads = tape.gradient(loss, variables)
optimizer.apply_gradients(zip(grads, variables))
return loss
for _ in range(10):
# "v" approaches 5, "loss" approaches 0
print("loss={:.2f} v={:.2f}".format(train_step(), imported.v.numpy()))
loss=36.00 v=3.20 loss=12.96 v=3.92 loss=4.67 v=4.35 loss=1.68 v=4.61 loss=0.60 v=4.77 loss=0.22 v=4.86 loss=0.08 v=4.92 loss=0.03 v=4.95 loss=0.01 v=4.97 loss=0.00 v=4.98
Messa a punto generale
Un SavedModel di Keras fornisce più dettagli di un semplice __call__
per affrontare casi più avanzati di messa a punto. TensorFlow Hub consiglia di fornire quanto segue, se applicabile, in SavedModels condivisi ai fini della messa a punto:
- Se il modello usa dropout o un'altra tecnica in cui il passaggio in avanti differisce tra training e inferenza (come la normalizzazione batch), il metodo
__call__
accetta un argomentotraining=
opzionale con valore Python che per impostazione predefinita èFalse
ma può essere impostato suTrue
. - Accanto all'attributo
__call__
, ci sono gli attributi.variable
e.trainable_variable
con i corrispondenti elenchi di variabili. Una variabile originariamente addestrabile ma destinata a essere congelata durante l'ottimizzazione viene omessa da.trainable_variables
. - Per il bene di framework come Keras che rappresentano i regolatori di peso come attributi di livelli o sottomodelli, può esserci anche un attributo
.regularization_losses
. Contiene un elenco di funzioni ad argomento zero i cui valori sono destinati ad essere aggiunti alla perdita totale.
Tornando all'esempio iniziale di MobileNet, puoi vederne alcuni in azione:
loaded = tf.saved_model.load(mobilenet_save_path)
print("MobileNet has {} trainable variables: {}, ...".format(
len(loaded.trainable_variables),
", ".join([v.name for v in loaded.trainable_variables[:5]])))
MobileNet has 83 trainable variables: conv1/kernel:0, conv1_bn/gamma:0, conv1_bn/beta:0, conv_dw_1/depthwise_kernel:0, conv_dw_1_bn/gamma:0, ...
trainable_variable_ids = {id(v) for v in loaded.trainable_variables}
non_trainable_variables = [v for v in loaded.variables
if id(v) not in trainable_variable_ids]
print("MobileNet also has {} non-trainable variables: {}, ...".format(
len(non_trainable_variables),
", ".join([v.name for v in non_trainable_variables[:3]])))
MobileNet also has 54 non-trainable variables: conv1_bn/moving_mean:0, conv1_bn/moving_variance:0, conv_dw_1_bn/moving_mean:0, ...
Specifica delle firme durante l'esportazione
Strumenti come TensorFlow Serving e saved_model_cli
possono interagire con SavedModels. Per aiutare questi strumenti a determinare quali ConcreteFunctions utilizzare, è necessario specificare le firme di servizio. tf.keras.Model
s specifica automaticamente le firme di servizio, ma dovrai dichiarare esplicitamente una firma di servizio per i nostri moduli personalizzati.
Per impostazione predefinita, nessuna firma viene dichiarata in un tf.Module
personalizzato.
assert len(imported.signatures) == 0
Per dichiarare una firma di servizio, specifica una ConcreteFunction usando le signatures
kwarg. Quando si specifica una singola firma, la sua chiave di firma sarà 'serving_default'
, che viene salvata come costante tf.saved_model.DEFAULT_SERVING_SIGNATURE_DEF_KEY
.
module_with_signature_path = os.path.join(tmpdir, 'module_with_signature')
call = module.__call__.get_concrete_function(tf.TensorSpec(None, tf.float32))
tf.saved_model.save(module, module_with_signature_path, signatures=call)
Tracing with Tensor("x:0", dtype=float32) Tracing with Tensor("x:0", dtype=float32) INFO:tensorflow:Assets written to: /tmp/tmpbf9fpzwt/module_with_signature/assets
imported_with_signatures = tf.saved_model.load(module_with_signature_path)
list(imported_with_signatures.signatures.keys())
['serving_default']
Per esportare più firme, passa un dizionario di chiavi di firma a ConcreteFunctions. Ogni chiave di firma corrisponde a una ConcreteFunction.
module_multiple_signatures_path = os.path.join(tmpdir, 'module_with_multiple_signatures')
signatures = {"serving_default": call,
"array_input": module.__call__.get_concrete_function(tf.TensorSpec([None], tf.float32))}
tf.saved_model.save(module, module_multiple_signatures_path, signatures=signatures)
Tracing with Tensor("x:0", shape=(None,), dtype=float32) Tracing with Tensor("x:0", shape=(None,), dtype=float32) INFO:tensorflow:Assets written to: /tmp/tmpbf9fpzwt/module_with_multiple_signatures/assets
imported_with_multiple_signatures = tf.saved_model.load(module_multiple_signatures_path)
list(imported_with_multiple_signatures.signatures.keys())
['serving_default', 'array_input']
Per impostazione predefinita, i nomi dei tensori di output sono abbastanza generici, come output_0
. Per controllare i nomi degli output, modifica la tua tf.function
per restituire un dizionario che associa i nomi degli output agli output. I nomi degli input sono derivati dai nomi arg della funzione Python.
class CustomModuleWithOutputName(tf.Module):
def __init__(self):
super(CustomModuleWithOutputName, self).__init__()
self.v = tf.Variable(1.)
@tf.function(input_signature=[tf.TensorSpec([], tf.float32)])
def __call__(self, x):
return {'custom_output_name': x * self.v}
module_output = CustomModuleWithOutputName()
call_output = module_output.__call__.get_concrete_function(tf.TensorSpec(None, tf.float32))
module_output_path = os.path.join(tmpdir, 'module_with_output_name')
tf.saved_model.save(module_output, module_output_path,
signatures={'serving_default': call_output})
INFO:tensorflow:Assets written to: /tmp/tmpbf9fpzwt/module_with_output_name/assets
imported_with_output_name = tf.saved_model.load(module_output_path)
imported_with_output_name.signatures['serving_default'].structured_outputs
{'custom_output_name': TensorSpec(shape=(), dtype=tf.float32, name='custom_output_name')}
Carica un modello salvato in C++
La versione C++ del caricatore SavedModel fornisce un'API per caricare un SavedModel da un percorso, consentendo SessionOptions e RunOptions. Devi specificare i tag associati al grafico da caricare. La versione caricata di SavedModel è denominata SavedModelBundle e contiene MetaGraphDef e la sessione in cui viene caricata.
const string export_dir = ...
SavedModelBundle bundle;
...
LoadSavedModel(session_options, run_options, export_dir, {kSavedModelTagTrain},
&bundle);
Dettagli dell'interfaccia della riga di comando di SavedModel
È possibile utilizzare la SavedModel Command Line Interface (CLI) per ispezionare ed eseguire un SavedModel. Ad esempio, è possibile utilizzare la CLI per ispezionare i SignatureDef
del modello. L'interfaccia a riga di comando consente di confermare rapidamente che il tipo e la forma del tensore di input corrispondano al modello. Inoltre, se desideri testare il tuo modello, puoi utilizzare la CLI per eseguire un controllo di integrità passando input di esempio in vari formati (ad esempio, espressioni Python) e quindi recuperando l'output.
Installa la CLI SavedModel
In generale, puoi installare TensorFlow in uno dei due modi seguenti:
- Installando un binario TensorFlow predefinito.
- Costruendo TensorFlow dal codice sorgente.
Se hai installato TensorFlow tramite un binario TensorFlow predefinito, la CLI SavedModel è già installata sul tuo sistema in percorso bin/saved_model_cli
.
Se hai creato TensorFlow dal codice sorgente, devi eseguire il seguente comando aggiuntivo per creare saved_model_cli
:
$ bazel build tensorflow/python/tools:saved_model_cli
Panoramica dei comandi
La CLI SavedModel supporta i seguenti due comandi su un SavedModel:
-
show
, che mostra i calcoli disponibili da un SavedModel. -
run
, che esegue un calcolo da un SavedModel.
show
comando
Un SavedModel contiene una o più varianti del modello (tecnicamente, v1.MetaGraphDef
s), identificate dai relativi set di tag. Per servire un modello, potresti chiederti che tipo di SignatureDef
ci sono in ciascuna variante del modello e quali sono i loro input e output. Il comando show
consente di esaminare i contenuti di SavedModel in ordine gerarchico. Ecco la sintassi:
usage: saved_model_cli show [-h] --dir DIR [--all]
[--tag_set TAG_SET] [--signature_def SIGNATURE_DEF_KEY]
Ad esempio, il comando seguente mostra tutti i set di tag disponibili in SavedModel:
$ saved_model_cli show --dir /tmp/saved_model_dir
The given SavedModel contains the following tag-sets:
serve
serve, gpu
Il comando seguente mostra tutte le chiavi SignatureDef
disponibili per un set di tag:
$ saved_model_cli show --dir /tmp/saved_model_dir --tag_set serve
The given SavedModel `MetaGraphDef` contains `SignatureDefs` with the
following keys:
SignatureDef key: "classify_x2_to_y3"
SignatureDef key: "classify_x_to_y"
SignatureDef key: "regress_x2_to_y3"
SignatureDef key: "regress_x_to_y"
SignatureDef key: "regress_x_to_y2"
SignatureDef key: "serving_default"
Se sono presenti più tag nel set di tag, è necessario specificare tutti i tag, ciascuno separato da una virgola. Per esempio:
$ saved_model_cli show --dir /tmp/saved_model_dir --tag_set serve,gpu
Per mostrare tutti gli input e gli output TensorInfo per uno specifico SignatureDef
, passare la chiave SignatureDef
all'opzione signature_def
. Questo è molto utile quando vuoi conoscere il valore della chiave del tensore, dtype e la forma dei tensori di input per eseguire il grafico di calcolo in un secondo momento. Per esempio:
$ saved_model_cli show --dir \
/tmp/saved_model_dir --tag_set serve --signature_def serving_default
The given SavedModel SignatureDef contains the following input(s):
inputs['x'] tensor_info:
dtype: DT_FLOAT
shape: (-1, 1)
name: x:0
The given SavedModel SignatureDef contains the following output(s):
outputs['y'] tensor_info:
dtype: DT_FLOAT
shape: (-1, 1)
name: y:0
Method name is: tensorflow/serving/predict
Per mostrare tutte le informazioni disponibili in SavedModel, utilizzare l'opzione --all
. Per esempio:
$ saved_model_cli show --dir /tmp/saved_model_dir --all MetaGraphDef with tag-set: 'serve' contains the following SignatureDefs: signature_def['classify_x2_to_y3']: The given SavedModel SignatureDef contains the following input(s): inputs['inputs'] tensor_info: dtype: DT_FLOAT shape: (-1, 1) name: x2:0 The given SavedModel SignatureDef contains the following output(s): outputs['scores'] tensor_info: dtype: DT_FLOAT shape: (-1, 1) name: y3:0 Method name is: tensorflow/serving/classify ... signature_def['serving_default']: The given SavedModel SignatureDef contains the following input(s): inputs['x'] tensor_info: dtype: DT_FLOAT shape: (-1, 1) name: x:0 The given SavedModel SignatureDef contains the following output(s): outputs['y'] tensor_info: dtype: DT_FLOAT shape: (-1, 1) name: y:0 Method name is: tensorflow/serving/predict
run
il comando
Richiamare il comando di run
per eseguire un calcolo del grafico, passando gli input e quindi visualizzando (e facoltativamente salvando) gli output. Ecco la sintassi:
usage: saved_model_cli run [-h] --dir DIR --tag_set TAG_SET --signature_def
SIGNATURE_DEF_KEY [--inputs INPUTS]
[--input_exprs INPUT_EXPRS]
[--input_examples INPUT_EXAMPLES] [--outdir OUTDIR]
[--overwrite] [--tf_debug]
Il comando run
fornisce i tre modi seguenti per passare gli input al modello:
- L'opzione
--inputs
ti consente di passare numpy ndarray nei file. - L'opzione
--input_exprs
ti consente di passare le espressioni Python. -
--input_examples
opzione ti consente di passaretf.train.Example
.
--inputs
Per passare i dati di input nei file, specifica l'opzione --inputs
, che assume il seguente formato generale:
--inputs <INPUTS>
dove INPUTS è uno dei seguenti formati:
-
<input_key>=<filename>
-
<input_key>=<filename>[<variable_name>]
Puoi passare più INGRESSI . Se si passano più input, utilizzare un punto e virgola per separare ciascuno degli INPUTS .
saved_model_cli
usa numpy.load
per caricare il nome del file . Il nome del file può essere in uno dei seguenti formati:
-
.npy
-
.npz
- formato sottaceto
Un file .npy
contiene sempre un numpy ndarray. Pertanto, durante il caricamento da un file .npy
, il contenuto verrà assegnato direttamente al tensore di input specificato. Se specifichi un nome_variabile con quel file .npy
, il nome_variabile verrà ignorato e verrà emesso un avviso.
Quando si esegue il caricamento da un .npz
(zip), è possibile specificare facoltativamente un nome_variabile per identificare la variabile all'interno del file zip da caricare per la chiave tensore di input. Se non specifichi un nome_variabile , la CLI SavedModel verificherà che un solo file sia incluso nel file zip e lo caricherà per la chiave tensore di input specificata.
Durante il caricamento da un file pickle, se tra parentesi quadre non viene specificato alcun variable_name
, tutto ciò che si trova all'interno del file pickle verrà passato alla chiave tensore di input specificata. In caso contrario, la CLI SavedModel presumerà che un dizionario sia archiviato nel file pickle e verrà utilizzato il valore corrispondente a nome_variabile .
--input_exprs
Per passare gli input attraverso le espressioni Python, specifica l'opzione --input_exprs
. Questo può essere utile quando non hai file di dati in giro, ma vuoi comunque controllare il modello con alcuni semplici input che corrispondono al dtype e alla forma di SignatureDef
s del modello. Per esempio:
`<input_key>=[[1],[2],[3]]`
Oltre alle espressioni Python, puoi anche passare funzioni numpy. Per esempio:
`<input_key>=np.ones((32,32,3))`
(Nota che il modulo numpy
è già disponibile per te come np
.)
--input_examples
Per passare tf.train.Example
come input, specifica l'opzione --input_examples
. Per ogni chiave di input, richiede un elenco di dizionari, dove ogni dizionario è un'istanza di tf.train.Example
. Le chiavi del dizionario sono le caratteristiche ei valori sono le liste di valori per ciascuna caratteristica. Per esempio:
`<input_key>=[{"age":[22,24],"education":["BS","MS"]}]`
Salva output
Per impostazione predefinita, la CLI SavedModel scrive l'output su stdout. Se una directory viene passata all'opzione --outdir
, gli output verranno salvati come file .npy
denominati in base alle chiavi del tensore di output nella directory specificata.
Usa --overwrite
per sovrascrivere i file di output esistenti.