2015-11-30 7 views
10

Ich habe festgestellt, dass Indizierung immer noch ein offenes Problem in Tensorflow (#206) ist, also frage ich mich, was ich als Workaround im Moment verwenden könnte. Ich möchte eine Zeile/Spalte einer Matrix basierend auf einer Variable, die sich für jedes Trainingsbeispiel ändert, indexieren/schneiden.Tensorflow Slicing basierend auf Variable

Was ich bisher versucht:

  1. Slicing auf Platzhalter Basis (nicht funktioniert)

Folgende (in Betrieb) Codescheiben basierend auf einer festgelegten Anzahl.

Es scheint jedoch, dass ich nicht einfach eine dieser festen Nummern durch einen tf.Placeholder ersetzen kann. Der folgende Code gibt mir den Fehler "TypeError: Liste der Tensoren, wenn Single Tensor erwartet."

import tensorflow as tf 
import numpy as np 

x = tf.placeholder("float") 
i = tf.placeholder("int32") 
y = tf.slice(x,[i],[1]) 

#initialize 
init = tf.initialize_all_variables() 
sess = tf.Session() 
sess.run(init) 

#run 
result = sess.run(y, feed_dict={x:[1,2,3,4,5],i:0}) 
print(result) 

Das klingt wie die Klammern um [i] sind zu viel, aber sie zu entfernen entweder nicht hilft. Wie verwende ich einen Platzhalter/eine Variable als Index?

  1. Slicing auf Python Variable basiert (nicht Backprop/update richtig)

ich auch einen normalen Python-Variable als Index versucht habe. Dies führt nicht zu einem Fehler, aber das Netzwerk lernt während des Trainings nichts. Ich nehme an, weil die sich ändernde Variable nicht korrekt registriert ist, ist das Diagramm fehlerhaft und Updates funktionieren nicht?

  1. Slicing über One-Hot-Vektor + Multiplikation (Arbeiten, aber langsam)

Eine Abhilfe gefunden wird mit einem One-Hot-Vektor. Einen einharten Vektor in Annotieren erstellen, diesen mit einem Platzhalter übergeben und dann das Slicing über Matrixmultiplikation durchführen. Das funktioniert, ist aber ziemlich langsam.

Haben Sie Ideen, wie Sie auf der Grundlage einer Variablen effizient schneiden/indexieren können?

Antwort

15

Slicing basierend auf einem Platzhalter sollte gut funktionieren. Es scheint, dass Sie aufgrund einiger subtiler Probleme von Formen und Typen in einen Typfehler geraten. Wo Sie folgende Voraussetzungen erfüllt sein:

x = tf.placeholder("float") 
i = tf.placeholder("int32") 
y = tf.slice(x,[i],[1]) 

... sollten Sie stattdessen haben:

x = tf.placeholder("float") 
i = tf.placeholder("int32") 
y = tf.slice(x,i,[1]) 

... und dann sollten Sie i als [0] im Aufruf von sess.run() füttern.

Um dies ein wenig klarer, mache ich den Code umschreiben würde empfehlen, wie folgt:

import tensorflow as tf 
import numpy as np 

x = tf.placeholder(tf.float32, shape=[None]) # 1-D tensor 
i = tf.placeholder(tf.int32, shape=[1]) 
y = tf.slice(x, i, [1]) 

#initialize 
init = tf.initialize_all_variables() 
sess = tf.Session() 
sess.run(init) 

#run 
result = sess.run(y, feed_dict={x: [1, 2, 3, 4, 5], i: [0]}) 
print(result) 

Die zusätzlichen shape Argumente an die tf.placeholder op Hilfe, um sicherzustellen, dass die Werte, die Sie die entsprechenden Formen füttern, und auch dass TensorFlow einen Fehler auslöst, wenn die Formen nicht korrekt sind.

+0

Das funktioniert, vielen Dank! – Daniela

+0

Es gab den folgenden Fehler: ValueError: Shape() muss Rang 1 haben – tejaskhot

+0

Ah ja, TensorFlow wurde strikter über den Unterschied zwischen Skalaren und Länge-1-Vektoren, seit ich das gepostet habe. Die Antwort wurde aktualisiert, um es zu beheben. – mrry