¿Cuál es la diferencia entre tf.placeholder y tf.Variable?

290

Soy un novato en TensorFlow. Estoy confundido acerca de la diferencia entre tf.placeholdery tf.Variable. En mi opinión, tf.placeholderse usa para datos de entrada y tf.Variablepara almacenar el estado de los datos. Esto es todo lo que sé.

¿Podría alguien explicarme más detalladamente sobre sus diferencias? En particular, ¿cuándo usar tf.Variabley cuándo usar tf.placeholder?

J.Doe
fuente
77
Intuitivamente, querrá gradientes con respecto a Variables, pero no placeholders (cuyos valores siempre deben proporcionarse).
Yibo Yang
Un curso como cs231n.stanford.edu puede ayudar a los confundidos. ¡Me gustó mucho! Obviamente hay otros
Nathan

Respuestas:

175

En resumen, utiliza tf.Variablepara variables entrenables como pesos (W) y sesgos (B) para su modelo.

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 se utiliza para alimentar ejemplos de entrenamiento reales.

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

Así es como alimentas los ejemplos de entrenamiento durante el entrenamiento:

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)

Serás tf.variablesentrenado (modificado) como resultado de este entrenamiento.

Ver más en https://www.tensorflow.org/versions/r0.7/tutorials/mnist/tf/index.html . (Se toman ejemplos de la página web).

Sung Kim
fuente
2
¿Qué sucede si quiero preprocesar mi imagen antes de alimentarla? (por ejemplo, reescalar el contraste). ¿Ahora necesito una variable para esto? Si es así, ¿tiene alguna memoria o implicaciones de velocidad?
Bastiaan
1
Cualquier preprocesamiento que realice vendrá antes de alimentar los datos en el gráfico de Tensorflow (es decir, la red), para que el trabajo no requiera técnicamente ninguna herramienta de código de Tensorflow. Por ejemplo, una variable sería innecesaria 1. porque son datos de entrada, que se pasan a través de tf. Marcadores de posición (no variables) en el gráfico y 2. El preprocesamiento ocurre antes de cargarse en un marcador de posición para el paso actual a través de la red .
PaulG
Solo quería notar cuánto aprecio esta respuesta. El hecho de que hay muchos menos upvotes en esta respuesta que en la cuestión sólo sirve para demostrar cómo la gente de gratificación instantánea pueden ser, y cómo las etiquetas de moda como tensorflowe deep learningy AIson.
Nathan
70

La diferencia es que con tf.Variableusted debe proporcionar un valor inicial cuando lo declara. Con tf.placeholderusted no tiene que proporcionar un valor inicial y puede especificarlo en tiempo de ejecución con el feed_dictargumento dentroSession.run

fabrizioM
fuente
63
-1. Si bien es cierto, esto pierde el punto. La diferencia más importante es su papel dentro de TensorFlow. Las variables se entrenan con el tiempo, los marcadores de posición son datos de entrada que no cambian a medida que su modelo entrena (como las imágenes de entrada y las etiquetas de clase para esas imágenes). Como dice la respuesta de Sung Kim, usted usa variables para pesos y sesgos en su modelo (aunque no se limita a eso, para la transferencia de estilo, optimiza una imagen con el tiempo).
Chris Anderson
@ChrisAnderson, ¿podríamos decir que esta ilustración está mal? youtu.be/MotG3XI2qSs?t=136
N0rA
@ChrisAnderson ¿Por qué importa para qué se debe usar, si las diferencias son solo una, necesita un valor inicial?
Goldname
1
@Goldname No es para lo que está "destinado" ser utilizado, es lo que es posible y no es posible. Son objetos totalmente diferentes. No son intercambiables, y las diferencias son más que "uno necesita un valor inicial".
Chris Anderson
61

Dado que los cálculos de Tensor se componen de gráficos, entonces es mejor interpretar los dos en términos de gráficos.

Tomemos por ejemplo la regresión lineal simple

WX+B=Y

dónde Wy Brepresentar los pesos y el sesgo y Xlas entradas Yde las observaciones y las salidas de las observaciones.

