web-dev-qa-db-fra.com

Tensorflow: comment modifier la valeur du tenseur

Comme j'ai besoin d'écrire quelques pré-processus pour les données avant d'utiliser Tensorflow pour former des modèles, quelques modifications sur tensor sont nécessaires. Cependant, je n'ai aucune idée de la façon de modifier les valeurs dans tensor comme la façon d'utiliser numpy.

La meilleure façon de le faire est de pouvoir modifier directement tensor. Pourtant, cela ne semble pas possible dans la version actuelle de Tensorflow. Une autre méthode consiste à remplacer tensor par ndarray pour le processus, puis utilisez tf.convert_to_tensor Pour revenir en arrière.

La clé est de savoir comment changer tensor en ndarray.
1) tf.contrib.util.make_ndarray(tensor): https://www.tensorflow.org/versions/r0.8/api_docs/python/contrib.util.html#make_ndarray
Cela semble être le moyen le plus simple selon le document, mais je ne trouve pas cette fonction dans la version actuelle du Tensorflow. Deuxièmement, son entrée est TensorProto plutôt que tensor.
2) Utilisez a.eval() pour copier a vers un autre ndarray
Pourtant, cela ne fonctionne qu'à l'aide de tf.InteractiveSession() dans le bloc-notes.

Un cas simple avec des codes montre ci-dessous. Le but de ce code est de faire en sorte que tfc ait la même sortie que npc après le processus.

[~ # ~] indice [~ # ~]
Vous devez considérer que tfc et npc sont indépendants l'un de l'autre. Cela correspond à la situation dans laquelle les données d'entraînement récupérées sont au début au format tensor avec tf.placeholder() .


Code source

import numpy as np
import tensorflow as tf
tf.InteractiveSession()

tfc = tf.constant([[1.,2.],[3.,4.]])
npc = np.array([[1.,2.],[3.,4.]])
row = np.array([[.1,.2]])
print('tfc:\n', tfc.eval())
print('npc:\n', npc)
for i in range(2):
    for j in range(2):
        npc[i,j] += row[0,j]

print('modified tfc:\n', tfc.eval())
print('modified npc:\n', npc)

Sortie:

tfc:
[[1. 2.]
[3. 4.]]
npc:
[[1. 2.]
[3. 4.]]
tfc modifié:
[[1. 2.]
[3. 4.]]
npc modifié:
[[1.1 2.2]
[3.1 4.2]]

11
user3030046

Utilisez assign et eval (ou sess.run) l'assign:

import numpy as np
import tensorflow as tf

npc = np.array([[1.,2.],[3.,4.]])
tfc = tf.Variable(npc) # Use variable 

row = np.array([[.1,.2]])

with tf.Session() as sess:   
    tf.initialize_all_variables().run() # need to initialize all variables

    print('tfc:\n', tfc.eval())
    print('npc:\n', npc)
    for i in range(2):
        for j in range(2):
            npc[i,j] += row[0,j]
    tfc.assign(npc).eval() # assign_sub/assign_add is also available.
    print('modified tfc:\n', tfc.eval())
    print('modified npc:\n', npc)

Il génère:

tfc:
 [[ 1.  2.]
 [ 3.  4.]]
npc:
 [[ 1.  2.]
 [ 3.  4.]]
modified tfc:
 [[ 1.1  2.2]
 [ 3.1  4.2]]
modified npc:
 [[ 1.1  2.2]
 [ 3.1  4.2]]
9
Sung Kim

J'ai lutté avec ça pendant un moment. La réponse donnée ajoutera assign opérations au graphique (et augmentera donc inutilement la taille de .meta si vous enregistrez ultérieurement un point de contrôle). Une meilleure solution consiste à utiliser tf.keras.backend.set_value. On pourrait émuler cela avec un tensorflow brut en faisant:

    for x, value in Zip(tf.global_variables(), values_npfmt):
      if hasattr(x, '_assign_placeholder'):
        assign_placeholder = x._assign_placeholder
        assign_op = x._assign_op
      else:
        assign_placeholder = array_ops.placeholder(tf_dtype, shape=value.shape)
        assign_op = x.assign(assign_placeholder)
        x._assign_placeholder = assign_placeholder
        x._assign_op = assign_op
      get_session().run(assign_op, feed_dict={assign_placeholder: value})
0
user5931