Quelle est la différence entre tf.placeholder et tf.Variable?


290

Je suis un débutant à TensorFlow. Je suis confus quant à la différence entre tf.placeholderet tf.Variable. À mon avis, tf.placeholderest utilisé pour les données d'entrée et tf.Variableest utilisé pour stocker l'état des données. C'est tout ce que je sais.

Quelqu'un pourrait-il m'expliquer plus en détail leurs différences? En particulier, quand utiliser tf.Variableet quand utiliser tf.placeholder?


7
Intuitivement, vous voudrez des gradients par rapport à Variables, mais pas à placeholders (dont les valeurs doivent toujours être fournies).
Yibo Yang

Un cours comme cs231n.stanford.edu peut aider ceux qui sont confus. J'ai beaucoup aimé! Évidemment, il y en a d'autres
Nathan

Réponses:


175

En bref, vous utilisez tf.Variablepour des variables entraînables telles que les poids (W) et les biais (B) pour votre modèle.

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 est utilisé pour alimenter des exemples de formation réels.

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

Voici comment vous alimentez les exemples de formation pendant la formation:

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)

Votre tf.variablessera formé (modifié) à la suite de cette formation.

Voir plus sur https://www.tensorflow.org/versions/r0.7/tutorials/mnist/tf/index.html . (Des exemples sont tirés de la page Web.)


2
Que faire si je souhaite prétraiter mon image avant de l'introduire? (par exemple, redimensionner le contraste). Ai-je maintenant besoin d'une variable pour cela? Si oui, cela a-t-il des implications en termes de mémoire ou de vitesse?
Bastiaan

1
Tout prétraitement que vous effectuez va venir avant d'introduire les données dans le graphique Tensorflow (c'est-à-dire le réseau), de sorte que le travail ne nécessite techniquement aucun outil de code de Tensorflow. Par exemple, une variable ne serait pas nécessaire 1. car ce sont des données d'entrée, qui sont transmises via tf.placeholders (pas des variables) dans le graphique et 2. Le prétraitement se produit avant d'être chargé dans un espace réservé pour le passage actuel à travers le réseau .
PaulG

Je voulais juste noter combien j'apprécie cette réponse. Le fait qu'il y ait beaucoup moins de votes positifs sur cette réponse que sur la question ne fait que montrer à quel point les gens peuvent être satisfaits instantanément, et à quel point les balises tendance aiment tensorflowet deep learninget AIsont.
Nathan

70

La différence est que tf.Variablevous devez fournir une valeur initiale lorsque vous la déclarez. Avec tf.placeholdervous n'avez pas à fournir une valeur initiale et vous pouvez la spécifier au moment de l'exécution avec l' feed_dictargument à l'intérieurSession.run


63
-1. Bien que cela soit vrai, cela manque le point. La différence la plus importante est leur rôle au sein de TensorFlow. Les variables sont entraînées au fil du temps, les espaces réservés sont des données d'entrée qui ne changent pas au fur et à mesure que votre modèle s'entraîne (comme les images d'entrée et les étiquettes de classe pour ces images). Comme le dit la réponse de Sung Kim, vous utilisez des variables pour les poids et les biais dans votre modèle (mais sans s'y limiter - pour le transfert de style, vous optimisez une image dans le temps).
Chris Anderson

@ChrisAnderson pourrait-on dire que cette illustration est fausse?! youtu.be/MotG3XI2qSs?t=136
N0rA

@ChrisAnderson Pourquoi est-il important de savoir pourquoi il est destiné à être utilisé, si les différences ne sont qu'une, il faut une valeur initiale?
Goldname

1
@Goldname Ce n'est pas ce pour quoi il est "destiné" à être utilisé - c'est ce qui est possible et ce n'est pas possible. Ce sont des objets totalement différents. Ils ne sont pas interchangeables et les différences sont plus que "il faut une valeur initiale".
Chris Anderson

61

Étant donné que les calculs Tensor se composent de graphiques, il est préférable d'interpréter les deux en termes de graphiques.

Prenons par exemple la régression linéaire simple

WX+B=Y

Wet Bpour les poids et biais et Xpour les entrées des observations et Ypour les sorties des observations.

