Was ist der Unterschied zwischen tf.placeholder und tf.Variable?


290

Ich bin ein Neuling bei TensorFlow. Ich bin verwirrt über den Unterschied zwischen tf.placeholderund tf.Variable. Wird aus meiner Sicht tf.placeholderfür Eingabedaten und tf.Variablezum Speichern des Datenstatus verwendet. Das ist alles was ich weiß.

Könnte mir jemand ihre Unterschiede genauer erklären? Insbesondere wann tf.Variableund wann zu verwenden tf.placeholder?


7
Intuitiv möchten Sie Farbverläufe in Bezug auf Variables, aber nicht in Bezug auf placeholders (deren Werte immer angegeben werden müssen).
Yibo Yang

Ein Kurs wie cs231n.stanford.edu kann Verwirrten helfen. Ich mochte es sehr! Offensichtlich gibt es noch andere
Nathan

Antworten:


175

Kurz gesagt, Sie verwenden tf.Variablefür trainierbare Variablen wie Gewichte (W) und Verzerrungen (B) für Ihr Modell.

weights = tf.Variable(
    tf.truncated_normal([IMAGE_PIXELS, hidden1_units],
                    stddev=1.0 / math.sqrt(float(IMAGE_PIXELS))), name='weights')

biases = tf.Variable(tf.zeros([hidden1_units]), name='biases')

tf.placeholder wird verwendet, um aktuelle Trainingsbeispiele zu füttern.

images_placeholder = tf.placeholder(tf.float32, shape=(batch_size, IMAGE_PIXELS))
labels_placeholder = tf.placeholder(tf.int32, shape=(batch_size))

So füttern Sie die Trainingsbeispiele während des Trainings:

for step in xrange(FLAGS.max_steps):
    feed_dict = {
       images_placeholder: images_feed,
       labels_placeholder: labels_feed,
     }
    _, loss_value = sess.run([train_op, loss], feed_dict=feed_dict)

Sie tf.variableswerden als Ergebnis dieser Schulung geschult (modifiziert).

Weitere Informationen finden Sie unter https://www.tensorflow.org/versions/r0.7/tutorials/mnist/tf/index.html . (Beispiele stammen von der Webseite.)


2
Was ist, wenn ich mein Bild vor dem Einspeisen vorverarbeiten möchte? (zB den Kontrast neu skalieren). Benötige ich jetzt eine Variable dafür? Wenn ja, hat dies Auswirkungen auf das Gedächtnis oder die Geschwindigkeit?
Bastiaan

1
Jede Vorverarbeitung, die Sie durchführen, erfolgt vor dem Einspeisen der Daten in das Tensorflow-Diagramm (dh das Netzwerk), sodass für die Arbeit technisch keine Code-Tools von Tensorflow erforderlich sind. Zum Beispiel wäre eine Variable unnötig, 1. weil es sich um Eingabedaten handelt, die über tf.placeholders (keine Variablen) im Diagramm übertragen werden, und 2. bevor sie in einen Platzhalter für den aktuellen Durchlauf durch das Netzwerk geladen wird .
PaulG

Ich wollte nur wissen, wie sehr ich diese Antwort schätze. Die Tatsache, dass diese Antwort weitaus weniger positive Stimmen enthält als die Frage, zeigt nur, wie sofort befriedigend Menschen sein können und wie trendig Tags mögen tensorflowund deep learningund AIsind.
Nathan

70

Der Unterschied besteht darin, dass tf.VariableSie bei der Deklaration einen Anfangswert angeben müssen. Mit tf.placeholderSie müssen einen Anfangswert nicht bieten und Sie es zur Laufzeit mit dem angeben feed_dictArgumente innenSession.run


63
-1. Dies ist zwar wahr, verfehlt aber den Punkt. Der wichtigere Unterschied ist ihre Rolle innerhalb von TensorFlow. Variablen werden im Laufe der Zeit trainiert, Platzhalter sind Eingabedaten, die sich beim Trainieren Ihres Modells nicht ändern (wie Eingabebilder und Klassenbeschriftungen für diese Bilder). Wie in der Antwort von Sung Kim angegeben, verwenden Sie Variablen für Gewichte und Verzerrungen in Ihrem Modell (obwohl dies nicht darauf beschränkt ist - für die Stilübertragung optimieren Sie ein Bild im Laufe der Zeit).
Chris Anderson

@ ChrisAnderson könnten wir sagen, dass diese Abbildung falsch ist?! youtu.be/MotG3XI2qSs?t=136
N0rA

