2017-01-17 6 views
0

Unten ist die einfache mnist Tutorial (dh einzelne Schicht softmax) von der Tensorflow Website, die ich mit einem Multi-Threaded-Trainingsschritt zu erweitern versucht:Tensorflow und Gewinde

from tensorflow.examples.tutorials.mnist import input_data 
import tensorflow as tf 
import threading 

# Training loop executed in each thread 
def training_func(): 
    while True: 
     batch = mnist.train.next_batch(100) 
     global_step_val,_ = sess.run([global_step, train_step], feed_dict={x: batch[0], y_: batch[1]}) 
     print("global step: %d" % global_step_val) 
     if global_step_val >= 4000: 
     break 

# create session and graph 
sess = tf.Session() 

x = tf.placeholder(tf.float32, shape=[None, 784]) 
y_ = tf.placeholder(tf.float32, shape=[None, 10]) 

W = tf.Variable(tf.zeros([784,10])) 
b = tf.Variable(tf.zeros([10])) 
global_step = tf.Variable(0, name="global_step") 
y = tf.matmul(x,W) + b 

cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(y, y_)) 

inc = global_step.assign_add(1) 
with tf.control_dependencies([inc]): 
    train_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy) 

correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1)) 
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32)) 

# initialize graph and create mnist loader 
sess.run(tf.global_variables_initializer()) 
mnist = input_data.read_data_sets('MNIST_data', one_hot=True) 

# create workers and execute threads 
workers = [] 
for _ in range(8): 
    t = threading.Thread(target=training_func) 
    t.start() 
    workers.append(t) 

for t in workers: 
    t.join() 

# evaluate accuracy of the model 
print(accuracy.eval(feed_dict={x: mnist.test.images, y_: mnist.test.labels}, 
    session=sess)) 

Ich muß etwas fehlen, wie 8 Gewinde wie unten ergeben inkonsistente Ergebnisse (Genauigkeit ca. = 0,1), wenn mit 1 Gewinde nur die erwartete Genauigkeit erreicht wird (ca. 0,92). Hat jemand eine Ahnung von meinen Fehlern? Vielen Dank!

+2

Sie wissen, dass TF-Graphen von einer stark parallelen Engine kompiliert und ausgeführt werden. Wenn Sie sich die CPU-Auslastung beim Einzel-Thread-Training ansehen, sehen Sie alle geladenen Kerne, nicht nur einen. Was möchten Sie erreichen, indem Sie das Training auf den richtigen Weg bringen? Ich erwarte, dass die Probleme, die Sie sehen, von mehreren Threads kommen, die Gewichte ohne jede Kontrolle aktualisieren und die gegenseitigen Änderungen überschreiben. –

+0

Mein Ziel wäre es, teure Schulungen zu beschleunigen. Ich verstehe, dass TF wirklich parallel ist, aber auch, dass man mit Multithreading beschleunigen kann - zB im obigen Beispiel ergibt Bereich (1) 15-20% für alle Kerne, während Bereich (16) zu 60-80% führt. –

+0

Ich vermutete, dass mein Problem von unkontrollierten gleichzeitigen Gewichtsaktualisierungen herrührt. Allerdings tut [dieser TF tutorial code] (https://github.com/tensorflow/tensorflow/blob/r0.12/tensorflow/models/embedding/word2vec_optimized.py) etwas analog zu meinem Beispielcode (l.319 bis l. 340), aber ich verstehe nicht, warum das in ihrem Fall funktioniert. Vielleicht verwaltet ihr Training op (word2vec.neg_train) diese gleichzeitige Updates intern? –

Antwort

1

Beachten Sie, dass threading mit Python keine echte Parallelität wegen der GIL erstellen kann. Was hier passiert, ist, dass Sie mehrere Threads haben, die alle auf derselben CPU laufen, wo sie in der Realität sequenziell laufen. Daher würde ich vorschlagen, Koordinator in Tensorflow zu verwenden. Mehr Informationen über Coordinator finden Sie hier:

https://www.tensorflow.org/programmers_guide/threading_and_queues
https://www.tensorflow.org/programmers_guide/reading_data

Schließlich würde ich vorschlagen, Sie sagen:

with tf.device('/cpu:0'): 
    your code should go here... 'for the first thread' 

Dann eine andere CPU für den anderen Thread verwenden und so weiter ... Hoffe, diese Antwort findet Sie gut !!

+0

Ich habe die Antwort nur gesehen und habe sie noch nicht getestet, aber die Information sieht relevant aus, danke für die Antwort :) Ich habe jetzt Upvote, und ich wähle die Antwort, wenn es das Problem löst (wenn ich Zeit habe zu testen :)) –