Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/tensorflow/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 我需要K.clear_session()和del模型做什么(使用Tensorflow gpu的Keras)?_Python_Tensorflow_Memory Management_Keras - Fatal编程技术网

Python 我需要K.clear_session()和del模型做什么(使用Tensorflow gpu的Keras)?

Python 我需要K.clear_session()和del模型做什么(使用Tensorflow gpu的Keras)?,python,tensorflow,memory-management,keras,Python,Tensorflow,Memory Management,Keras,我在做什么 我正在训练和使用卷积神经网络(CNN)进行图像分类,使用Keras和Tensorflow gpu作为后端 我正在使用的内容 -PyCharm社区2018.1.2 -Python2.7和3.5(但不能同时使用这两种版本) -Ubuntu 16.04 -Keras 2.2.0 -Tensorflow GPU 1.8.0作为后端 我想知道的 在许多代码中,我看到人们使用 from keras import backend as K # Do some code, e.g. train

我在做什么
我正在训练和使用卷积神经网络(CNN)进行图像分类,使用Keras和Tensorflow gpu作为后端

我正在使用的内容
-PyCharm社区2018.1.2
-Python2.7和3.5(但不能同时使用这两种版本)
-Ubuntu 16.04
-Keras 2.2.0
-Tensorflow GPU 1.8.0作为后端

我想知道的
在许多代码中,我看到人们使用

from keras import backend as K 

# Do some code, e.g. train and save model

K.clear_session()
或在使用模型后删除模型:

del model
keras文档中提到了关于清除会话的内容:“销毁当前TF图并创建新TF图。这有助于避免旧模型/层的混乱。”

这样做有什么意义?我也应该这样做吗?加载或创建新模型时,我的模型会被覆盖,何必麻烦呢?

K.clear_session()
在连续创建多个模型时非常有用,例如在超参数搜索或交叉验证期间。训练的每个模型都会将节点(可能以千为单位)添加到图形中。无论何时(或Keras)调用
tf.Session.run()
tf.Tensor.eval()
,TensorFlow都会执行整个图形,因此您的模型训练速度会越来越慢,并且您可能会耗尽内存。清除会话将删除以前型号的所有剩余节点,从而释放内存并防止减速


编辑19年6月21日:

默认情况下,TensorFlow是惰性的。不会立即计算TensorFlow操作:创建一个tensor或对其执行一些操作会在数据流图中创建节点。当您调用
tf.Session.run()
tf.Tensor.eval()
时,通过一次性计算图形的相关部分来计算结果。这使得TensorFlow可以构建一个执行计划,将可以并行执行的操作分配给不同的设备。它还可以将相邻节点折叠在一起或删除冗余节点(例如,如果将两个张量连接起来,然后将它们再次拆分,而不做任何更改)。有关详细信息,请参阅

所有的TensorFlow模型都作为一系列的张量和张量操作存储在图形中。机器学习的基本操作是张量点积-神经网络的输出是输入矩阵和网络权重的点积。如果您有一个单层感知器和1000个训练样本,那么每个历元至少创建1000个张量操作。如果有1000个纪元,那么在考虑预处理、后处理和更复杂的模型(如循环网络、编码器-解码器、注意模型等)之前,图形的末尾至少包含1000000个节点

问题是最终图形会太大,无法放入视频内存(在我的例子中为6GB),因此TF会将图形的部分从视频传输到主内存,然后再返回。最终,它甚至会变得太大,无法容纳主内存(12GB),并开始在主内存和硬盘之间移动。不用说,随着训练的进行,这让事情变得难以置信,而且越来越慢。在开发这个save model/clear session/reload model流之前,我计算出,按照我所经历的每一个历元的减速率,我的模型完成训练所需的时间将超过宇宙的年龄

免责声明:我已经将近一年没有使用TensorFlow了,所以这可能已经改变了。我记得在这方面有很多GitHub问题,所以希望它已经被修复


del将删除python中的变量,因为model是一个变量,del model将删除它,但TF图不会有任何更改(TF是您的Keras后端)。也就是说,K.clear_session()将破坏当前的TF图并创建一个新的TF图。创建一个新模型似乎是一个独立的步骤,但不要忘记后端:)

在交叉验证期间,我想运行
number\u replicates
folds(也称为a.a.replicates),以获得平均验证损失,作为与另一个算法进行比较的基础。所以我需要对两个不同的算法执行交叉验证,我有多个GPU可用,所以我认为这不会是一个问题

不幸的是,我开始在我的丢失日志中看到图层名被添加到了
\u2
\u3
,等等。我还注意到,如果我在单个脚本中使用循环按顺序运行复制(又称折叠),那么GPU上的内存就会耗尽

这个策略对我有效;我在Ubuntu lambda机器上的
tmux
会话中连续运行了几个小时,有时会看到内存泄漏,但它们会被超时函数杀死。它需要估计完成每个交叉验证折叠/复制所需的时间长度;在下面的代码中,该数字为
timeEstimateRequiredPerReplicate
(最好将通过环路的行程数加倍,以防一半行程被切断):


你有没有发现与你的问题有关的东西?我正试图找到同样的答案。提供的1答案并没有完全理清我的思路。据我所知,模型不会被覆盖。如果你不清除TF图,TF图只会将新模型添加到旧模型TF图中。Del模型只是节省内存,这样cpu/gpu就不必在其中保存额外的内容。如果您在Keras中使用顺序方法,并且您以model=Sequential()开始创建一个新模型,那么我同意您以前的模型应该被覆盖。但是,我在文档中找不到确认信息。事实上,您的问题本身对我帮助很大,非常感谢我在过去6个小时里一直在搜索这个问题。再次感谢您祝您好运。当我运行K.clear_session()时,我需要创建一个新模型。另外,您能否解释一下向图形部分添加节点会导致模型速度变慢和内存不足。这个答案可能不会
from multiprocessing import Process

# establish target for process workers
def machine():
    import tensorflow as tf
    from tensorflow.keras.backend import clear_session

    from tensorflow.python.framework.ops import disable_eager_execution
    import gc

    clear_session()

    disable_eager_execution()  
    nEpochs = 999 # set lower if not using tf.keras.callbacks.EarlyStopping in callbacks
    callbacks = ... # establish early stopping, logging, etc. if desired

    algorithm_model = ... # define layers, output(s), etc.
    opt_algorithm = ... # choose your optimizer
    loss_metric = ... # choose your loss function(s) (in a list for multiple outputs)
    algorithm_model.compile(optimizer=opt_algorithm, loss=loss_metric)

    trainData = ... # establish which data to train on (for this fold/replicate only)
    validateData = ... # establish which data to validate on (same caveat as above)
    algorithm_model.fit(
        x=trainData,
        steps_per_epoch=len(trainData),
        validation_data=validateData,
        validation_steps=len(validateData),
        epochs=nEpochs,
        callbacks=callbacks
    )

    gc.collect()
    del algorithm_model

    return


# establish main loop to start each process
def main_loop():
    for replicate in range(replicatesDesired - replicatesCompleted):
        print(
            '\nStarting cross-validation replicate {} '.format(
                replicate +
                replicatesCompleted + 1
            ) +
            'of {} desired:\n'.format(
                replicatesDesired
            )
        )
        p = Process(target=process_machine)
        p.start()
        flag = p.join(timeEstimateRequiredPerReplicate)
        print('\n\nSubprocess exited with code {}.\n\n'.format(flag))
    return


# enable running of this script from command line
if __name__ == "__main__":
    main_loop()