@ChrisAnderson Warum ist es wichtig, wofür es verwendet werden soll, wenn die Unterschiede nur einen sind, der einen Anfangswert benötigt?
Goldname

1
@Goldname Es ist nicht das, wofür es "gedacht" ist - es ist möglich und nicht möglich. Sie sind völlig verschiedene Objekte. Sie sind nicht austauschbar und die Unterschiede sind mehr als "man braucht einen Anfangswert".
Chris Anderson

61

Da Tensor-Berechnungen aus Graphen bestehen, ist es besser, die beiden in Form von Graphen zu interpretieren.

Nehmen wir zum Beispiel die einfache lineare Regression

WX+B=Y

wo Wund Bstehen für die Gewichte und Verzerrungen und Xfür die Eingaben Yder Beobachtungen und für die Ausgaben der Beobachtungen.

Offensichtlich Xund Ysind von gleicher Natur (Manifestvariablen), die sich von denen von Wund B(latente Variablen) unterscheiden. Xund Ysind Werte der Proben (Beobachtungen) und benötigen daher einen zu füllenden Platz , während Wund Bsind die Gewichte und die Abweichung Variablen (die vorherigen Werte wirken sich auf letztere aus) in der Grafik, die unter Verwendung von verschiedenen Xund YPaaren trainiert werden sollten . Wir platzieren verschiedene Stichproben in den Platzhaltern , um die Variablen zu trainieren .

Wir müssen nur die Variablen (an Prüfpunkten) speichern oder wiederherstellen , um das Diagramm mit dem Code zu speichern oder neu zu erstellen.

Platzhalter sind meist Inhaber für die verschiedenen Datensätze (z. B. Trainingsdaten oder Testdaten). Im Trainingsprozess werden jedoch Variablen für die spezifischen Aufgaben trainiert, dh um das Ergebnis der Eingabe vorherzusagen oder die Eingaben den gewünschten Beschriftungen zuzuordnen. Sie bleiben gleich, bis Sie das Modell mit verschiedenen oder denselben Beispielen neu trainieren oder optimieren , um die Platzhalter häufig durch das Diktat zu füllen . Zum Beispiel:

 session.run(a_graph, dict = {a_placeholder_name : sample_values}) 

Platzhalter werden auch als Parameter zum Festlegen von Modellen übergeben.

Wenn Sie während des Trainings die Platzhalter (Hinzufügen, Löschen, Ändern der Form usw.) eines Modells ändern, können Sie den Prüfpunkt weiterhin ohne weitere Änderungen neu laden. Wenn jedoch die Variablen eines gespeicherten Modells geändert werden, sollten Sie den Prüfpunkt entsprechend anpassen, um ihn neu zu laden und das Training fortzusetzen (alle im Diagramm definierten Variablen sollten im Prüfpunkt verfügbar sein).

Zusammenfassend lässt sich sagen, dass Sie, wenn die Werte aus den Stichproben stammen (Beobachtungen, die Sie bereits haben), sicher einen Platzhalter erstellen, um sie zu halten. Wenn Sie einen zu trainierenden Parameter benötigen, nutzen Sie eine Variable (einfach ausgedrückt, stellen Sie die Variablen für die gewünschten Werte ein TF automatisch verwenden).

In einigen interessanten Modellen, wie einem Stilübertragungsmodell, werden die Eingabepixel optimiert und die normalerweise als Modellvariablen bezeichneten Variablen werden festgelegt. Dann sollten wir die Eingabe (normalerweise zufällig initialisiert) als Variable vornehmen, wie in diesem Link implementiert.

Weitere Informationen finden Sie in diesem einfachen und anschaulichen Dokument .


38

TL; DR

Variablen

  • Damit Parameter lernen
  • Werte können aus dem Training abgeleitet werden
  • Anfangswerte sind erforderlich (oft zufällig)

Platzhalter

  • Zugewiesener Speicher für Daten (z. B. für Bildpixeldaten während eines Feeds)
  • Anfangswerte sind nicht erforderlich (können aber eingestellt werden, siehe tf.placeholder_with_default)

34

Der offensichtlichste Unterschied zwischen dem tf.Variable und dem tf.placeholder ist der folgende


Sie verwenden Variablen, um Parameter zu speichern und zu aktualisieren. Variablen sind speicherinterne Puffer, die Tensoren enthalten. Sie müssen explizit initialisiert werden und können während und nach dem Training auf der Festplatte gespeichert werden. Sie können gespeicherte Werte später wiederherstellen, um das Modell zu trainieren oder zu analysieren.

