Tensorflow:如何修改张量中的值

16

由于在使用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.]]
npc:
[[ 1. 2.]
[ 3. 4.]]
修改后的tfc:
[[ 1. 2.]
[ 3. 4.]]
修改后的npc:
[[ 1.1 2.2]
[ 3.1 4.2]]

2个回答

10

使用assign和eval(或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]]

1
谢谢!我认为你的想法是假设tfcnpc在开始时具有相同的值,以便您可以先处理npc,然后将其分配给tfc以获得相同的输出。然而实际情况并非如此。在实际情况中,您只拥有tfc这些数据,因此需要在开始时将npc视为不存在。因此关键在于如何处理tfc中的数据。 - user3030046
@user3030046 这取决于操作。如果它们是简单的加/减,使用assign_sub/assign_add。其他情况下,我们有许多其他方法。您想要更新tf.Tensor中的元素吗?如果您给我一个用例,我会看看我能做什么。 - Sung Kim
我的情况是,我正在尝试实现CBOW(此处中的最后一个单元)。它需要对所有附近跳过的向量进行求和以进行预测。具体来说,就像在10x3矩阵上使用逐行求和并输出10x1向量一样。这个卷积操作将在10x100矩阵上重复,并产生一个相同大小的输出矩阵。你有什么想法吗? - user3030046
@user3030046,您能否添加另一个带有一些示例代码的问题?这样更容易理解您的问题并回答它。谢谢! - Sung Kim

0
我曾经为此苦苦挣扎。所给出的答案将向图形中添加“assign”操作(因此,如果您随后保存检查点,则会不必要地增加.meta的大小)。更好的解决方案是使用tf.keras.backend.set_value。可以通过以下方式使用原始tensorflow来模拟:
    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})

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接