TensorFlow中reshape前后张量打印结果不一致的原因排查
这个问题其实是TensorFlow计算图执行机制的典型坑——你每次调用eval()(或者sess.run())的时候,都会重新执行一遍对应的计算链,包括tf.random_normal这个随机生成操作。
问题根源分析
你的代码里,a_cC = tf.random_normal(...)定义的是一个生成随机数的操作节点,而不是一个固定的值。当你第一次调用a_cC.eval()时,TensorFlow会执行这个节点,生成一组随机数并返回;当你接着调用a_C_unrolled.eval()时,它会再次执行tf.random_normal节点,生成另一组全新的随机数,再做reshape——这自然就和第一次的结果对不上了。
哪怕你设置了tf.set_random_seed(1),这个种子只是保证每次运行图时的随机序列是可复现的,但你两次eval()相当于触发了两次随机生成操作,取的是序列里的不同位置,结果当然不一样。
两种解决方法
方法1:一次性获取两个张量的结果
把两个张量放到同一个sess.run()调用里,这样TensorFlow只会执行一次tf.random_normal,得到的是同一组随机数,再分别返回原张量和展平后的结果:
tf.reset_default_graph() tf.set_random_seed(1) a_cC = tf.random_normal([1, 4, 4, 3], mean=1, stddev=4) m, n_H, n_W, n_C = a_cC.get_shape().as_list() a_C_unrolled = tf.reshape(a_cC,[n_H*n_W,-1]) with tf.Session() as sess: # 一次性运行两个节点,共享同一个随机张量 original_tensor, unrolled_tensor = sess.run([a_cC, a_C_unrolled]) print(original_tensor) print(unrolled_tensor)
方法2:用变量保存随机值
如果需要多次使用这个随机张量,可以把它存入tf.Variable中——变量在初始化时会执行一次随机生成,之后的值就固定了,不管多少次eval()都不会改变:
tf.reset_default_graph() tf.set_random_seed(1) # 将随机张量存入变量,初始化后值固定 a_cC = tf.Variable(tf.random_normal([1, 4, 4, 3], mean=1, stddev=4)) m, n_H, n_W, n_C = a_cC.get_shape().as_list() a_C_unrolled = tf.reshape(a_cC,[n_H*n_W,-1]) with tf.Session() as sess: sess.run(tf.global_variables_initializer()) # 初始化变量,生成随机值 print(a_cC.eval()) print(a_C_unrolled.eval()) # 基于同一个变量值展平,结果匹配
补充说明
另外,你的原代码里用了tf.initialize_all_variables(),这个函数已经被废弃了,建议换成tf.global_variables_initializer()。而且如果只是用操作节点(不是变量),其实不需要调用初始化操作,因为没有需要初始化的变量~
内容的提问来源于stack exchange,提问作者David