Die Initialisierung der Variablen erfolgt mit sess.run(tf.global_variables_initializer()). Auch beim Erstellen einer Variablen müssen Sie einen Tensor als Anfangswert an den Variable()Konstruktor übergeben. Wenn Sie eine Variable erstellen, kennen Sie immer deren Form.


Andererseits können Sie den Platzhalter nicht aktualisieren. Sie sollten auch nicht initialisiert werden, aber da sie ein Versprechen für einen Tensor sind, müssen Sie den Wert in sie einspeisen sess.run(<op>, {a: <some_val>}). Und schließlich kennt der Platzhalter im Vergleich zu einer Variablen möglicherweise nicht die Form. Sie können entweder Teile der Abmessungen oder gar nichts angeben.


Es gibt andere Unterschiede:

Interessant ist, dass nicht nur Platzhalter gefüttert werden können. Sie können den Wert einer Variablen und sogar einer Konstanten zuführen.


14

Neben den Antworten anderer erklären sie dies auch sehr gut in diesem MNIST-Tutorial auf der Tensoflow-Website:

Wir beschreiben diese Interaktionsoperationen durch Manipulieren symbolischer Variablen. Lassen Sie uns eine erstellen:

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

xist kein bestimmter Wert. Es ist ein Platzhalter, ein Wert, den wir eingeben, wenn wir TensorFlow bitten, eine Berechnung auszuführen. Wir möchten in der Lage sein, eine beliebige Anzahl von MNIST-Bildern einzugeben, die jeweils zu einem 784-dimensionalen Vektor abgeflacht sind. Wir stellen dies als 2-D-Tensor von Gleitkommazahlen mit einer Form dar [Keine, 784]. (Hier bedeutet Keine, dass eine Dimension beliebig lang sein kann.)

Wir brauchen auch die Gewichte und Vorurteile für unser Modell. Wir könnten uns vorstellen, diese wie zusätzliche Eingaben zu behandeln, aber TensorFlow hat eine noch bessere Möglichkeit, damit umzugehen : Variable. A Variableist ein modifizierbarer Tensor, der in TensorFlows Diagramm der Interaktionsoperationen enthalten ist. Es kann durch die Berechnung verwendet und sogar modifiziert werden. Für maschinelle Lernanwendungen müssen im Allgemeinen die Modellparameter Variables sein.

W = tf.Variable(tf.zeros([784, 10]))

b = tf.Variable(tf.zeros([10]))

Wir erstellen diese Variables, indem wir tf.Variableden Anfangswert von Variable: angeben. In diesem Fall initialisieren wir beide Wund bals Tensoren voller Nullen. Da wir lernen werden Wund bes nicht sehr wichtig ist, was sie anfangs sind.


Hallo, danke für deine Antwort! In dem Beispiel, das Sie geben, haben wir xmit Form [batch size, features], wir haben die Gewichte, die von der Eingabe zur ersten Ebene der Größe [features, hidden units]und den Verzerrungen gehen [hidden units]. Meine Frage ist also: Wie multiplizieren wir sie miteinander? Wenn wir das tun, werden tf.matmul(x, w)wir es bekommen [batch size, hidden units]und wir können es nicht b, da es Form hat[hidden units]
Euler_Salter

1
M.Gorner erklärt dies alles in seinen Diashows "Learn TensorFlow und Deep Learning, ohne einen Doktortitel". besser als ich es jemals hier in diesem Kommentar tun könnte. Erlauben
tagoma

11

Tensorflow verwendet drei Arten von Containern, um den Prozess zu speichern / auszuführen

  1. Konstanten: Konstanten enthalten die typischen Daten.

  2. Variablen: Datenwerte werden mit den jeweiligen Funktionen wie cost_function geändert.

  3. Platzhalter: Trainings- / Testdaten werden an die Grafik übergeben.


10

Beispielausschnitt:

import numpy as np
import tensorflow as tf

### Model parameters ###
W = tf.Variable([.3], tf.float32)
b = tf.Variable([-.3], tf.float32)

### Model input and output ###
x = tf.placeholder(tf.float32)
linear_model = W * x + b
y = tf.placeholder(tf.float32)

### loss ###
loss = tf.reduce_sum(tf.square(linear_model - y)) # sum of the squares

