Desidero scrivere un nuovo algoritmo di ottimizzazione per la mia rete su Tensorflow. Spero di implementare lo Levenberg Marquardt optimization algorithm, che ora è escluso dall'API di TF. Ho trovato scarsa documentazione su come scrivere un ottimizzatore personalizzato, quindi chiedo se qualcuno può dare il mio consiglio. Grazie.Come creare un ottimizzatore in Tensorflow
risposta
L'esempio più semplice di un ottimizzatore è probabilmente lo gradient descent optimizer. Mostra come si crea un'istanza di base optimizer class. La documentazione della classe base dell'ottimizzatore spiega cosa fanno i metodi.
Il lato python degli ottimizzatori aggiunge nuovi nodi al grafico che calcola e applica i gradienti che vengono propagati di nuovo. Fornisce i parametri che vengono passati agli operatori e fa parte della gestione ad alto livello dell'ottimizzatore. Quindi, è necessario l'effettivo "Applica" op.
Gli op hanno sia un componente python che un componente C++. La scrittura di un'opzione di formazione è la stessa (ma specializzata) del general process of adding an Op to TensorFlow.
Per un esempio di esercitazioni di allenamento che calcolano e applicano gradienti, vedere python/training/training_ops.py - questa è la colla Python per le effettive operazioni di allenamento. Si noti che il codice qui riguarda principalmente l'inferenza della forma: il calcolo sarà nel C++.
L'effettiva matematica per applicare i gradienti è gestita da un Op (ricordando che, in generale, le operazioni sono scritte in C++). In questo caso, le opzioni di gradienti di applicazione sono definite in core/kernels/training_ops.cc. Si può vedere, ad esempio, la realizzazione di ApplyGradientDescentOp in là, che fa riferimento a un ApplyGradientDescent funtore:
var.device(d) -= grad * lr();
L'attuazione della Op si segue l'attuazione di ogni altra op come descritto nella documentazione aggiunta di-un-op .
Grazie per la spiegazione. C'è una ragione per farlo in C++? Non vedo come la composizione di questa semplice computazione (moltiplicazione scalare e sottrazione basata su elementi) in C++ debba essere molto più veloce che in Python. Per gli ottimizzatori di prototipi, sarebbe utile fare tutto in Python. Sai se è possibile? – danijar
@danijar la semplice ragione è che Python è solo una delle interfacce disponibili di Tensorflow. Implementare meccanismi di base in C++ aiuta a creare interfacce per altre lingue. –
scusate il codice per tensorflow è davvero denso e confuso. Quindi, dove esattamente nel codice si può trovare ciò che stanno facendo matematicamente le operazioni 'apply_gradient'? Ad esempio, stavo leggendo https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/training/optimizer.py e non sembra che abbia espressioni matematiche né il codice per la discesa del gradiente optimizer https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/training/gradient_descent.py. Dove posso vedere come viene utilizzata la sfumatura di applicazione? – Pinocchio
Prima di eseguire il Session tensorflow, si dovrebbe avviare una Optimizer come si vede qui sotto:
# Gradient Descent
optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(cost)
tf.train.GradientDescentOptimizer è un oggetto della classe GradientDescentOptimizer e come dice il nome, implementa l'algoritmo di discesa del gradiente.
Procedimento minimize() è chiamato un “costo” come parametro e costituito dai due metodi compute_gradients() e poi apply_gradients().
Per la maggior parte delle implementazioni di ottimizzatori (personalizzati), il metodo apply_gradients() deve essere adattato.
Questo metodo si basa sulla (nuova) Optimizer (classe), che creeremo, per implementare i seguenti metodi: _create_slots(), _prepare(), _apply_dense(), e _apply_sparse().
_create_slots() e _prepare() creare e inizializzare ulteriori variabili, come slancio.
_apply_dense() e _apply_sparse() attuare Ops reali, che aggiornano le variabili.
Gli op sono generalmente scritti in C++. Senza dover cambiare tu stesso l'intestazione del C++, puoi ancora restituire un wrapper python di alcune Ops attraverso questi metodi. Questo viene fatto come segue:
def _create_slots(self, var_list):
# Create slots for allocation and later management of additional
# variables associated with the variables to train.
# for example: the first and second moments.
'''
for v in var_list:
self._zeros_slot(v, "m", self._name)
self._zeros_slot(v, "v", self._name)
'''
def _apply_dense(self, grad, var):
#define your favourite variable update
# for example:
'''
# Here we apply gradient descents by substracting the variables
# with the gradient times the learning_rate (defined in __init__)
var_update = state_ops.assign_sub(var, self.learning_rate * grad)
'''
#The trick is now to pass the Ops in the control_flow_ops and
# eventually groups any particular computation of the slots your
# wish to keep track of:
# for example:
'''
m_t = ...m... #do something with m and grad
v_t = ...v... # do something with v and grad
'''
return control_flow_ops.group(*[var_update, m_t, v_t])
Per una spiegazione più dettagliata con l'esempio, si veda questo post del blog https://www.bigdatarepublic.nl/custom-optimizer-in-tensorflow/
fattori di smorzamento non hanno nulla a che fare con il flusso tensore. Le reti neurali non hanno bisogno di regressione della cresta ... Non capisco questa comunità. +1 per sparare una bella domanda inebriante. Per me fornire una buona risposta richiederebbe un po 'di apprendimento e questo è il mio aspetto preferito di SO. – kpie
hai mai creato l'ottimizzatore personalizzato in TensorFlow? Se hai un link al tuo codice tramite github o qualcosa che sarebbe super utile! – Pinocchio
La risposta di dga è utile se vuoi fare degli ottimizzatori che sono (presumibilmente) più veloci e riusabili tra le interfacce del linguaggio TensorFlow, ma se vuoi implementare un ottimizzatore in Python per l'uso in Python, controlla 'ExternalOptimizerInterface': https: // www.tensorflow.org/api_docs/python/tf/contrib/opt/ExternalOptimizerInterface – GEOFBOT