TensorFlow技术问询:如何执行操作不添加到计算图避免图膨胀?
我明白你遇到的麻烦了——每次调用session.run()来生成可视化用的numpy数组时,都在偷偷给计算图加新节点,最后直接触发了2GB的大小限制。换个新Session又报错张量不在当前图里,确实头疼。咱们一步步来解决:
问题根源
你在print_best_prediction里写的predictions[best_prediction]/tf.reduce_max(labels[best_prediction]),每次调用这个函数时,TensorFlow都会把这个除法和reduce_max操作当成新的Op添加到计算图里。训练循环跑几百几千个epoch后,图自然就膨胀到超限了。
具体解决方案
方案1:在numpy层面做标准化(最简单直接)
既然我们只是为了可视化,完全可以先把张量对应的numpy数组取出来,再用numpy做除法运算——这完全不会涉及计算图的修改。修改你的print_best_prediction函数:
def print_best_prediction(session, predictions, labels, best_prediction): # 一次run取出需要的两个张量,提升效率 pred_np, label_np = session.run([predictions[best_prediction], labels[best_prediction]]) # 用numpy完成标准化,不触碰计算图 result = pred_np / label_np.max() plt.imshow(result, cmap='gray') plt.show()
这样每次调用都不会给计算图新增节点,自然不会出现膨胀问题。
方案2:提前在计算图里定义标准化张量
如果想把标准化操作留在TensorFlow图里(比如后续还有其他图内操作需求),可以在模型定义阶段就把标准化后的张量定义好,而不是在循环里临时创建:
在train函数的模型定义部分(...define model, placeholders, optimizer_step...)添加:
# 根据你的张量形状调整axis参数,确保reduce_max计算的是单张标签图的最大值 normalized_predictions = predictions / tf.reduce_max(labels, axis=[1,2], keepdims=True)
然后在print_best_prediction里直接run这个提前定义好的张量:
def print_best_prediction(session, normalized_predictions, best_prediction): result = session.run(normalized_predictions[best_prediction]) plt.imshow(result, cmap='gray') plt.show()
这样整个训练过程中,标准化操作只在计算图里存在一次,不会重复添加。
关于新Session报错的补充
你尝试用新Session时遇到的Tensor is not an element of this graph错误,是因为新Session默认会创建一个全新的计算图,而你的模型张量是在原来的默认图里定义的。如果非要用新Session,需要指定复用原来的图:
with tf.Session(graph=tf.get_default_graph()) as new_sess: # 这里可以正常运行原来图里的张量
不过其实完全没必要换Session,解决上面的计算图膨胀问题后,用原来的Session就可以正常工作了。
内容的提问来源于stack exchange,提问作者Aristos Athens

