Debug:memory leak导致tensorflow运行越来越慢

对于我这样的二把刀程序员,写程序简直就是在写bug。因此,前进的过程就是不断debug的过程。

本来把我新装好的tensorflow-gpu版跑起来,我看了开始几个iteration,速度杠杠的,然后我就开心的出去玩耍了,结果第二天来办公室一看,程序竟然越跑越慢,从最开始的一个iteration只需要半分钟,到第20个iteration的时候已经需要一个多小时了,这显然是有bug。

经过搜索,发现是由于tensorflow的memory leak导致的。原因如下:

因为在运行时的session里,定义了tf的op导致的。这样每一次迭代都会在graph里增加新的节点,导致memory leak,程序越来越慢,最后强行退出。特别是如果session里有循环(比如利用batch训练),循环里有tf的op存在,会导致运行时间增加的非常快。

解决方法:将所有你能找到的op都移到session以外,特别是移出循环以外。

以我的程序为例,问题出在哪里呢?请看下面(不重要的代码就省略了):

with tf.Session() as sess:
    summary_writer = tf.summary.FileWriter(summary_dir, sess.graph)
    iterations = 200
    ...
    for it in range(iterations):
        # 配置运行时需要记录的信息
        run_options = tf.RunOptions(trace_level=tf.RunOptions.FULL_TRACE)
        # 运行时记录运行信息的proto。
        run_metadata = tf.RunMetadata()
        for n in range(batches_count):
            # 这里的关键是要把输入数组转为np.array
            # 运行训练步骤以及所有的日志生成操作,得到这次运行的日志
            ... = sess.run([...],
                            ...,
                            options=run_options, run_metadata=run_metadata)
        ...

问题就出在上面标红的几行代码上了,而且我把这几行代码放在循环里了……

说实话,这几行代码并不是必须的,就是记录节点信息的,于是我就把它注释掉试了一下,结果问题解决了,程序不再随着运行越变越慢。

我在网上也看到了其他的几种方法,如添加以下代码:

tf.reset_default_graph()
    graph = tf.Graph()
    with graph.as_default() as g:

但是一是我自己试了一下,没试明白,二是我觉得这些方法只是绕过了这个问题,并没有解决这个问题。因此建议大家出现这种问题,还是好好看一下自己的程序,特别是循环里,有没有添加op,如果有的话,把op移出循环,再运行程序应该可以获得立竿见影的效果。

ps. 这几行关于记录节点信息的代码其实是从《TensorFlow:实现Google深度学习框架》上抄来的(见于第一版第9.2.2节(P237)或第二版第11.2.2节(P297)),没想到会给我的程序带来这么大的影响。当然并不是说他们的程序写的有问题,他们的程序我也运行过,增长不明显,可能一是由于示例程序本身数据量很小,第二是示例程序中每隔1000轮才记录一次信息,并不像我的程序中无意间如此频繁的触发了这个操作,因此使得这个问题基本可以忽略不计。

最后附上两个关于这个问题的讨论,我觉得看了以后很有帮助。

https://www.zhihu.com/question/58577743

https://stackoverflow.com/questions/47528401/tensorflow-why-my-code-is-running-slower-and-slower?rq=1

你可能感兴趣的:(tensorflow)