### optimizer ###
optimizer = tf.train.GradientDescentOptimizer(0.01)
train = optimizer.minimize(loss)

### training data ###
x_train = [1,2,3,4]
y_train = [0,-1,-2,-3]

### training loop ###
init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init) # reset values to wrong
for i in range(1000):
  sess.run(train, {x:x_train, y:y_train})

Wie der Name schon sagt, ist ein Platzhalter ein Versprechen, später einen Wert bereitzustellen, d. H.

Variablen sind einfach die Trainingsparameter ( W(Matrix), b(Bias), die den normalen Variablen entsprechen, die Sie in Ihrer täglichen Programmierung verwenden und die der Trainer bei jedem Lauf / Schritt aktualisiert / ändert.

Während Platzhalter erfordert keinen Anfangswert, dass , wenn Sie erstellt xund yTF zugeordnet keinen Speicher, anstatt später , wenn Sie die Platzhalter in der Beschickung sess.run()mit feed_dict, TensorFlow den entsprechend dimensionierten Speicher für sie zuweisen ( xund y) - diese unconstrained- Mit dieser Funktion können wir Daten jeder Größe und Form eingeben.


Kurz gesagt :

Variable - ist ein Parameter, den der Trainer (dh GradientDescentOptimizer) nach jedem Schritt aktualisieren soll.

Platzhalter- Demo -

a = tf.placeholder(tf.float32)
b = tf.placeholder(tf.float32)
adder_node = a + b  # + provides a shortcut for tf.add(a, b)

Ausführung:

print(sess.run(adder_node, {a: 3, b:4.5}))
print(sess.run(adder_node, {a: [1,3], b: [2, 4]}))

was zur Ausgabe führt

7.5
[ 3.  7.]

Im ersten Fall werden 3 und 4.5 an abzw. bbzw. an adder_node ouputting 7 übergeben. Im zweiten Fall gibt es eine Feed-Liste. Die ersten Schritte 1 und 2 werden hinzugefügt, die nächsten 3 und 4 ( aund b).


Relevante liest:


7

Variablen

Eine TensorFlow-Variable ist der beste Weg, um einen von Ihrem Programm manipulierten gemeinsamen, dauerhaften Status darzustellen. Variablen werden über die Klasse tf.Variable bearbeitet. Intern speichert eine tf.Variable einen persistenten Tensor. Mit bestimmten Operationen können Sie die Werte dieses Tensors lesen und ändern. Diese Änderungen sind in mehreren tf.Sessions sichtbar, sodass mehrere Worker dieselben Werte für eine tf.Variable sehen können. Variablen müssen vor der Verwendung initialisiert werden.

Beispiel:

x = tf.Variable(3, name="x")
y = tf.Variable(4, name="y")
f = x*x*y + y + 2

Dadurch wird ein Berechnungsdiagramm erstellt. Die Variablen (x und y) können wie folgt initialisiert und die Funktion (f) in einer Tensorflow-Sitzung ausgewertet werden:

with tf.Session() as sess:
     x.initializer.run()
     y.initializer.run()
     result = f.eval()
print(result)
42

Platzhalter

Ein Platzhalter ist ein Knoten (wie eine Variable), dessen Wert in Zukunft initialisiert werden kann. Diese Knoten geben grundsätzlich den ihnen zur Laufzeit zugewiesenen Wert aus. Ein Platzhalterknoten kann mithilfe der Klasse tf.placeholder () zugewiesen werden, für die Sie Argumente wie den Typ der Variablen und / oder ihre Form angeben können. Platzhalter werden häufig zur Darstellung des Trainingsdatensatzes in einem Modell für maschinelles Lernen verwendet, da sich der Trainingsdatensatz ständig ändert.

Beispiel:

A = tf.placeholder(tf.float32, shape=(None, 3))
B = A + 5

Hinweis: "Keine" für eine Dimension bedeutet "beliebige Größe".

with tf.Session as sess:
    B_val_1 = B.eval(feed_dict={A: [[1, 2, 3]]})
    B_val_2 = B.eval(feed_dict={A: [[4, 5, 6], [7, 8, 9]]})

print(B_val_1)
[[6. 7. 8.]]
print(B_val_2)
[[9. 10. 11.]
 [12. 13. 14.]]

Verweise:

  1. https://www.tensorflow.org/guide/variables
  2. https://www.tensorflow.org/api_docs/python/tf/placeholder
  3. O'Reilly: Praktisches maschinelles Lernen mit Scikit-Learn & Tensorflow

6

VariableStellen Sie sich in Tensorflow normale Variablen vor, die wir in Programmiersprachen verwenden. Wir initialisieren Variablen, wir können sie auch später ändern. Wobei placeholderkein Anfangswert erforderlich ist. Der Platzhalter weist einfach einen Speicherblock für die zukünftige Verwendung zu. Später können wir feed_dictdie Daten einspeisen placeholder. Standardmäßig placeholderhat es eine uneingeschränkte Form, mit der Sie Tensoren unterschiedlicher Form in einer Sitzung füttern können. Sie können eine eingeschränkte Form erstellen, indem Sie die optionale Argumentform -shap übergeben, wie unten beschrieben.

x = tf.placeholder(tf.float32,(3,4))
y =  x + 2

sess = tf.Session()
print(sess.run(y)) # will cause an error

s = np.random.rand(3,4)
print(sess.run(y, feed_dict={x:s}))

Während der maschinellen Lernaufgabe ist uns die Anzahl der Zeilen meistens nicht bekannt, aber (nehmen wir an) wir kennen die Anzahl der Features oder Spalten. In diesem Fall können wir None verwenden.

x = tf.placeholder(tf.float32, shape=(None,4))

Jetzt können wir zur Laufzeit jede Matrix mit 4 Spalten und beliebig vielen Zeilen füttern.

Platzhalter werden auch für Eingabedaten verwendet (es handelt sich um Variablen, mit denen wir unser Modell füttern), wobei Variablen Parameter wie Gewichte sind, die wir im Laufe der Zeit trainieren.


4

Platzhalter:

  1. Ein Platzhalter ist einfach eine Variable, der wir zu einem späteren Zeitpunkt Daten zuweisen. Es ermöglicht uns, unsere Operationen zu erstellen und unser Berechnungsdiagramm zu erstellen, ohne die Daten zu benötigen. In der TensorFlow-Terminologie geben wir dann Daten über diese Platzhalter in das Diagramm ein.

  2. Anfangswerte sind nicht erforderlich, können aber Standardwerte mit haben tf.placeholder_with_default)

  3. Wir müssen zur Laufzeit einen Wert liefern wie:

    a = tf.placeholder(tf.int16) // initialize placeholder value
    b = tf.placeholder(tf.int16) // initialize placeholder value
    
    use it using session like :
    
    sess.run(add, feed_dict={a: 2, b: 3}) // this value we have to assign at runtime

