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'utilizzo tipico è quello di costruire un tf.Graph , eventualmente 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 offre anche un supporto limitato per il caricamento del formato TF1 Hub in TF2 .

Utilizzando 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 suo URL o percorso del filesystem, come ad esempio:

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

Nota: ulteriori informazioni su altri tipi di handle validi sono disponibili qui .

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

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 vengono memorizzati nella cache i moduli 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 dagli input del tensore agli output del 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, questi vengono condivisi tra tutte le applicazioni.

I moduli possono definire più firme con nome per consentirne 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 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, questi 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 un target in tf.Session.run() . Infatti, gli editori dei moduli possono scegliere di fornire vari output per usi avanzati (come l'attivazione di strati intermedi) insieme agli output principali. I consumatori del modulo dovrebbero gestire con garbo gli output aggiuntivi.

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 diverse 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 attività 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. Ti consigliamo invece di pubblicare 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 del modulo (ad esempio, diversa memorizzazione degli inizializzatori di risorse, diversa codifica convenzioni per i metagrafi). Il modo più semplice per distinguerli sul 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 istanziare un oggetto modulo all'interno di un particolare grafico TensorFlow. In tal caso, non esiste alcun checkpoint e l'istanza del modulo utilizzerà invece gli inizializzatori della variabile.

Qualsiasi istanza del modulo può essere serializzata su disco tramite il relativo 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 dei moduli dovrebbero implementare una firma comune quando possibile, in modo che i consumatori possano scambiarsi facilmente i moduli e trovare quello migliore per il loro problema.

Esempio reale

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

Ritocchi

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

Per i consumatori

Per abilitare la regolazione fine, istanziare il modulo con hub.Module(..., trainable=True) per rendere le sue variabili addestrabili e importare REGULARIZATION_LOSSES di TensorFlow. Se il modulo dispone di più varianti di grafici, 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 gli editori

Per facilitare la regolazione per i consumatori, tieni presente quanto segue:

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

  • Nel modello editore, evitare 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 livelli di regolarizzazione a livello globale potrebbe non essere appropriata per il consumatore. Fatta eccezione per la regolarizzazione L1 nei modelli ampi (cioè lineari sparsi) o ampi e profondi, dovrebbe essere possibile utilizzare invece le perdite di regolarizzazione individuali.

  • Se usi il dropout, la normalizzazione batch o tecniche di training simili, imposta i relativi iperparametri su valori che abbiano senso per molti usi previsti. Potrebbe essere necessario adeguare il tasso di abbandono alla propensione del problema target all'overfitting. Nella normalizzazione batch, il momento (noto anche come coefficiente di decadimento) dovrebbe essere sufficientemente piccolo da consentire la messa a punto con set di dati piccoli e/o batch di grandi dimensioni. Per i consumatori avanzati, valuta la possibilità di aggiungere una firma che esponga il controllo sugli iperparametri critici.