Obviamente Xy Yson de la misma naturaleza (variables manifiestas) que difieren de la de Wy B(variables latentes). Xy Yson valores de las muestras (observaciones) y, por lo tanto, necesitan un lugar para ser llenado , mientras que Wy Bson los pesos y el sesgo, las variables (los valores anteriores afectan a las últimas) en el gráfico que deben entrenarse utilizando diferentes Xy Ypares. Colocamos diferentes muestras a los Marcadores de posición para entrenar las Variables .

Solo necesitamos guardar o restaurar las Variables (en los puntos de control) para guardar o reconstruir el gráfico con el código.

Los marcadores de posición son en su mayoría titulares de los diferentes conjuntos de datos (por ejemplo, datos de capacitación o datos de prueba). Sin embargo, las variables se entrenan en el proceso de capacitación para las tareas específicas, es decir, para predecir el resultado de la entrada o asignar las entradas a las etiquetas deseadas. Siguen siendo los mismos hasta que vuelva a entrenar o ajustar el modelo utilizando muestras diferentes o iguales para rellenar los Marcadores de posición a menudo a través del dict. Por ejemplo:

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

Los marcadores de posición también se pasan como parámetros para establecer modelos.

Si cambia los marcadores de posición (agregar, eliminar, cambiar la forma, etc.) de un modelo en medio del entrenamiento, aún puede volver a cargar el punto de control sin ninguna otra modificación. Pero si se cambian las variables de un modelo guardado, debe ajustar el punto de control en consecuencia para volver a cargarlo y continuar el entrenamiento (todas las variables definidas en el gráfico deben estar disponibles en el punto de control).

En resumen, si los valores provienen de las muestras (observaciones que ya tiene), puede hacer un marcador de posición para mantenerlos, mientras que si necesita un parámetro para entrenar, aproveche una Variable (simplemente, establezca las Variables para los valores que desea para usar TF automáticamente).

En algunos modelos interesantes, como un modelo de transferencia de estilo , los pixeles de entrada se optimizarán y las variables del modelo normalmente llamadas son fijas, entonces deberíamos hacer que la entrada (generalmente inicializada al azar) sea una variable tal como se implementa en ese enlace.

Para obtener más información, infiera a este documento simple e ilustrativo .

Lerner Zhang
fuente
38

TL; DR

Variables

  • Para parámetros para aprender
  • Los valores pueden derivarse del entrenamiento
  • Se requieren valores iniciales (a menudo al azar)

Marcadores de posición

  • Almacenamiento asignado para datos (como para datos de píxeles de imagen durante una alimentación)
  • Los valores iniciales no son obligatorios (pero se pueden configurar, ver tf.placeholder_with_default)
James
fuente
34

La diferencia más obvia entre el tf. Variable y el tf.placeholder es que


usa variables para mantener y actualizar parámetros. Las variables son memorias intermedias en memoria que contienen tensores. Deben inicializarse explícitamente y pueden guardarse en el disco durante y después del entrenamiento. Posteriormente puede restaurar los valores guardados para ejercitar o analizar el modelo.

La inicialización de las variables se realiza con sess.run(tf.global_variables_initializer()) . Además, al crear una variable, debe pasar un Tensor como su valor inicial al Variable()constructor y cuando crea una variable siempre conoce su forma.


Por otro lado, no puede actualizar el marcador de posición. Tampoco deben inicializarse, pero debido a que son una promesa de tener un tensor, es necesario introducir el valor en ellos.sess.run(<op>, {a: <some_val>}) . Y, por último, en comparación con una variable, el marcador de posición podría no conocer la forma. Puede proporcionar partes de las dimensiones o no proporcionar nada en absoluto.


Hay otras diferencias:

Lo interesante es que no solo se pueden alimentar los marcadores de posición. Puede alimentar el valor a una variable e incluso a una constante.

Salvador Dalí
fuente
14

Además de las respuestas de otros, también lo explican muy bien en este tutorial de MNIST en el sitio web de Tensoflow:

Describimos estas operaciones de interacción mediante la manipulación de variables simbólicas. Vamos a crear uno:

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

xNo es un valor específico. Es un marcador de posición, un valor que ingresaremos cuando le solicitemos a TensorFlow que ejecute un cálculo. Queremos poder ingresar cualquier cantidad de imágenes MNIST, cada una aplanada en un vector de 784 dimensiones. Representamos esto como un tensor 2-D de números de coma flotante, con una forma [Ninguno, 784]. (Aquí Ninguno significa que una dimensión puede ser de cualquier longitud).

