TensorFlow 1.5转TensorFlow 2代码及Session性能异常问题咨询
把TensorFlow 1.5代码转换为TF2,以及Session相关问题的解答
先一步步拆解你的问题,从代码转换开始,再逐个解答你的核心疑问。
一、TF2版本的等效代码
TF2默认启用Eager Execution,完全不需要依赖Session来执行计算——张量操作会立即运行,这和你弃用Session时的逻辑完全一致。修正后的标准TF2代码如下:
import tensorflow as tf # TF2中用tf.random.normal替代旧版random_normal A = tf.random.normal([10000, 10000]) B = tf.random.normal([10000, 10000]) # 直接执行计算并打印,无需Session print(tf.reduce_sum(tf.matmul(A, B)))
这段代码和你弃用Session的版本功能完全等效,也是TF2的推荐写法。
二、为什么tf.compat.v1.Session会报错?
你遇到的RuntimeError: Attempting to capture an EagerTensor without building a function,本质是图模式和Eager模式的冲突:
- TF2默认是Eager模式,你创建的
A、B都是EagerTensor(即立即求值的张量)。 - 而
tf.compat.v1.Session是TF1图模式的遗留API,它只能处理图模式下的符号张量(未求值的计算节点)。当你试图在Session中运行EagerTensor时,TensorFlow无法将这种即时求值的张量转换为图节点,所以抛出异常。
简单说:TF2的Eager模式和TF1的Session图模式不能混用,强行混用必然报错。
三、弃用Session后功能是否等效?
完全等效。TF2的Eager Execution和TF1的图模式只是计算执行方式不同:
- TF1图模式是“先构建完整计算图,再批量执行”;
- TF2 Eager模式是“逐行立即执行”,但如果需要极致性能,依然可以通过
tf.function将代码转换为优化后的静态计算图。
对于你的矩阵乘法求和场景,两种模式的计算结果完全一致,功能没有任何差异。
四、为什么使用Session会让TF1.16运行速度慢6000倍?
这个问题的核心是错误的混合模式使用导致的额外开销:
- TF1.16的默认行为:TF1.16是TF1向TF2过渡的版本,默认开启了Eager Execution(和TF2一致)。你原代码中创建的
A、B都是EagerTensor,而非图模式的符号张量。 - Session的额外转换开销:当你把EagerTensor传入
Session.run()时,TensorFlow需要临时将这些即时张量转换为图模式的节点,这个转换过程会产生巨大的额外开销——相当于每次run都要重新构建计算图,而且无法利用AVX2等硬件优化(因为优化是针对静态计算图的)。 - 无Session时的优化:当你弃用Session直接执行时,Eager模式会直接调用优化后的算子(比如支持AVX2的矩阵乘法实现),所以速度极快。
而在无AVX2的TF2中,不用Session时Eager模式依然能避免图转换的开销,所以比强行用Session快一倍。
如果要在TF1中用Session获得高性能,应该先禁用Eager,回到纯图模式:
import tensorflow as tf tf.compat.v1.disable_eager_execution() # 禁用Eager,回到纯图模式 A = tf.random.normal([10000, 10000]) B = tf.random.normal([10000, 10000]) with tf.compat.v1.Session() as sess: print(sess.run(tf.reduce_sum(tf.matmul(A,B))))
这段纯图模式的代码在TF1.16中应该能和弃用Session的版本速度接近。
内容的提问来源于stack exchange,提问作者Cerin
相关产品推荐
相关产品推荐