Evidemment Xet Ysont de même nature (variables manifestes) qui diffèrent de celle de Wet B(variables latentes). Xet Ysont des valeurs des échantillons (observations) et ont donc besoin d'une place à remplir , tandis que Wet Bsont les poids et les biais, les variables (les valeurs précédentes affectent ces dernières) dans le graphique qui doivent être entraînées à l'aide de différents Xet de Ypaires. Nous plaçons différents échantillons dans les espaces réservés pour former les variables .

Nous avons seulement besoin d' enregistrer ou de restaurer les variables (aux points de contrôle) pour enregistrer ou reconstruire le graphique avec le code.

Les espaces réservés sont principalement des détenteurs pour les différents ensembles de données (par exemple des données de formation ou des données de test). Cependant, les variables sont formées au processus de formation pour les tâches spécifiques, c'est-à-dire pour prédire le résultat de l'entrée ou mapper les entrées aux étiquettes souhaitées. Ils restent les mêmes jusqu'à ce que vous réentraîniez ou affiniez le modèle en utilisant des échantillons différents ou identiques à remplir dans les espaces réservés souvent via le dict. Par exemple:

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

Les espaces réservés sont également passés en tant que paramètres pour définir des modèles.

Si vous modifiez des espaces réservés (ajoutez, supprimez, modifiez la forme, etc.) d'un modèle au milieu de la formation, vous pouvez toujours recharger le point de contrôle sans aucune autre modification. Mais si les variables d'un modèle enregistré sont modifiées, vous devez ajuster le point de contrôle en conséquence pour le recharger et continuer la formation (toutes les variables définies dans le graphique doivent être disponibles dans le point de contrôle).

Pour résumer, si les valeurs proviennent des échantillons (observations que vous avez déjà), vous créez en toute sécurité un espace réservé pour les conserver, tandis que si vous avez besoin d'un paramètre pour être formé, exploitez une variable (mettez simplement, définissez les variables pour les valeurs que vous voulez pour utiliser TF automatiquement).

Dans certains modèles intéressants, comme un modèle de transfert de style , les pixels d'entrée vont être optimisés et les variables de modèle normalement appelées sont fixes, alors nous devrions faire de l'entrée (généralement initialisée au hasard) en tant que variable implémentée dans ce lien.

Pour plus d'informations, veuillez vous référer à ce document simple et illustrant .


38

TL; DR

Variables

  • Pour les paramètres à apprendre
  • Les valeurs peuvent être dérivées de la formation
  • Les valeurs initiales sont requises (souvent aléatoires)

Espaces réservés

  • Stockage alloué pour les données (comme pour les données de pixels d'image lors d'un flux)
  • Les valeurs initiales ne sont pas requises (mais peuvent être définies, voir tf.placeholder_with_default)

34

La différence la plus évidente entre le tf.Variable et le tf.placeholder est que


vous utilisez des variables pour conserver et mettre à jour les paramètres. Les variables sont des tampons en mémoire contenant des tenseurs. Ils doivent être explicitement initialisés et peuvent être enregistrés sur le disque pendant et après la formation. Vous pouvez ensuite restaurer les valeurs enregistrées pour exercer ou analyser le modèle.

L'initialisation des variables se fait avec sess.run(tf.global_variables_initializer()). De plus, lors de la création d'une variable, vous devez transmettre un tenseur comme valeur initiale au Variable()constructeur et lorsque vous créez une variable, vous connaissez toujours sa forme.


En revanche, vous ne pouvez pas mettre à jour l'espace réservé. Ils ne doivent pas non plus être initialisés, mais comme ils sont une promesse d'avoir un tenseur, vous devez leur fournir la valeur sess.run(<op>, {a: <some_val>}). Et enfin, par rapport à une variable, l'espace réservé peut ne pas connaître la forme. Vous pouvez soit fournir des parties des dimensions, soit ne rien fournir du tout.


Il y a d'autres différences:

La partie intéressante est que non seulement les espaces réservés peuvent être alimentés. Vous pouvez fournir la valeur à une variable et même à une constante.


14

Ajoutant aux réponses des autres, ils l'expliquent également très bien dans ce tutoriel MNIST sur le site Web de Tensoflow:

Nous décrivons ces opérations en interaction en manipulant des variables symboliques. Créons-en un:

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

