Modelli salvati riutilizzabili

Introduzione

TensorFlow Hub ospita SavedModels per TensorFlow 2, tra le altre risorse. Possono essere ricaricati in un programma Python con obj = hub.load(url) [ ulteriori informazioni ]. L' obj restituito è il risultato di tf.saved_model.load() (vedi la guida SavedModel di TensorFlow). Questo oggetto può avere attributi arbitrari che sono tf.functions, tf.Variables (inizializzati dai loro valori pre-addestrati), altre risorse e, ricorsivamente, altri oggetti simili.

Questa pagina descrive un'interfaccia che deve essere implementata obj caricato per essere riutilizzata in un programma TensorFlow Python. I SavedModel conformi a questa interfaccia sono chiamati Reusable SavedModels .

Riutilizzare significa costruire un modello più ampio attorno a obj , inclusa la possibilità di perfezionarlo. La messa a punto significa un ulteriore allenamento dei pesi obj caricato come parte del modello circostante. La funzione di perdita e l'ottimizzatore sono determinati dal modello circostante; obj definisce solo la mappatura delle attivazioni di input e output (il "passaggio in avanti"), eventualmente includendo tecniche come il dropout o la normalizzazione batch.

Il team di TensorFlow Hub consiglia di implementare l'interfaccia Reusable SavedModel in tutti i SavedModel destinati a essere riutilizzati nel senso sopra indicato. Molte utilità della libreria tensorflow_hub , in particolare hub.KerasLayer , richiedono SavedModels per implementarla.

Relazione con SignatureDefs

Questa interfaccia in termini di tf.functions e altre funzionalità di TF2 è separata dalle firme di SavedModel, che sono disponibili a partire da TF1 e continuano a essere utilizzate in TF2 per l'inferenza (come la distribuzione di SavedModels su TF Serving o TF Lite). Le firme per l'inferenza non sono sufficientemente espressive per supportare la messa a punto e tf.function fornisce un'API Python più naturale ed espressiva per il modello riutilizzato.

Relazione con le librerie di modellizzazione

Un SavedModel riutilizzabile utilizza solo le primitive TensorFlow 2, indipendentemente da qualsiasi particolare libreria di creazione di modelli come Keras o Sonnet. Ciò facilita il riutilizzo tra le librerie di costruzione del modello, libero da dipendenze dal codice di costruzione del modello originale.

Sarà necessario un certo grado di adattamento per caricare i modelli salvati riutilizzabili o salvarli da una determinata libreria di creazione di modelli. Per Keras, hub.KerasLayer fornisce il caricamento e il salvataggio integrato di Keras nel formato SavedModel è stato riprogettato per TF2 con l'obiettivo di fornire un superset di questa interfaccia (vedere RFC di maggio 2019).

Relazione con le "API comuni SavedModel" specifiche dell'attività

La definizione dell'interfaccia in questa pagina consente qualsiasi numero e tipo di ingressi e uscite. Le API Common SavedModel per TF Hub perfezionano questa interfaccia generale con convenzioni di utilizzo per attività specifiche per rendere i modelli facilmente intercambiabili.

Definizione dell'interfaccia

Attributi

Un SavedModel riutilizzabile è un SavedModel TensorFlow 2 tale che obj = tf.saved_model.load(...) restituisce un oggetto che ha i seguenti attributi

  • __call__ . Necessario. Una funzione tf. che implementa il calcolo del modello (il "passaggio in avanti") soggetto alle specifiche seguenti.

  • variables : un elenco di oggetti tf.Variable, che elenca tutte le variabili utilizzate da ogni possibile invocazione di __call__ , comprese quelle addestrabili e non addestrabili.

    Questo elenco può essere omesso se vuoto.

  • trainable_variables : un elenco di oggetti tf.Variable in modo tale che v.trainable sia vero per tutti gli elementi. Queste variabili devono essere un sottoinsieme di variables . Queste sono le variabili da addestrare durante la messa a punto dell'oggetto. Il creatore di SavedModel può scegliere di omettere qui alcune variabili che originariamente erano addestrabili per indicare che queste non devono essere modificate durante la messa a punto.

    Questo elenco può essere omesso se vuoto, in particolare se SavedModel non supporta la regolazione fine.

  • regularization_losses : un elenco di tf.functions, ciascuna delle quali accetta zero input e restituisce un singolo tensore scalare float. Per la messa a punto, si consiglia all'utente SavedModel di includerli come termini di regolarizzazione aggiuntivi nella perdita (nel caso più semplice senza ulteriore ridimensionamento). In genere, questi vengono utilizzati per rappresentare regolarizzatori di peso. (Per mancanza di input, queste tf.functions non possono esprimere regolatori di attività.)

    Questo elenco può essere omesso se vuoto, in particolare se SavedModel non supporta il fine tuning o non vuole prescrivere la regolarizzazione del peso.