Variable:

  1. Eine TensorFlow-Variable ist der beste Weg, um einen von Ihrem Programm manipulierten gemeinsamen, dauerhaften Status darzustellen.
  2. Variablen werden über die Klasse tf.Variable bearbeitet. Eine tf.Variable stellt einen Tensor dar, dessen Wert durch Ausführen von ops geändert werden kann.

Beispiel: tf.Variable("Welcome to tensorflow!!!")


3

Tensorflow 2.0-kompatible Antwort : Das Konzept der Platzhalter ist standardmäßig tf.placeholdernicht verfügbar Tensorflow 2.x (>= 2.0), da der Standardausführungsmodus Eager Execution ist.

Wir können sie jedoch verwenden, wenn sie in Graph Mode( Disable Eager Execution) verwendet werden.

Entsprechender Befehl für TF Placeholder in Version 2.x ist tf.compat.v1.placeholder.

Der äquivalente Befehl für die TF-Variable in Version 2.x lautet. tf.VariableWenn Sie den Code von 1.x auf 2.x migrieren möchten, lautet der äquivalente Befehl

tf.compat.v2.Variable.

Weitere Informationen zu Tensorflow Version 2.0 finden Sie auf dieser Tensorflow-Seite .

Weitere Informationen zur Migration von Version 1.x auf Version 2.x finden Sie im Migrationshandbuch .


2

Stellen Sie sich ein Berechnungsdiagramm vor . In einem solchen Diagramm benötigen wir einen Eingabeknoten, um unsere Daten an das Diagramm zu übergeben . Diese Knoten sollten als Platzhalter im Tensorflow definiert werden .

Denken Sie nicht als allgemeines Programm in Python. Sie können ein Python-Programm schreiben und all die Dinge tun, die in anderen Antworten nur durch Variablen erklärt wurden. Für Berechnungsdiagramme im Tensorflow müssen Sie diese Nods jedoch als Platzhalter definieren, um Ihre Daten dem Diagramm zuzuführen.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.