Formato hub TF1

Al suo lancio nel 2018, TensorFlow Hub offriva un unico tipo di risorsa: il formato TF1 Hub per l'importazione nei programmi TensorFlow 1.

Questa pagina spiega come utilizzare il formato TF1 Hub in TF1 (o la modalità di compatibilità TF1 di TF2) con la classe hub.Module e le API associate. (L'uso tipico è costruire un tf.Graph , possibilmente all'interno di un TF1 Estimator , combinando uno o più modelli in formato TF1 Hub con tf.compat.layers o tf.layers ).

Gli utenti di TensorFlow 2 (al di fuori della modalità di compatibilità TF1) devono utilizzare la nuova API con hub.load() o hub.KerasLayer . La nuova API carica il nuovo tipo di risorsa TF2 SavedModel, ma ha anche un supporto limitato per il caricamento del formato TF1 Hub in TF2 .

Utilizzo di un modello in formato TF1 Hub

Istanziazione di un modello in formato TF1 Hub

Un modello in formato TF1 Hub viene importato in un programma TensorFlow creando un oggetto hub.Module da una stringa con il relativo URL o percorso del filesystem, ad esempio:

m = hub.Module("path/to/a/module_dir")

Questo aggiunge le variabili del modulo al grafico TensorFlow corrente. L'esecuzione dei loro inizializzatori leggerà i loro valori pre-addestrati dal disco. Allo stesso modo, al grafico vengono aggiunte tabelle e altri stati.

Moduli di memorizzazione nella cache

Quando si crea un modulo da un URL, il contenuto del modulo viene scaricato e memorizzato nella cache nella directory temporanea del sistema locale. La posizione in cui i moduli sono memorizzati nella cache può essere sovrascritta utilizzando la variabile di ambiente TFHUB_CACHE_DIR . Per i dettagli, vedere Memorizzazione nella cache .

Applicazione di un modulo

Una volta istanziato, un modulo m può essere chiamato zero o più volte come una funzione Python da input tensore a output tensore:

y = m(x)

Ciascuna di queste chiamate aggiunge operazioni al grafico TensorFlow corrente per calcolare y da x . Se si tratta di variabili con pesi addestrati, queste vengono condivise tra tutte le applicazioni.

I moduli possono definire più firme con nome per consentire l'applicazione in più di un modo (simile a come gli oggetti Python hanno metodi ). La documentazione di un modulo dovrebbe descrivere le firme disponibili. La chiamata di cui sopra applica la firma denominata "default" . Qualsiasi firma può essere selezionata passando il suo nome all'argomento opzionale signature= .

Se una firma ha più input, devono essere passati come dict, con le chiavi definite dalla firma. Allo stesso modo, se una firma ha più output, questi possono essere recuperati come dict passando as_dict=True , sotto le chiavi definite dalla firma (la chiave "default" è per il singolo output restituito se as_dict=False ). Quindi la forma più generale di applicazione di un modulo è simile a:

outputs = m(dict(apples=x1, oranges=x2), signature="fruit_to_pet", as_dict=True)
y1 = outputs["cats"]
y2 = outputs["dogs"]

