在tensorflow中使用tf.data从文本文件导入数据时,内存耗尽

时间:2018-03-27 13:31:13

标签: python tensorflow machine-learning deep-learning tensorflow-datasets

我想使用tensorflow训练RNN和密集模型,数据文件太大而无法输入到内存,所以我使用tf.data模块从文件生成批量数据。

数据有7个部分:

第1栏:atom_length;

第二栏:relation_length;

第3~1502栏:原子信息

1503~2202栏:关系信息

2203~3602栏:蛋白质信息

3603专栏:protein_length

最后一栏:标签

代码如下:

import tensorflow as tf
import time

NUM_EPOCHS=10
BATCH_SIZE=128

# default column types
default_column_value = [[0] for i in range(2)]
default_column_value.extend([[0.0] for i in range(3600)])
default_column_value.extend([[0] for i in range(2)])

# using tf.data module to generate the dataset and an iterator
filenames=tf.constant(["F:\\train1_2.txt"])
dataset = tf.data.TextLineDataset(filenames)
dataset = dataset.map(lambda line: tf.decode_csv(
                line,         record_defaults=default_column_value)).repeat(NUM_EPOCHS).shuffle(buffer_size=1000).batch(BATCH_SIZE)
iterator = dataset.make_initializable_iterator()
next_element = iterator.get_next()

# stack specific columns, these are the data used for feeding to the placeholders
atom_length=next_element[0]
relation_length=next_element[1]
atom = tf.stack(next_element[2:1502],axis=1)
relation = tf.stack(next_element[1502:2202],axis=1)
protein_sequence = tf.stack(next_element[2202:3602],axis=1)
protein_length= next_element[-2]
labels = next_element[-1]

with tf.Session() as sess:
    tf.global_variables_initializer().run()
    tf.local_variables_initializer().run()
    sess.run(iterator.initializer)
    step=0
    epoch=1
    try:
        epoch_start_time=time.time()
        while(True):
            one_step_time=time.time()
            step=step+1
            if step%(int(489548//BATCH_SIZE+1))==0:
                print("epoch_used_time:"+str(time.time()-epoch_start_time))
                epoch_start_time=time.time()
                epoch+=1
            # generate the batch data used for training
            cur_atom_length_batch,cur_relation_length_batch,cur_protein_length_batch,cur_atom_batch,cur_relation_batch,cur_protein_sequence_batch,cur_labels_batch=sess.run(
                [atom_length,relation_length,protein_length,atom,relation,protein_sequence,labels])

            input_labels=sess.run(tf.one_hot(cur_labels_batch,depth=2,on_value=1,off_value=0))

        print("cur_atom_length_batch:",cur_atom_length_batch)
        print("cur_relation_length_batch:",cur_relation_length_batch)
        print("cur_atom_batch:",cur_atom_batch)
        print("cur_protein_length_batch:",cur_protein_length_batch)
    except tf.errors.OutOfRangeError:
        print("end of epochs.")
        pass
    finally:
        print('epoch time:',time.time()-epoch_start_time)

当我运行代码时,尽管数据是作为批处理生成的,但本地内存使用率却越来越高。

train1_2.txt文件为3.75GB,即使第一次纪元培训尚未完成,32GB本地内存也几乎耗尽! 这可能是什么原因?我的代码有什么问题?

我使用的环境是GTX1080 GPU,i7处理器,32GB内存,Windows 7。

2 个答案:

答案 0 :(得分:2)

您的代码的主要问题是您在每次迭代时都会向计算图添加新操作。见这一行:

input_labels=sess.run(tf.one_hot(cur_labels_batch,depth=2,on_value=1,off_value=0))

在此处调用tf.one_hot将向图表添加新操作。您可以在每个批次中添加此类操作。你想要做的是将这个操作放在训练循环之外,然后在训练循环中评估它的输出而不是创建一个新的输出,如下所示:

one_hot = tf.one_hot(cur_labels_batch,depth=2,on_value=1,off_value=0)
# other necessary code here
while training:
    # ....
    other_ops_result, input_labels = sess.run([other_ops, one_hot])

经验法则:除非您明确要在计算图中添加新操作,否则不要在训练循环内调用任何tf命名空间操作。请记住,一旦添加,它就无法删除,并且可能会减慢代码速度和/或增加内存消耗,除非必要。

答案 1 :(得分:-1)

我听说这是人们在使用tensorflow时遇到的常见错误。 所以我做了我的研究...... 我想知道你的代码中的下面两行是否正常工作。

tf.global_variables_initializer().run()
tf.local_variables_initializer().run()
sess.run(iterator.initializer)
  1. 前两行是否重复?
  2. 以下是不是正确的实施?
  3. session.run(tf.global_variables_initializer())

    1. 此处不完全确定,但请检查此link。你能尝试使用
    2. 吗? feed_dict内的

      sess.run()参数,而不是tf

      内的其他sess.run()操作