xn'est pas une valeur spécifique. C'est un espace réservé, une valeur que nous entrerons lorsque nous demanderons à TensorFlow d'exécuter un calcul. Nous voulons être en mesure de saisir n'importe quel nombre d'images MNIST, chacune aplatie dans un vecteur à 784 dimensions. Nous représentons cela comme un tenseur 2D de nombres à virgule flottante, avec une forme [Aucun, 784]. (Ici, None signifie qu'une dimension peut être de n'importe quelle longueur.)

Nous avons également besoin des poids et des biais pour notre modèle. On pourrait imaginer le traitement de ces entrées supplémentaires comme, mais tensorflow a une meilleure façon de le gérer: Variable. A Variableest un tenseur modifiable qui vit dans le graphique des opérations en interaction de TensorFlow. Il peut être utilisé et même modifié par le calcul. Pour les applications d'apprentissage automatique, on a généralement les paramètres du modèle Variables.

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

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

Nous créons ces Variables en donnant tf.Variablela valeur initiale de la Variable: dans ce cas, nous initialisons à la fois Wet en btant que tenseurs pleins de zéros. Puisque nous allons apprendre Wet b, peu importe ce qu'ils sont au départ.


salut merci pour votre réponse! Dans l'exemple que vous donnez, nous avons xavec la forme [batch size, features], nous avons les poids allant de l'entrée à la première couche de taille [features, hidden units]et les biais [hidden units]. Ma question est donc: comment les multiplier ensemble? Si nous le faisons, tf.matmul(x, w)nous allons y arriver [batch size, hidden units]et nous ne pouvons pas le bfaire, car il a une forme[hidden units]
Euler_Salter

1
M.Gorner explique tout cela dans ses diaporamas "Apprenez TensorFlow et l'apprentissage profond, sans doctorat." mieux que je ne pourrais jamais le faire ici dans ce commentaire. Alors, permettez-moi de me référer à cette diapositive: docs.google.com/presentation/d/…
tagoma

11

Tensorflow utilise trois types de conteneurs pour stocker / exécuter le processus

  1. Constantes: les constantes contiennent les données typiques.

  2. variables: Les valeurs des données seront modifiées, avec respectivement les fonctions telles que cost_function ..

  3. espaces réservés: les données de formation / test seront transmises au graphique.


10

Exemple d'extrait:

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

Comme son nom l'indique, l'espace réservé est une promesse de fournir une valeur plus tard, c'est-à-dire

Les variables sont simplement les paramètres d'entraînement ( W(matrice), b(biais) identiques aux variables normales que vous utilisez dans votre programmation quotidienne, que le formateur met à jour / modifie à chaque exécution / étape.

Bien que l' espace réservé ne nécessite aucune valeur initiale, que lorsque vous avez créé xet que yTF n'alloue pas de mémoire, au lieu de cela plus tard lorsque vous alimentez les espaces réservés à l' sess.run()aide feed_dict, TensorFlow leur allouera la mémoire de taille appropriée ( xet y) - ceci sans contrainte - ness nous permet d'alimenter n'importe quelle taille et forme de données.


En bref :

Variable - est un paramètre que le formateur (ie GradientDescentOptimizer) doit mettre à jour après chaque étape.

Démo de l' espace réservé -

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

Exécution:

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

résultant en la sortie

7.5
[ 3.  7.]

Dans le premier cas, 3 et 4.5 seront transmis à aet brespectivement, puis à adder_node ouputting 7. Dans le second cas, il y a une liste de flux, les premières étapes 1 et 2 seront ajoutées, les 3 et 4 suivants ( aet b).


Lectures pertinentes:


7

Variables

Une variable TensorFlow est le meilleur moyen de représenter un état partagé et persistant manipulé par votre programme. Les variables sont manipulées via la classe tf.Variable. En interne, une tf.Variable stocke un tenseur persistant. Des opérations spécifiques vous permettent de lire et de modifier les valeurs de ce tenseur. Ces modifications sont visibles sur plusieurs tf.Sessions, de sorte que plusieurs travailleurs peuvent voir les mêmes valeurs pour un tf.Variable. Les variables doivent être initialisées avant d'être utilisées.

Exemple:

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

Cela crée un graphique de calcul. Les variables (x et y) peuvent être initialisées et la fonction (f) évaluée dans une session tensorflow comme suit:

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

Espaces réservés

