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