Questa pagina è stata tradotta dall'API Cloud Translation.
Switch to English

Modelli salvati dall'hub TF in TensorFlow 2

Il formato SavedModel di TensorFlow 2 è il modo consigliato per condividere modelli pre-addestrati e parti del modello su TensorFlow Hub. Sostituisce il vecchio formato Hub TF1 e viene fornito con un nuovo set di API.

Questa pagina spiega come riutilizzare TF2 SavedModels in un programma TensorFlow 2 con l'API hub.load() basso livello e il suo wrapper hub.KerasLayer . (In genere, hub.KerasLayer è combinato con altri tf.keras.layers per creare un modello Keras o il model_fn di un estimatore TF2.) Queste API possono anche caricare i modelli legacy nel formato Hub TF1, entro i limiti, vedere la guida alla compatibilità .

Gli utenti di TensorFlow 1 possono eseguire l'aggiornamento a TF 1.15 e quindi utilizzare le stesse API. Le versioni precedenti di TF1 non funzionano.

Utilizzo di SavedModels da TF Hub

Utilizzo di un modello salvato in Keras

Keras è l'API di alto livello di TensorFlow per la creazione di modelli di deep learning componendo oggetti Keras Layer. La libreria tensorflow_hub fornisce la classe hub.KerasLayer che viene inizializzata con l'URL (o il percorso del file system) di un SavedModel e quindi fornisce il calcolo da SavedModel, inclusi i suoi pesi pre-addestrati.

Di seguito è riportato un esempio di utilizzo di un incorporamento di testo pre-addestrato:

import tensorflow as tf
import tensorflow_hub as hub

hub_url = "https://tfhub.dev/google/tf2-preview/nnlm-en-dim128/1"
embed = hub.KerasLayer(hub_url)
embeddings = embed(["A long sentence.", "single-word", "http://example.com"])
print(embeddings.shape, embeddings.dtype)

Da questo, un classificatore di testo può essere costruito nel solito modo di Keras:

model = tf.keras.Sequential([
    embed,
    tf.keras.layers.Dense(16, activation="relu"),
    tf.keras.layers.Dense(1, activation="sigmoid"),
])

La colonna di classificazione del testo è un esempio completo di come addestrare e valutare un tale classificatore.

I pesi del modello in un hub.KerasLayer sono impostati su non addestrabile per impostazione predefinita. Vedere la sezione sulla messa a punto di seguito per come cambiarlo. I pesi sono condivisi tra tutte le applicazioni dello stesso oggetto livello, come al solito in Keras.

Utilizzo di un modello salvato in uno stimatore

Gli utenti dell'API Estimator di TensorFlow per l'addestramento distribuito possono utilizzare SavedModels da TF Hub scrivendo il loro model_fn in termini di hub.KerasLayer tra gli altri tf.keras.layers .

Dietro le quinte: download e memorizzazione nella cache di SavedModel

L'utilizzo di un SavedModel da TensorFlow Hub (o altri server HTTPS che implementano il suo protocollo di hosting ) lo scarica e lo decomprime nel filesystem locale se non è già presente. La variabile d'ambiente TFHUB_CACHE_DIR può essere impostata per sovrascrivere la posizione temporanea predefinita per la memorizzazione nella cache dei SavedModels scaricati e non compressi. Per i dettagli, vedere Memorizzazione nella cache .

Utilizzo di un SavedModel in TensorFlow di basso livello