También necesitamos los pesos y sesgos para nuestro modelo. Podríamos imaginar que el tratamiento de estos como entradas adicionales, pero TensorFlow tiene una mejor manera de manejar la situación: Variable. A Variablees un tensor modificable que vive en el gráfico de operaciones interactivas de TensorFlow. Puede ser utilizado e incluso modificado por el cálculo. Para aplicaciones de aprendizaje automático, generalmente los parámetros del modelo son Variables.

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

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

Creamos estos Variables dando tf.Variableel valor inicial de Variable: en este caso, inicializamos ambos Wy bcomo tensores llenos de ceros. Como vamos a aprender Wy b, no importa mucho cuáles son inicialmente.

tagoma
fuente
¡Hola, gracias por tu respuesta! En el ejemplo que da, tenemos xforma [batch size, features], tenemos los pesos que van desde la entrada hasta la primera capa de tamaño [features, hidden units]y los sesgos [hidden units]. Entonces mi pregunta es: ¿cómo los multiplicamos? Si lo hacemos, tf.matmul(x, w)entonces vamos a llegar [batch size, hidden units]y no podemos bhacerlo, ya que tiene forma[hidden units]
Euler_Salter
1
M.Gorner explica todo esto en sus presentaciones de diapositivas "Aprenda TensorFlow y el aprendizaje profundo, sin un doctorado". mejor de lo que podría hacer aquí en este comentario. Entonces, permítanme referirme a esta diapositiva: docs.google.com/presentation/d/…
tagoma
11

Tensorflow utiliza tres tipos de contenedores para almacenar / ejecutar el proceso.

  1. Constantes: las constantes contienen los datos típicos.

  2. variables: los valores de los datos se cambiarán, con las funciones respectivas, como cost_function.

  3. marcadores de posición: los datos de capacitación / prueba se pasarán al gráfico.

Karnakar Reddy
fuente
10

Fragmento de ejemplo:

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})

Como su nombre lo indica, el marcador de posición es una promesa de proporcionar un valor más adelante, es decir

Las variables son simplemente los parámetros de entrenamiento ( W(matriz),b (sesgo) iguales a las variables normales que usa en su programación diaria, que el entrenador actualiza / modifica en cada carrera / paso.

Si bien el marcador de posición no requiere ningún valor inicial, cuando creó xy yTF no asignó ninguna memoria, en su lugar más tarde cuando alimente los marcadores de posición en el sess.run()uso feed_dict, TensorFlow asignará la memoria del tamaño adecuado para ellos ( xy y), esto sin restricciones. Ness nos permite alimentar cualquier tamaño y forma de datos.


En pocas palabras :

Variable : es un parámetro que desea que el entrenador (es decir, GradientDescentOptimizer) actualice después de cada paso.

Demo de marcador de posición -

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

Ejecución:

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

resultando en la salida

7.5
[ 3.  7.]

En el primer caso, 3 y 4.5 se pasarán a ay brespectivamente, y luego a adder_node ouputting 7. En el segundo caso hay una lista de fuentes, se agregarán los primeros pasos 1 y 2, luego los 3 y 4 ( ay b).


Lecturas relevantes:

Nabeel Ahmed
fuente
7

Variables

Una variable TensorFlow es la mejor manera de representar el estado compartido persistente manipulado por su programa. Las variables se manipulan a través de la clase tf.Variable. Internamente, un tf.Variable almacena un tensor persistente. Las operaciones específicas le permiten leer y modificar los valores de este tensor. Estas modificaciones son visibles en varias sesiones de tf, por lo que varios trabajadores pueden ver los mismos valores para una tf.Variable. Las variables deben inicializarse antes de usar.

Ejemplo:

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

Esto crea un gráfico de cálculo. Las variables (x e y) se pueden inicializar y evaluar la función (f) en una sesión de tensorflow de la siguiente manera:

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

Marcadores de posición

Un marcador de posición es un nodo (igual que una variable) cuyo valor se puede inicializar en el futuro. Estos nodos básicamente generan el valor asignado a ellos durante el tiempo de ejecución. Se puede asignar un nodo de marcador de posición utilizando la clase tf.placeholder () a la que puede proporcionar argumentos como el tipo de la variable y / o su forma. Los marcadores de posición se utilizan ampliamente para representar el conjunto de datos de entrenamiento en un modelo de aprendizaje automático a medida que el conjunto de datos de entrenamiento cambia constantemente.

Ejemplo:

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

Nota: 'Ninguno' para una dimensión significa 'cualquier tamaño'.

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.]]

