一、tf.Graph.finalize()
tf.Graph.finalize()
# 有时候也可以使用下面的方式
# tf.get_default_graph().finalize()
Finalizes this graph, making it read-only.
结束当前的计算图,使之成为只读。
After calling g.finalize()
, no new operations can be added to g
. This method is used to ensure that no operations are added to a graph when it is shared between multiple threads, for example when using a tf.train.QueueRunner
.
在调用 g.finalize()
之后,不能向计算图 g
添加新操作。 此方法用于确保在多个线程之间共享时能像计算图添加任何操作,例如使用 tf.train.QueueRunner
的时候。
二、代码
在合适的位置加上 finalize()
:
import tensorflow as tf
# here is the definition of your graph
a = tf.constant(3)
b = tf.add(a, 10)
# finalize your graph
tf.get_default_graph().finalize()
# do something you need, like iterations to train
print(b)
结果如下:
Tensor("Add:0", shape=(), dtype=int32)
在 finalize()
之后再一次加入新的计算节点:
import tensorflow as tf
# here is the definition of your graph
a = tf.constant(3)
b = tf.add(a, 10)
# finalize your graph
tf.get_default_graph().finalize()
# WRONG!
c = tf.add(b, 30)
# do something you need, like iterations to train
print(c)
结果如下:
RuntimeError: Graph is finalized and cannot be modified.
三、finalize()
和ResourceExhaustedError
ResourceExhaustedError
往往是深度学习模型在训练时经常会遇到的问题,而有时候这个错误往往会很难处理,这里给出几个简单的处理方法(不保证一定会有效果,但可一试):
- 按照表面的含义理解,
ResourceExhaustedError
错误出现的原因最大的可能是因为内存资源或者显存资源耗尽,因此可以尝试将batchsize减小,但是这会延长训练的时间。或者尝试更改模型,减少模型的参数,例如减小全连接层的维度,这会在一定程度上损失模型的精度。或者可能是由于使用了被占用的显卡,这种情况只需调整使用的显卡编号。 - 可以使用命令
nvidia-smi
(Linux)来查看当前占用资源的进程,强制结束无用进程,节约显存资源。
kill -9 进程号
- 很多时候,训练过程中会突然出现
ResourceExhaustedError
错误,一般来讲会有以下两种原因,第一个就是磁盘资源耗尽,因为在训练过程中,我们会经常保存训练好的模型,这回耗费较多的磁盘资源,如果磁盘空间不足,则会报错。 - 第二中原因就是在训练开始阶段,计算图没有被锁定变成只读,在训练过程中会有新的计算节点加入到计算图中(即使没有显式增加,也有可能隐式增加了新的节点,具体原因囿于能力,目前尚不清楚),逐渐占用越来越多的内存显存资源,最后资源耗尽。因此可以在训练循环开始之前调用
finalize()
,使计算图变成只读,避免新增加不必要的计算节点。
以上的原因只是我根据平时我的使用总结的,可能并不完整,也并不准确,如果有朋友发现了其中的错误,还请不吝指出,谢谢!