2016-07-28 13 views
3

Ich entwarf ein neuronales Netzwerk in Tensorflow für meine Regression Problem durch Befolgen und Anpassen der Tensorflow-Tutorial. Aufgrund der Struktur meines Problems (~ 300.000 Datenpunkte und die Verwendung des kostenintensiven FTRLOptimizer), dauerte mein Problem zu lange, um sogar mit meinem 32-CPU-Rechner (ich habe keine GPUs) auszuführen.Train-Modell mit Warteschlange Tensorflow

Nach this comment und eine schnelle Bestätigung über htop, es scheint, dass ich einige Singlethread-Operationen haben und es sollte feed_dict sein.

Daher, wie empfohlen here, ich versuchte, Warteschlangen für Multithreading meines Programms zu verwenden.

Ich schrieb eine einfache Code-Datei mit Warteschlange ein Modell wie folgt zu trainieren:

import numpy as np 
import tensorflow as tf 
import threading 

#Function for enqueueing in parallel my data 
def enqueue_thread(): 
    sess.run(enqueue_op, feed_dict={x_batch_enqueue: x, y_batch_enqueue: y}) 

#Set the number of couples (x, y) I use for "training" my model 
BATCH_SIZE = 5 

#Generate my data where y=x+1+little_noise 
x = np.random.randn(10, 1).astype('float32') 
y = x+1+np.random.randn(10, 1)/100 

#Create the variables for my model y = x*W+b, then W and b should both converge to 1. 
W = tf.get_variable('W', shape=[1, 1], dtype='float32') 
b = tf.get_variable('b', shape=[1, 1], dtype='float32') 

#Prepare the placeholdeers for enqueueing 
x_batch_enqueue = tf.placeholder(tf.float32, shape=[None, 1]) 
y_batch_enqueue = tf.placeholder(tf.float32, shape=[None, 1]) 

#Create the queue 
q = tf.RandomShuffleQueue(capacity=2**20, min_after_dequeue=BATCH_SIZE, dtypes=[tf.float32, tf.float32], seed=12, shapes=[[1], [1]]) 

#Enqueue operation 
enqueue_op = q.enqueue_many([x_batch_enqueue, y_batch_enqueue]) 

#Dequeue operation 
x_batch, y_batch = q.dequeue_many(BATCH_SIZE) 

#Prediction with linear model + bias 
y_pred=tf.add(tf.mul(x_batch, W), b) 

#MAE cost function 
cost = tf.reduce_mean(tf.abs(y_batch-y_pred)) 

learning_rate = 1e-3 
train_op = tf.train.GradientDescentOptimizer(learning_rate).minimize(cost) 
init = tf.initialize_all_variables() 
sess = tf.Session() 
sess.run(init) 
available_threads = 1024 

#Feed the queue 
for i in range(available_threads): 
    threading.Thread(target=enqueue_thread).start() 

#Train the model 
for step in range(1000): 
    _, cost_step = sess.run([train_op, cost]) 
    print(cost_step) 
Wf=sess.run(W) 
bf=sess.run(b) 

Dieser Code funktioniert nicht, weil jedes Mal, wenn ich x_batch nennen, auch eine y_batch und umgekehrt aus der Warteschlange entfernt wird. Dann vergleiche ich die Features nicht mit dem entsprechenden "Ergebnis".

Gibt es eine einfache Möglichkeit, dieses Problem zu vermeiden?

Antwort

1

Mein Fehler, alles hat gut funktioniert. Ich wurde in die Irre geführt, weil ich bei jedem Schritt des Algorithmus meine Leistung auf verschiedenen Chargen schätzte und auch weil mein Modell zu kompliziert für einen Dummy war (ich hätte etwas wie y = W * x oder y = x + b). Wenn ich dann versuchte, in der Konsole zu drucken, habe ich mehrmals sess.run auf verschiedenen Variablen ausgeführt und offensichtlich nicht konsistente Ergebnisse erhalten.

0

Trotzdem ist Ihr Problem gelöst, wollte Ihnen eine kleine Ineffizienz in Ihrem Code zeigen. Wenn Sie Ihre RandomShuffleQueue erstellt haben, haben Sie capacity=2**20 angegeben. In allen Warteschlangen capacity:

Die obere Grenze für die Anzahl der Elemente, die in dieser Warteschlange gespeichert werden können.

Die Warteschlange versucht, so viele Elemente wie möglich in die Warteschlange zu stellen, bis sie diese Grenze erreicht. All diese Elemente essen Ihren RAM. Wenn jedes Element nur aus 1 Byte besteht, verbraucht Ihre Warteschlange 1 MB Ihrer Daten. Wenn Sie 10 KB Bilder in Ihrer Warteschlange haben, werden Sie 10 GB RAM essen.

Dies ist sehr verschwenderisch, vor allem, weil Sie nie so viele Elemente in der Warteschlange benötigen. Sie müssen nur sicherstellen, dass Ihre Warteschlange niemals leer ist. Suchen Sie also eine vernünftige Kapazität der Warteschlange und verwenden Sie keine großen Zahlen.