Referencias

  1. https://www.tensorflow.org/guide/variables
  2. https://www.tensorflow.org/api_docs/python/tf/placeholder
  3. O'Reilly: Aprendizaje automático práctico con Scikit-Learn y Tensorflow
Ankita Mishra
fuente
6

Piense en Variablein tensorflow como variables normales que usamos en lenguajes de programación. Inicializamos variables, también podemos modificarlo más tarde. Mientras placeholderque no requiere valor inicial. El marcador de posición simplemente asigna un bloque de memoria para uso futuro. Más tarde, podemos usar feed_dictpara alimentar los datos placeholder. De forma predeterminada, placeholdertiene una forma sin restricciones, que le permite alimentar tensores de diferentes formas en una sesión. Puede hacer una forma restringida pasando el argumento opcional -shape, como he hecho a continuación.

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}))

Mientras realizamos la tarea de Aprendizaje automático, la mayoría de las veces desconocemos la cantidad de filas, pero (supongamos) sabemos la cantidad de características o columnas. En ese caso, podemos usar Ninguno.

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

Ahora, en tiempo de ejecución, podemos alimentar cualquier matriz con 4 columnas y cualquier número de filas.

Además, los marcadores de posición se utilizan para los datos de entrada (son un tipo de variables que utilizamos para alimentar nuestro modelo), donde las variables son parámetros tales como los pesos que entrenamos con el tiempo.

Muhammad Usman
fuente
4

Marcador de posición:

  1. Un marcador de posición es simplemente una variable a la que asignaremos datos en una fecha posterior. Nos permite crear nuestras operaciones y construir nuestro gráfico de cálculo, sin necesidad de los datos. En la terminología de TensorFlow, luego introducimos datos en el gráfico a través de estos marcadores de posición.

  2. Los valores iniciales no son obligatorios, pero pueden tener valores predeterminados con tf.placeholder_with_default)

  3. Tenemos que proporcionar valor en tiempo de ejecución como:

    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. Una variable TensorFlow es la mejor manera de representar el estado compartido persistente manipulado por su programa.
  2. Las variables se manipulan a través de la clase tf.Variable. Un tf.Variable representa un tensor cuyo valor se puede cambiar ejecutando operaciones en él.

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

jitsm555
fuente
3

Respuesta compatible con Tensorflow 2.0 : El concepto de Marcadores de posición tf.placeholderno estará disponible Tensorflow 2.x (>= 2.0)de forma predeterminada, ya que el Modo de ejecución predeterminado es Ejecución ansiosa.

Sin embargo, podemos usarlos si se usan en Graph Mode( Disable Eager Execution).

El comando equivalente para TF Placeholder en la versión 2.x es tf.compat.v1.placeholder.

El comando equivalente para la variable TF en la versión 2.x es tf.Variabley si desea migrar el código de 1.xa 2.x, el comando equivalente es

tf.compat.v2.Variable.

Consulte esta página de Tensorflow para obtener más información sobre Tensorflow Versión 2.0.

Consulte la Guía de migración para obtener más información sobre la migración de las versiones 1.xa 2.x.

Soporte Tensorflow
fuente
2

Piensa en un gráfico de cálculo . En dicho gráfico, necesitamos un nodo de entrada para pasar nuestros datos al gráfico, esos nodos deben definirse como Placeholder en el tensorflow .

No pienses como un programa general en Python. Puede escribir un programa Python y hacer todas esas cosas que los chicos explicaron en otras respuestas solo con Variables, pero para los gráficos de cálculo en tensorflow, para alimentar sus datos al gráfico, debe definir esos guiños como Marcadores de posición.

Ali Salehi
fuente