La funzione hub.load(handle) scarica e decomprime un SavedModel (a meno che l' handle non sia già un percorso del file system) e quindi restituisce il risultato del caricamento con la funzione integrata di TensorFlow tf.saved_model.load() . Pertanto, hub.load() può gestire qualsiasi SavedModel valido (a differenza del suo predecessore hub.Module per TF1).

Argomento avanzato: cosa aspettarsi da SavedModel dopo il caricamento

A seconda del contenuto di SavedModel, il risultato di obj = hub.load(...) può essere richiamato in vari modi (come spiegato in modo molto più dettagliato nella Guida SavedModel di TensorFlow:

  • Le firme di servizio di SavedModel (se presenti) sono rappresentate come un dizionario di funzioni concrete e possono essere chiamate come tensors_out = obj.signatures["serving_default"](**tensors_in) , con dizionari di tensori codificati dal rispettivo input e output nomi e soggetti ai vincoli di forma e dtype della firma.

  • I metodi @tf.function -decorated dell'oggetto salvato (se presenti) vengono ripristinati come oggetti tf.function che possono essere chiamati da tutte le combinazioni di argomenti Tensor e non-Tensor per i quali la funzione tf. era stata tracciata prima del salvataggio. In particolare, se esiste un metodo obj.__call__ con tracce adeguate, obj stesso può essere chiamato come una funzione Python. Un semplice esempio potrebbe apparire come output_tensor = obj(input_tensor, training=False) .

Questo lascia un'enorme libertà nelle interfacce che possono essere implementate da SavedModels. L' interfaccia Reusable SavedModels per obj stabilisce convenzioni tali che il codice client, inclusi gli adattatori come hub.KerasLayer , sappia utilizzare SavedModel.

Alcuni SavedModels potrebbero non seguire tale convenzione, in particolare modelli interi non destinati a essere riutilizzati in modelli più grandi e fornire solo firme di servizio.

Le variabili addestrabili in un SavedModel vengono ricaricate come tf.GradientTape e tf.GradientTape le guarderà per impostazione predefinita. Vedere la sezione sulla messa a punto di seguito per alcuni avvertimenti e considerare di evitare questo per i principianti. Anche se vuoi mettere a punto, potresti voler vedere se obj.trainable_variables consiglia di ri-addestrare solo un sottoinsieme delle variabili allenabili originariamente.

Creazione di SavedModels per TF Hub

Panoramica

SavedModel è il formato di serializzazione standard di TensorFlow per modelli addestrati o pezzi di modello. Memorizza i pesi addestrati del modello insieme alle esatte operazioni di TensorFlow per eseguire il suo calcolo. Può essere utilizzato indipendentemente dal codice che lo ha creato. In particolare, può essere riutilizzato in diverse API di creazione di modelli di alto livello come Keras, perché le operazioni TensorFlow sono il loro linguaggio di base comune.

Risparmio da Keras

A partire da TensorFlow 2, tf.keras.Model.save() e tf.keras.models.save_model() impostazione predefinita il formato SavedModel (non HDF5). I SavedModels risultanti che possono essere utilizzati con hub.load() , hub.KerasLayer e adattatori simili per altre API di alto livello non appena diventano disponibili.

Per condividere un modello Keras completo, salvalo con include_optimizer=False .

Per condividere un pezzo di un modello Keras, rendi il pezzo un modello in sé e poi salvalo. Puoi disporre il codice in questo modo dall'inizio ...

piece_to_share = tf.keras.Model(...)
full_model = tf.keras.Sequential([piece_to_share, ...])
full_model.fit(...)
piece_to_share.save(...)

... o ritaglia il pezzo da condividere dopo il fatto (se si allinea con la stratificazione del tuo modello completo):

full_model = tf.keras.Model(...)
sharing_input = full_model.get_layer(...).get_output_at(0)
sharing_output = full_model.get_layer(...).get_output_at(0)
piece_to_share = tf.keras.Model(sharing_input, sharing_output)
piece_to_share.save(..., include_optimizer=False)

TensorFlow Models su GitHub utilizza il primo approccio per BERT (vedi nlp / bert / bert_models.py e nlp / bert / export_tfhub.py , nota la divisione tra core_model e pretrain_model ) e l'ultimo approccio per ResNet (vedi vision / image_classification / tfhub_export .py ).

Risparmio da TensorFlow di basso livello

Ciò richiede una buona familiarità con la guida SavedModel di TensorFlow.

Se desideri fornire più di una semplice firma di pubblicazione, devi implementare l' interfaccia Reusable SavedModel . Concettualmente, questo sembra

class MyMulModel(tf.train.Checkpoint):
  def __init__(self, v_init):
    super(MyMulModel, self).__init__()
    self.v = tf.Variable(v_init)
    self.variables = [self.v]
    self.trainable_variables = [self.v]
    self.regularization_losses = [
        tf.function(input_signature=[])(lambda: 0.001 * self.v**2),
    ]

  @tf.function(input_signature=[tf.TensorSpec(shape=None, dtype=tf.float32)])
  def __call__(self, inputs):
    return tf.multiply(inputs, self.v)

tf.saved_model.save(MyMulModel(2.0), "/tmp/my_mul")

layer = hub.KerasLayer("/tmp/my_mul")
print(layer([10., 20.]))  # [20., 40.]
layer.trainable = True
print(layer.trainable_weights)  # [2.]
print(layer.losses)  # 0.004

Il codice in tensorflow / examples / saved_model / integration_tests / contiene esempi più grandi, esp. la coppia export_mnist.py e use_mnist.py .

Ritocchi

L'addestramento delle variabili già addestrate di un SavedModel importato insieme a quelle del modello attorno ad esso viene chiamato regolazione fine del SavedModel. Ciò può portare a una migliore qualità, ma spesso rende la formazione più impegnativa (può richiedere più tempo, dipendere maggiormente dall'ottimizzatore e dai suoi iperparametri, aumentare il rischio di overfitting e richiedere l'aumento del set di dati, specialmente per le CNN). Consigliamo ai consumatori di SavedModel di esaminare la messa a punto solo dopo aver stabilito un buon regime di formazione e solo se l'editore di SavedModel lo consiglia.

L'ottimizzazione fine modifica i parametri del modello "continuo" addestrato. Non modifica le trasformazioni hard-coded, come la tokenizzazione dell'input di testo e il mapping dei token alle voci corrispondenti in una matrice di incorporamento.

Per i consumatori di SavedModel

Creare un hub.KerasLayer come hub.KerasLayer

layer = hub.KerasLayer(..., trainable=True)

abilita la regolazione fine del SavedModel caricato dal layer. Aggiunge i pesi addestrabili e i regolarizzatori di peso dichiarati in SavedModel al modello Keras ed esegue il calcolo di SavedModel in modalità training (pensa al dropout ecc.).

La colonna di classificazione delle immagini contiene un esempio end-to-end con regolazione fine opzionale.

Riesportazione del risultato della regolazione fine

Gli utenti avanzati potrebbero voler salvare i risultati della regolazione fine in un SavedModel che può essere utilizzato al posto di quello originariamente caricato. Questo può essere fatto con codice come

loaded_obj = hub.load("https://tfhub.dev/...")
hub_layer = hub.KerasLayer(loaded_obj, trainable=True, ...)

model = keras.Sequential([..., hub_layer, ...])
model.compile(...)
model.fit(...)

export_module_dir = os.path.join(os.getcwd(), "finetuned_model_export")
tf.saved_model.save(loaded_obj, export_module_dir)

Per i creatori di SavedModel

Quando crei un SavedModel per la condivisione su TensorFlow Hub, pensa in anticipo se e come i suoi consumatori dovrebbero ottimizzarlo e fornisci indicazioni nella documentazione.

Salvare da un modello Keras dovrebbe far funzionare tutti i meccanismi di messa a punto (risparmio di perdite di regolarizzazione del peso, dichiarazione di variabili __call__ , tracciamento __call__ sia per training=True che training=False , ecc.)

Scegli un'interfaccia del modello che funzioni bene con il flusso del gradiente, ad esempio logit di output invece di probabilità softmax o previsioni top-k.

Se il modello utilizza dropout, normalizzazione batch o tecniche di addestramento simili che implicano iperparametri, impostarli su valori che abbiano senso per molti problemi di destinazione previsti e dimensioni batch. (Al momento della stesura di questo articolo, il salvataggio da Keras non rende facile consentire ai consumatori di modificarli, ma vedi tensorflow / examples / saved_model / integration_tests / export_mnist_cnn.py per alcune soluzioni alternative.)

I regolarizzatori di peso sui singoli strati vengono salvati (con i loro coefficienti di forza di regolarizzazione), ma la regolarizzazione del peso dall'interno dell'ottimizzatore (come tf.keras.optimizers.Ftrl.l1_regularization_strength=...) ) viene persa. Consiglia i consumatori del tuo SavedModel di conseguenza.