Un espace réservé est un nœud (identique à une variable) dont la valeur peut être initialisée à l'avenir. Ces nœuds génèrent essentiellement la valeur qui leur est affectée lors de l'exécution. Un nœud d'espace réservé peut être attribué à l'aide de la classe tf.placeholder () à laquelle vous pouvez fournir des arguments tels que le type de la variable et / ou sa forme. Les espaces réservés sont largement utilisés pour représenter l'ensemble de données d'apprentissage dans un modèle d'apprentissage automatique, car l'ensemble de données d'apprentissage continue de changer.

Exemple:

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

Remarque: «Aucun» pour une dimension signifie «n'importe quelle taille».

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

Références:

  1. https://www.tensorflow.org/guide/variables
  2. https://www.tensorflow.org/api_docs/python/tf/placeholder
  3. O'Reilly: apprentissage automatique pratique avec Scikit-Learn et Tensorflow

6

Considérez Variabledans tensorflow comme des variables normales que nous utilisons dans les langages de programmation. Nous initialisons des variables, nous pouvons également les modifier plus tard. Alors que placeholderne nécessite pas de valeur initiale. L'espace réservé alloue simplement un bloc de mémoire pour une utilisation future. Plus tard, nous pouvons utiliser feed_dictpour alimenter les données placeholder. Par défaut, placeholdera une forme sans contrainte, ce qui vous permet d'alimenter des tenseurs de formes différentes dans une session. Vous pouvez créer une forme contrainte en passant l'argument optionnel -shape, comme je l'ai fait ci-dessous.

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

Lors de la tâche d'apprentissage automatique, la plupart du temps, nous ne connaissons pas le nombre de lignes, mais (supposons), nous connaissons le nombre de fonctionnalités ou de colonnes. Dans ce cas, nous pouvons utiliser None.

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

Maintenant, au moment de l'exécution, nous pouvons alimenter n'importe quelle matrice avec 4 colonnes et n'importe quel nombre de lignes.

En outre, les espaces réservés sont utilisés pour les données d'entrée (ce sont des types de variables que nous utilisons pour alimenter notre modèle), où les variables sont des paramètres tels que les poids que nous entraînons au fil du temps.


4

Espace réservé:

  1. Un espace réservé est simplement une variable à laquelle nous assignerons des données à une date ultérieure. Il nous permet de créer nos opérations et de construire notre graphe de calcul, sans avoir besoin des données. Dans la terminologie TensorFlow, nous introduisons ensuite des données dans le graphique via ces espaces réservés.

  2. Les valeurs initiales ne sont pas obligatoires mais peuvent avoir des valeurs par défaut avec tf.placeholder_with_default)

  3. Nous devons fournir de la valeur lors de l'exécution comme:

    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. Une variable TensorFlow est le meilleur moyen de représenter un état partagé et persistant manipulé par votre programme.
  2. Les variables sont manipulées via la classe tf.Variable. Une tf.Variable représente un tenseur dont la valeur peut être modifiée en exécutant ops dessus.

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


3

Réponse compatible avec Tensorflow 2.0 : Le concept d' espaces réservéstf.placeholder ne sera pas disponible Tensorflow 2.x (>= 2.0)par défaut, car le mode d'exécution par défaut est Exécution désirée.

Cependant, nous pouvons les utiliser s'ils sont utilisés dans Graph Mode( Disable Eager Execution).

La commande équivalente pour TF Placeholder dans la version 2.x est tf.compat.v1.placeholder.

La commande équivalente pour la variable TF dans la version 2.x est tf.Variableet si vous souhaitez migrer le code de 1.x vers 2.x, la commande équivalente est

tf.compat.v2.Variable.

Veuillez consulter cette page Tensorflow pour plus d'informations sur Tensorflow version 2.0.

Veuillez consulter le Guide de migration pour plus d'informations sur la migration des versions 1.x à 2.x.


2

Pensez à un graphique de calcul . Dans un tel graphique, nous avons besoin d'un nœud d'entrée pour transmettre nos données au graphique, ces nœuds doivent être définis comme espace réservé dans tensorflow .

Ne pensez pas comme un programme général en Python. Vous pouvez écrire un programme Python et faire toutes ces choses que les gars ont expliquées dans d'autres réponses uniquement par des variables, mais pour les graphiques de calcul dans tensorflow, pour alimenter vos données en graphique, vous devez définir ces hochements de tête comme espaces réservés.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.