Tensorflow:如何修改张量中的值

Tensorflow: How to modify the value in tensor

由于在使用Tensorflow训练模型之前需要对数据进行一些预处理,因此需要对tensor进行一些修改。但是,我不知道如何像使用numpy 那样修改tensor 中的值。

最好的方法是直接修改tensor。然而,在当前版本的 Tensorflow 中似乎不可能。另一种方法是将进程的 tensor 更改为 ndarray,然后使用 tf.convert_to_tensor 更改回来。

关键是如何把tensor改成ndarray
1) tf.contrib.util.make_ndarray(tensor): https://www.tensorflow.org/versions/r0.8/api_docs/python/contrib.util.html#make_ndarray
根据文档,这似乎是最简单的方法,但我在当前版本的 Tensorflow 中找不到此功能。其次,它的输入是 TensorProto 而不是 tensor.
2) 使用a.eval()复制a到另一个ndarray
然而,它仅适用于在笔记本中使用 tf.InteractiveSession()

一个带有代码的简单案例如下所示。此代码的目的是使 tfc 在处理后具有与 npc 相同的输出。

提示
你应该认为 tfcnpc 是相互独立的。这满足了最初检索到的训练数据是 tensor 格式和 tf.placeholder() 的情况。


源代码

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)

输出:

tfc:
[[ 1. 2.]
[ 3. 4.]]
全国人大:
[[ 1. 2.]
[ 3. 4.]]
修改后的 tfc:
[[ 1. 2.]
[ 3. 4.]]
修改过的npc:
[[ 1.1 2.2]
[ 3.1 4.2]]

使用赋值和求值(或sess.run)赋值:

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)

它输出:

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

我为此苦苦挣扎了一段时间。给出的答案将向图中添加 assign 操作(因此如果您随后保存检查点,则不必要地增加 .meta 的大小)。更好的解决方案是使用 tf.keras.backend.set_value。可以通过以下方式使用原始张量流来模拟:

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