Un chiamante deve fornire tutti gli ingressi definiti da una firma, ma non è necessario utilizzare tutte le uscite di un modulo. TensorFlow eseguirà solo quelle parti del modulo che finiscono come dipendenze di una destinazione in tf.Session.run() . In effetti, gli editori di moduli possono scegliere di fornire vari output per usi avanzati (come l'attivazione di livelli intermedi) insieme agli output principali. I consumatori del modulo dovrebbero gestire le uscite aggiuntive con garbo.

Provare moduli alternativi

Ogni volta che sono presenti più moduli per la stessa attività, TensorFlow Hub incoraggia a dotarli di firme (interfacce) compatibili in modo tale che provarne di diversi sia facile come variare l'handle del modulo come un iperparametro con valori di stringa.

A tal fine, manteniamo una raccolta di firme comuni consigliate per le attività più comuni.

Creazione di un nuovo modulo

Nota di compatibilità

Il formato TF1 Hub è orientato verso TensorFlow 1. È supportato solo parzialmente da TF Hub in TensorFlow 2. Considera invece la pubblicazione nel nuovo formato TF2 SavedModel .

Il formato TF1 Hub è simile al formato SavedModel di TensorFlow 1 a livello sintattico (stessi nomi di file e messaggi di protocollo) ma semanticamente diverso per consentire il riutilizzo, la composizione e il riaddestramento dei moduli (ad es. diversa memorizzazione degli inizializzatori di risorse, tag diversi convenzioni per i metagrafi). Il modo più semplice per distinguerli su disco è la presenza o l'assenza del file tfhub_module.pb .

Approccio generale

Per definire un nuovo modulo, un editore chiama hub.create_module_spec() con una funzione module_fn . Questa funzione costruisce un grafico che rappresenta la struttura interna del modulo, utilizzando tf.placeholder() per gli input che devono essere forniti dal chiamante. Quindi definisce le firme chiamando hub.add_signature(name, inputs, outputs) una o più volte.

Per esempio:

def module_fn():
  inputs = tf.placeholder(dtype=tf.float32, shape=[None, 50])
  layer1 = tf.layers.dense(inputs, 200)
  layer2 = tf.layers.dense(layer1, 100)
  outputs = dict(default=layer2, hidden_activations=layer1)
  # Add default signature.
  hub.add_signature(inputs=inputs, outputs=outputs)

...
spec = hub.create_module_spec(module_fn)

Il risultato di hub.create_module_spec() può essere utilizzato, invece di un percorso, per creare un'istanza di un oggetto modulo all'interno di un particolare grafico TensorFlow. In tal caso, non esiste un checkpoint e l'istanza del modulo utilizzerà invece gli inizializzatori di variabili.

Qualsiasi istanza del modulo può essere serializzata su disco tramite il suo metodo export(path, session) . L'esportazione di un modulo serializza la sua definizione insieme allo stato corrente delle sue variabili in session nel percorso passato. Questo può essere utilizzato quando si esporta un modulo per la prima volta, così come quando si esporta un modulo ottimizzato.

Per compatibilità con TensorFlow Estimators, hub.LatestModuleExporter esporta i moduli dall'ultimo checkpoint, proprio come tf.estimator.LatestExporter esporta l'intero modello dall'ultimo checkpoint.

Gli editori di moduli dovrebbero implementare una firma comune quando possibile, in modo che i consumatori possano scambiare facilmente i moduli e trovare quello migliore per il loro problema.

Esempio reale

Dai un'occhiata al nostro esportatore di moduli di incorporamento di testo per un esempio reale di come creare un modulo da un formato di incorporamento di testo comune.

Ritocchi

Il training delle variabili di un modulo importato insieme a quelle del modello che lo circonda è chiamato fine-tuning . La messa a punto può comportare una migliore qualità, ma aggiunge nuove complicazioni. Consigliamo ai consumatori di esaminare la messa a punto solo dopo aver esplorato modifiche di qualità più semplici e solo se l'editore del modulo lo consiglia.

Per i consumatori

Per abilitare la messa a punto, istanziare il modulo con hub.Module(..., trainable=True) per rendere le sue variabili addestrabili e importare REGULARIZATION_LOSSES di TensorFlow. Se il modulo ha più varianti del grafico, assicurati di scegliere quella appropriata per la formazione. Di solito è quello con i tag {"train"} .

Scegli un regime di allenamento che non rovini i pesi pre-allenati, ad esempio un tasso di apprendimento inferiore rispetto all'allenamento da zero.

Per editori

Per semplificare la messa a punto per i consumatori, tenere presente quanto segue:

  • La messa a punto necessita di regolarizzazione. Il tuo modulo viene esportato con la raccolta REGULARIZATION_LOSSES , che è ciò che mette la tua scelta di tf.layers.dense(..., kernel_regularizer=...) ecc. in ciò che il consumatore ottiene da tf.losses.get_regularization_losses() . Preferire questo modo di definire le perdite di regolarizzazione L1/L2.

  • Nel modello publisher, evita di definire la regolarizzazione L1/L2 tramite i parametri l1_ e l2_regularization_strength di tf.train.FtrlOptimizer , tf.train.ProximalGradientDescentOptimizer e altri ottimizzatori prossimali. Questi non vengono esportati insieme al modulo e l'impostazione dei punti di forza della regolarizzazione a livello globale potrebbe non essere appropriata per il consumatore. Fatta eccezione per la regolarizzazione L1 nei modelli wide (vale a dire lineare sparso) o wide & deep, dovrebbe essere possibile utilizzare invece le perdite di regolarizzazione individuali.

  • Se utilizzi tecniche di abbandono, normalizzazione batch o di addestramento simili, imposta i relativi iperparametri su valori che abbiano senso per molti usi previsti. Potrebbe essere necessario adattare il tasso di abbandono in base alla propensione all'overfitting del problema target. Nella normalizzazione batch, la quantità di moto (nota anche come coefficiente di decadimento) dovrebbe essere sufficientemente piccola da consentire la messa a punto con piccoli set di dati e/o grandi batch. Per i consumatori avanzati, prendi in considerazione l'aggiunta di una firma che esponga il controllo sugli iperparametri critici.