2

, also versuche ich Tensorflows LSTM zu verwenden, um gesprochene Wörter zu erkennen. Nachdem jedoch jedes Trainingswort durch den LSTM geleitet wurde, dauert die Verarbeitung des nächsten Wortes länger (insbesondere die Berechnung des Gradienten durch Rückwärtsausbreitung und die Anwendung dieser auf das Netzwerk). Ich arbeite gerade an einem iMac ohne CUDA-Unterstützung, also muss ich eine CPU verwenden, keine GPU (ich werde zu GPU wechseln, sobald ich dazu in der Lage bin).Tensor Flow LSTM für die Spracherkennung verlangsamt sich beim Training jedes weitere Wort

Ich programmiere mit Python-2.7

ich ein sehr kleines Vokabular verwenden, 8 Wortklassen mit 10 Trainingsbeispielen jeder und jedes Wort isoliert (nicht Teil eines Satzes ist, nur ein Wort auf seinem besitzen).

Jedes Wort wird in Mel Frequency Cepstral-Koeffizienten vorverarbeitet und dann werden diese unter Verwendung von Kmeans mit K = 100 gruppiert. Somit ist die Eingabe in das LSTM eine Liste von float32s, die jeweils in einem Element gespeist werden.

Die Verlangsamung tritt definitiv im LSTM auf, da die Zeit, die benötigt wird, um jedes Element aus der Liste zu holen und es an das LSTM zu übergeben, für jedes Element ungefähr gleich bleibt. Die Größe jedes Elements, das an den LSTM übergeben wird, ist ebenfalls jedes Mal gleich (längere Wörter haben einfach längere Listen von Elementen); jedoch werden noch kürzere Wörter (mit weniger Elementen in ihrer Liste) immer länger dauern, während das Training fortfährt.

Ich verwende gradient decent und backpropogation, um das Netzwerk zu trainieren und habe versucht, Gradienten in 10 Zeitschritten zu schneiden oder gar nicht zu schneiden, was keinen Unterschied macht.

Die LSTM instanziiert mit:

cell = rnn_cell.BasicLSTMCell(size, forget_bias=config.forget_bias) 
cell_layers = rnn_cell.MultiRNNCell([cell] * config.num_layers) 
//pass inputs through the cell 
outputs, states = RNN.rnn(cell_layers, _inputs,initial_state=self._initial_state) 

Nach dem LSTM I eine softmax Schicht aufweisen; Deren Ausgabe wird mit einem einzigen heißen Vektor verglichen, der die korrekte Ausgabe darstellt, wobei der Kreuzenthalpieverlust verwendet wird.

Pipeline sudo Code:

_inputs = [[float32]*] 
for input in _inputs: //input = _inputs[0][0] at time zero input = _inputs[0][1] at time 1 etc. 
lstm_output = LSTM(input) 
soft_out = softmax(last_output) 
cost = CrossEnthalpyCost(soft_out, answer) 
gradients = backprop(cost) 
new_weights = gradientDecent(gradients, learning_rate) 

Schließlich habe ich den Fall, dass nicht klar gewesen, was mein Problem ist, hier ist die Timings von meinem Netzwerk:

Epoch: 0 Learning rate: 1.000 
{'heart': 5, 'car': 1, 'dog': 3, 'cat': 2, 'book': 0, 'three': 7, 'girl': 4, 'milk': 6} 
book 

time to input all clusters for one word into network: 0.0293724536896 
time to pass all inputs for one word and perform gradient decent:2.956 
Time difference from previous word: 2.956 
Epoch Number: 0 Word Number:1, Number of Pieces:247, Word ID:0 

time to input all clusters for one word into network: 0.0287952423096 
time to pass all inputs for one word and perform gradient decent:3.738 
Time difference from previous word: 0.782 
Epoch Number: 0 Word Number:2, Number of Pieces:247, Word ID:0 

time to input all clusters for one word into network: 0.029797077179 
time to pass all inputs for one word and perform gradient decent:4.754 
Time difference from previous word: 1.015 
Epoch Number: 0 Word Number:3, Number of Pieces:250, Word ID:0 
... 

time to input all clusters for one word into network: 0.0417804718018 
time to pass all inputs for one word and perform gradient decent:25.123 
Time difference from previous word: 12.255 
Epoch Number: 0 Word Number:24, Number of Pieces:258, Word ID:2 
... 

time to input all clusters for one word into network: 0.0413291454315 
time to pass all inputs for one word and perform gradient decent:40.364 
Time difference from previous word: 0.932 
Epoch Number: 0 Word Number:38, Number of Pieces:255, Word ID:3 

Wenn jemand irgendwelche Ideen, warum es länger und länger dauert

+1

sind Rufen Sie den LSTM-Code mehrfach auf (zB nach jedem Aufruf von 'sess.run()')?Dies würde zu einer Verlängerung der Ausführungszeiten führen, da TensorFlow für die wiederholte Verwendung desselben Diagramms optimiert ist. – mrry

+0

@mrry Der LSTM wird zu Beginn der Sitzung mit einer with-Anweisung erstellt. ie 'mit tf.Graph(). As_default(), tf.Session() als Sitzung:' Ich benutze 'session.run (tf.assign (some_variable, some_other_variable))' um verschiedene Variablen zu vergeben, die sich durchgängig ändern die Sitzung. Zum Beispiel habe ich ein Flag, das dem Optimierer sagt, wann das Ende eines Wortes erreicht wurde, damit es die Kosten berechnen kann. Das passiert einmal pro Wort, also kann ich nicht sehen, wie das die Verarbeitungszeit für jedes nachfolgende Wort erhöhen würde. Danke. – Eli

+0

Das klingt alles vernünftig. Möglicherweise müssen wir Ihre Trainingsschleife sehen, um eine Idee zu bekommen, warum dies passieren könnte. – mrry

Antwort

2

Das Problem wurde verursacht durch eine Verwendung tf.assign jedes Mal, wenn ein Wortsegment eingespeist wurde. Dies bewirkt, dass das Diagramm wächst, wenn jeweils eine neue Variable erstellt wird mich. In meinem Fall wurde jedes Wort in ungefähr 250 Stücke geteilt, daher der schnelle und große Zeitaufwand.

Das Problem wurde behoben, indem die tf.assign-Methode entfernt und die fehlerhafte Variable durch einen Platzhalter ersetzt wurde, der mit feed_dict und nicht mit assign gesetzt wurde.

Dank @mrry für die Hilfe!

0

Ein netter Trick, um mit dieser Art von Fehler zu helfen, ist Graph.finalize() ... Sobald Sie alle gewünschten Graph-Ops hinzugefügt haben, rufen Sie finalize auf und alle Versuche, dem Diagramm zusätzliche Ops hinzuzufügen, werden einen Fehler erzeugen. War sehr hilfreich für mich, als ich anfing und hatte nicht vollständig verinnerlicht die "Ich baue das Diagramm ONCE und bekomme Zeiger auf Tensoren, wie ich, dann ich ausschließlich ops/call eval auf den Tensoren zu tun Sachen" Mantra