TensorFlow问题:堆叠张量数组中所有元素求值结果为何完全相同?
问题分析与解决方案
你的问题核心在于混淆了TensorFlow计算图中的节点引用和实际数值存储,加上每次循环都重新初始化变量,导致最终堆叠的张量所有行都使用了最后一次变量初始化后的结果。
为什么会出现重复值?
让我们拆解一下你的代码逻辑:
- 你在图中定义了固定的
dr1、dr2变量节点——它们是计算图里的固定操作,不是具体的数值。 - 每次循环都调用
sess.run(init),这会把dr1和dr2重新初始化为新的随机值。 - 你把
row = tf.concat([dr1, dr2, rowres], 0)这个张量节点添加到res列表里,但这个节点始终依赖于同一个dr1、dr2变量。 - 当你最后
eval(res_tsr)时,所有这些row节点都会重新计算,而此时dr1、dr2已经被最后一次init设置成了新值,所以所有行都变成了最后一次的结果。
简单说:你存的是"计算规则",不是"计算结果",每次eval都会用最新的变量值重新计算所有规则。
修正方案:存储实际数值而非张量节点
解决思路是每次循环中先获取变量的具体数值,把数值存入列表,最后再将整个数值列表转换成TensorFlow张量。这样每个元素都是独立的数值,不会被后续的变量初始化覆盖。
修正后的代码如下:
import tensorflow as tf g = tf.Graph() res = [] with g.as_default(): with tf.Session() as sess: # 定义变量节点 dr1 = tf.Variable(tf.random_uniform([1], minval=1, maxval=7, dtype=tf.int32, seed=0)) dr2 = tf.Variable(tf.random_uniform([1], minval=1, maxval=7, dtype=tf.int32, seed=1)) rowres = tf.add(dr1, dr2) init = tf.global_variables_initializer() for i in range(5): sess.run(init) # 每次初始化得到新的随机值 # 直接获取当前变量的数值,而不是张量节点 dr1_val, dr2_val, rowres_val = sess.run([dr1, dr2, rowres]) # 拼接数值成1x3的列表,存入结果列表 row_val = [dr1_val[0], dr2_val[0], rowres_val[0]] res.append(row_val) # 最后把数值列表转换成张量 res_tsr = tf.convert_to_tensor(res, dtype=tf.int32) print(res_tsr.eval())
运行这段代码,你会得到符合预期的输出:
[[4 4 8] [4 4 8] [2 3 5] [4 1 5] [3 6 9]]
另一种方案:在计算图中创建独立节点
如果你希望全程在计算图中操作(不提前获取数值),可以每次循环创建新的随机张量(而非复用同一个变量),这样每个row都是独立的节点,不会互相影响:
import tensorflow as tf g = tf.Graph() res = [] with g.as_default(): with tf.Session() as sess: for i in range(5): # 每次循环创建新的随机张量,不使用变量,也就不需要初始化 dr1 = tf.random_uniform([1], minval=1, maxval=7, dtype=tf.int32, seed=i) dr2 = tf.random_uniform([1], minval=1, maxval=7, dtype=tf.int32, seed=i+1) rowres = tf.add(dr1, dr2) row = tf.concat([dr1, dr2, rowres], 0) res.append(row) res_tsr = tf.stack(res) print(res_tsr.eval())
注意这里我们给每个随机张量设置了不同的seed,确保每次循环的随机值不同。
内容的提问来源于stack exchange,提问作者Gensoukyou1337
相关产品推荐
相关产品推荐

