2016-06-14 38 views
6

Qual è il modo migliore di duplicare un grafico TensorFlow e mantenerlo aggiornato?duplicare un grafico tensorflow

Idealmente, voglio mettere il grafico duplicato su un altro dispositivo (ad esempio da GPU a CPU) e quindi aggiornare la copia ogni tanto.

+0

Perché non creare più grafici in parallelo anziché replicarne uno esistente? –

+1

Questa domanda è abbastanza ambigua. Stai chiedendo di aggiornare una struttura di dati 'Graph' di TensorFlow in situ [(difficile)] (http://stackoverflow.com/questions/37610757/how-to-remove-nodes-from-tensorflow-graph/37620231#37620231) ? O stai chiedendo come aggiornare i parametri in un grafico da un altro [(non così male)] (https://www.tensorflow.org/versions/master/how_tos/variables/index.html#saving-and-restoring) senza cambiare la struttura? O questo è legato al controllo della versione sulle reti neurali (che è un problema di ingegneria del software più in generale)? – rdadolf

+0

@rdadolf il secondo. Ho solo bisogno di tenere una copia degli stessi modelli su macchine diverse e sincronizzare i parametri di volta in volta. – MBZ

risposta

10

Risposta breve: Probabilmente si desidera checkpoint files (permalink).


Risposta lunga:

Cerchiamo di essere chiari circa la messa a punto qui. Immagino che tu abbia due dispositivi, A e B, e che tu stia allenando su A e eseguendo l'inferenza su B. Periodicamente, ti piacerebbe aggiornare i parametri sul dispositivo che eseguono l'inferenza con i nuovi parametri trovati durante l'allenamento sul altro. Il tutorial sopra riportato è un buon punto di partenza. Ti mostra come funzionano gli oggetti e non dovresti aver bisogno di qualcosa di più complicato qui.

Ecco un esempio:

import tensorflow as tf 

def build_net(graph, device): 
    with graph.as_default(): 
    with graph.device(device): 
     # Input placeholders 
     inputs = tf.placeholder(tf.float32, [None, 784]) 
     labels = tf.placeholder(tf.float32, [None, 10]) 
     # Initialization 
     w0 = tf.get_variable('w0', shape=[784,256], initializer=tf.contrib.layers.xavier_initializer()) 
     w1 = tf.get_variable('w1', shape=[256,256], initializer=tf.contrib.layers.xavier_initializer()) 
     w2 = tf.get_variable('w2', shape=[256,10], initializer=tf.contrib.layers.xavier_initializer()) 
     b0 = tf.Variable(tf.zeros([256])) 
     b1 = tf.Variable(tf.zeros([256])) 
     b2 = tf.Variable(tf.zeros([10])) 
     # Inference network 
     h1 = tf.nn.relu(tf.matmul(inputs, w0)+b0) 
     h2 = tf.nn.relu(tf.matmul(h1,w1)+b1) 
     output = tf.nn.softmax(tf.matmul(h2,w2)+b2) 
     # Training network 
     cross_entropy = tf.reduce_mean(-tf.reduce_sum(labels * tf.log(output), reduction_indices=[1])) 
     optimizer = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)  
     # Your checkpoint function 
     saver = tf.train.Saver() 
     return tf.initialize_all_variables(), inputs, labels, output, optimizer, saver 

Il codice per il programma di formazione:

def programA_main(): 
    from tensorflow.examples.tutorials.mnist import input_data 
    mnist = input_data.read_data_sets('MNIST_data', one_hot=True) 
    # Build training network on device A 
    graphA = tf.Graph() 
    init, inputs, labels, _, training_net, saver = build_net(graphA, '/cpu:0') 
    with tf.Session(graph=graphA) as sess: 
    sess.run(init) 
    for step in xrange(1,10000): 
     batch = mnist.train.next_batch(50) 
     sess.run(training_net, feed_dict={inputs: batch[0], labels: batch[1]}) 
     if step%100==0: 
     saver.save(sess, '/tmp/graph.checkpoint') 
     print 'saved checkpoint' 

... e il codice per un programma di inferenza:

def programB_main(): 
    from tensorflow.examples.tutorials.mnist import input_data 
    mnist = input_data.read_data_sets('MNIST_data', one_hot=True) 
    # Build inference network on device B 
    graphB = tf.Graph() 
    init, inputs, _, inference_net, _, saver = build_net(graphB, '/cpu:0') 
    with tf.Session(graph=graphB) as sess: 
    batch = mnist.test.next_batch(50) 

    saver.restore(sess, '/tmp/graph.checkpoint') 
    print 'loaded checkpoint' 
    out = sess.run(inference_net, feed_dict={inputs: batch[0]}) 
    print out[0] 

    import time; time.sleep(2) 

    saver.restore(sess, '/tmp/graph.checkpoint') 
    print 'loaded checkpoint' 
    out = sess.run(inference_net, feed_dict={inputs: batch[0]}) 
    print out[1] 

Se fuoco il programma di allenamento e poi il programma di inferenza, vedrai il programma di inferenza che produce due uscite differenti (dallo stesso batch di input). Questo è il risultato del rilevamento dei parametri che il programma di allenamento ha posto sotto controllo.

Ora, questo programma ovviamente non è il tuo punto finale. Non eseguiamo alcuna sincronizzazione reale e dovrai decidere cosa significa "periodico" rispetto al checkpoint. Ma questo dovrebbe darti un'idea di come sincronizzare i parametri da una rete all'altra.

Un ultimo avviso: questo è non significa che le due reti sono necessariamente deterministiche. Esistono elementi non deterministici noti in TensorFlow (ad es., this), quindi fai attenzione se hai bisogno di esattamente la stessa risposta.Ma questa è la dura verità sull'esecuzione su più dispositivi.

Buona fortuna!

2

cercherò di andare con una risposta piuttosto semplificata, per vedere se l'approccio generale è quello che OP sta descrivendo:

mi piacerebbe attuare tramite l'oggetto tf.train.Saver.

Supponiamo di avere il vostro peso in una variabile W1, W2, e b1

mysaver = tf.train.Saver(({'w1': W1, 'w2': W2, 'b1': b1})) 

Nel ciclo treno è possibile aggiungere, ogni n iterazioni:

saver.save(session_var, 'model1', global_step=step) 

e poi nel caso di carico , quando necessario, si esegue:

tf.train.Saver.restore(other_session_object, 'model1') 

Spero che questo è simile alla soluzione che chiedete.

Problemi correlati