Je suis nouveau sur TensorFlow. Pendant que je lisais la documentation existante, j’ai trouvé le terme tensor
très déroutant. À cause de cela, je dois clarifier les questions suivantes:
tensor
et Variable
, tensor
tf.constant
, 'tenseur' vs tf.placeholder
?TensorFlow n'a pas d'objets Tensor de première classe, ce qui signifie qu'il n'y a aucune notion de Tensor
dans le graphe sous-jacent exécuté par le moteur d'exécution. Au lieu de cela, le graphe est constitué de nœuds op connectés les uns aux autres, représentant les opérations. Une opération alloue de la mémoire pour ses sorties, qui sont disponibles sur les noeuds finaux :0
, :1
, etc., et vous pouvez considérer chacun de ces noeuds finaux comme une Tensor
. Si vous avez tensor
correspondant à nodename:0
, vous pouvez récupérer sa valeur sous la forme sess.run(tensor)
ou sess.run('nodename:0')
. La granularité d'exécution se produisant au niveau de l'opération, la méthode run
sera exécutée de manière à calculer tous les points de terminaison, pas seulement le point de terminaison :0
. Il est possible d'avoir un nœud Op sans sortie (comme tf.group
), auquel cas il n'y a pas de tenseurs associés. Il n’est pas possible d’avoir des tenseurs sans noeud Op sous-jacent.
Vous pouvez examiner ce qui se passe dans le graphique sous-jacent en faisant quelque chose comme ceci
tf.reset_default_graph()
value = tf.constant(1)
print(tf.get_default_graph().as_graph_def())
Donc, avec tf.constant
, vous obtenez un seul nœud d'opération et vous pouvez le récupérer à l'aide de sess.run("Const:0")
ou sess.run(value)
De même, value=tf.placeholder(tf.int32)
crée un nœud normal nommé Placeholder
, que vous pouvez alimenter en tant que feed_dict={"Placeholder:0":2}
ou feed_dict={value:2}
. Vous ne pouvez pas alimenter et récupérer un espace réservé dans le même appel session.run
, mais vous pouvez voir le résultat en attachant un nœud tf.identity
au-dessus et en le récupérant.
Pour variable
tf.reset_default_graph()
value = tf.Variable(tf.ones_initializer()(()))
value2 = value+3
print(tf.get_default_graph().as_graph_def())
Vous verrez qu'il crée deux nœuds Variable
et Variable/read
, le noeud final :0
est une valeur valide à extraire sur ces deux nœuds. Cependant, Variable:0
a un type ref
spécial, ce qui signifie qu'il peut être utilisé comme entrée pour des opérations de mutation. Le résultat de l'appel Python tf.Variable
est un objet Python Variable
et une magie Python permet de remplacer Variable/read:0
ou Variable:0
selon que la mutation est nécessaire ou non. Étant donné que la plupart des ops n'ont qu'un seul point de terminaison, :0
est supprimé. Un autre exemple est Queue
- la méthode close()
créera un nouveau nœud Close
op qui se connecte à Queue
op. Pour résumer, les opérations sur les objets python tels que Variable
et Queue
correspondent aux différents nœuds op sous-jacents TensorFlow en fonction de l'utilisation.
Pour des opérations comme tf.split
ou tf.nn.top_k
qui créent des nœuds avec plusieurs noeuds finaux, l'appel session.run
de Python encapsule automatiquement la sortie dans des objets Tuple
ou collections.namedtuple
sur Tensor
pouvant être extraits individuellement.
Du glossaire :
Un tenseur est un tableau multi-dimensionnel typé. Par exemple, un tableau 4-D de nombres en virgule flottante représentant un mini-lot d'images de dimensions [lot, hauteur, largeur, canal].
Fondamentalement, chaque data est un tenseur dans TensorFlow (d'où son nom):
feed_dict
dans sess.run()
)var.assign()
). Techniquement parlant, tf.Variable
n'est pas une sous-classe de tf.Tensor
bien quetf.constant
est juste le plus basique Tensor, qui contient une valeur fixe donnée quand vous le créezCependant, dans le graphique, chaque nœud est une opération qui peut avoir des tenseurs comme entrées ou comme sorties.
Comme déjà mentionné par d'autres, oui, ils sont tous des tenseurs.
La façon dont je les ai comprises consiste à visualiser et à comprendre d’abord les tenseurs 1D, 2D, 3D, 4D, 5D et 6D, comme illustré ci-dessous. (source: knoldus)
Maintenant, dans le contexte de TensorFlow, vous pouvez imaginer un graphe de calcul comme celui ci-dessous,
Ici, les Op
s prennent deux tenseurs a
et b
comme input; multiplie les tenseurs avec lui-même puis ajoute le résultat de ces multiplications pour produire le résultat tenseur t3
. Et ces multiplications et additionOp
s se produisent aux nœuds du graphe de calcul.
Et ces tenseurs a
et b
peuvent être des tenseurs constants, des tenseurs variables ou des espaces réservés. Peu importe, dans la mesure où ils ont le même type de données et des formes compatibles (ou broadcast
dans ce dernier) pour réaliser les opérations.