La funzione __call__

Un obj SavedModel ripristinato ha un attributo obj.__call__ che è una funzione tf.function ripristinata e consente di chiamare obj come segue.

Sinossi (pseudo-codice):

outputs = obj(inputs, trainable=..., **kwargs)

Argomenti

Gli argomenti sono i seguenti.

  • Esiste un argomento posizionale obbligatorio con un batch di attivazioni di input di SavedModel. Il suo tipo è uno di

    • un singolo tensore per un singolo input,
    • un elenco di tensori per una sequenza ordinata di input senza nome,
    • un detto di tensori codificato da un particolare insieme di nomi di input.

    (Le revisioni future di questa interfaccia potrebbero consentire annidamenti più generali.) Il creatore di SavedModel sceglie uno di questi e le forme e i dtype tensoriali. Ove utile, alcune dimensioni della forma dovrebbero essere indefinite (in particolare la dimensione del lotto).

  • Potrebbe esserci un training facoltativo sull'argomento parola chiave che accetta un valore booleano Python, True o False . L'impostazione predefinita è False . Se il modello supporta la messa a punto e se il suo calcolo differisce tra i due (ad esempio, come nel dropout e nella normalizzazione batch), tale distinzione viene implementata con questo argomento. Altrimenti, questo argomento potrebbe essere assente.

    Non è necessario che __call__ accetti un argomento training con valore tensore. Spetta al chiamante utilizzare tf.cond() se necessario per effettuare l'invio tra di loro.

  • Il creatore di SavedModel può scegliere di accettare kwargs più facoltativi con nomi particolari.

    • Per gli argomenti con valori tensoriali, il creatore di SavedModel definisce i tipi e le forme consentiti. tf.function accetta un valore predefinito Python su un argomento tracciato con un input tf.TensorSpec. Tali argomenti possono essere utilizzati per consentire la personalizzazione degli iperparametri numerici coinvolti in __call__ (ad esempio, tasso di abbandono).

    • Per gli argomenti con valori Python, il creatore di SavedModel definisce i valori consentiti. Tali argomenti possono essere utilizzati come indicatori per effettuare scelte discrete nella funzione tracciata (ma attenzione all'esplosione combinatoria delle tracce).

La funzione __call__ ripristinata deve fornire tracce per tutte le combinazioni consentite di argomenti. L'inversione training tra True e False non deve modificare l'ammissibilità degli argomenti.

Risultato

Gli outputs della chiamata obj possono essere

  • un singolo Tensore per una singola uscita,
  • un elenco di tensori per una sequenza ordinata di output senza nome,
  • un dict di tensori codificato da un particolare insieme di nomi di output.

(Le revisioni future di questa interfaccia potrebbero consentire annidamenti più generali.) Il tipo restituito può variare a seconda dei kwargs con valore Python. Ciò consente ai flag di produrre output aggiuntivi. Il creatore di SavedModel definisce i tipi e le forme di output e la loro dipendenza dagli input.

Chiamabili nominati

Un SavedModel riutilizzabile può fornire più parti del modello nel modo descritto sopra inserendoli in sottooggetti con nome, ad esempio obj.foo , obj.bar e così via. Ogni sottooggetto fornisce un metodo __call__ e attributi di supporto sulle variabili ecc. specifici per quel pezzo del modello. Per l'esempio sopra, ci sarebbero obj.foo.__call__ , obj.foo.variables e così via.

Tieni presente che questa interfaccia non copre l'approccio di aggiungere una semplice tf.function direttamente come tf.foo .

È previsto che gli utenti di Reusable SavedModels gestiscano solo un livello di nidificazione ( obj.bar ma non obj.bar.baz ). (Le revisioni future di questa interfaccia potrebbero consentire una nidificazione più profonda e potrebbero rinunciare al requisito che l'oggetto di livello superiore sia esso stesso richiamabile.)

Osservazioni conclusive

Relazione con le API in-process

Questo documento descrive un'interfaccia di una classe Python che consiste di primitive come tf.function e tf.Variable che sopravvivono a un viaggio di andata e ritorno attraverso la serializzazione tramite tf.saved_model.save() e tf.saved_model.load() . Tuttavia, l'interfaccia era già presente sull'oggetto originale passato a tf.saved_model.save() . L'adattamento a tale interfaccia consente lo scambio di parti del modello tra API di creazione di modelli all'interno di un singolo programma TensorFlow.