Tensorflow map_fn内存不足问题

时间:2019-07-25 02:25:39

标签: python-3.x tensorflow

我的代码在大型数据集上的内存不足时遇到问题。我试图对数据进行分块以将其输入到计算图中,但最终出现内存不足错误。将其设置为使用feed_dict功能可以解决此问题吗?

由于tf_itertools_product_2D_nest函数的结果,我的代码以如下方式设置,并带有嵌套的map_fn函数。

tf_itertools_product_2D_nest函数来自Cartesian Product in Tensorflow

我还尝试了一种变体方法,在该方法中,我创建了一个张量列表列表,该列表的速度比单纯在张量流中完成的速度要慢得多,因此我宁愿避免使用该方法。

import tensorflow as tf
import numpy as np

config = tf.ConfigProto(allow_soft_placement=True)
config.gpu_options.allow_growth = True
config.gpu_options.per_process_gpu_memory_fraction = 0.9

run_options = tf.RunOptions(trace_level=tf.RunOptions.FULL_TRACE)
run_metadata = tf.RunMetadata()



sess = tf.Session()
sess.run(tf.global_variables_initializer())
tensorboard_log_dir = "../log/"

def tf_itertools_product_2D_nest(a,b): #does not work on nested tensors
    a, b = a[ None, :, None ], b[ :, None, None ]
    #print(sess.run(tf.shape(a)))
    #print(sess.run(tf.shape(b)))
    n_feat_dimension_in_common = tf.shape(a)[-1]
    c = tf.concat( [ a + tf.zeros_like( b ), tf.zeros_like( a ) + b ], axis = 2 )
    return c

def do_calc(arr_pair):
    arr_1 = arr_pair[0]
    arr_binary = arr_pair[1]
    return tf.reduce_max(tf.cumsum(arr_1*arr_binary))

def calc_row_wrapper(row):
    return tf.map_fn(do_calc,row)

for i in range(0,10):
    a = tf.constant(np.random.random((7,10))*10,tf.float64)
    b = tf.constant(np.random.randint(2, size=(3,10)),tf.float64)
    a_b_itertools_product = tf_itertools_product_2D_nest(a,b)
    '''Creates array like this:

    [ [[arr_a0,arr_b0], [arr_a1,arr_b0],...],
      [[arr_a0,arr_b1], [arr_a1,arr_b1],...],
      [[arr_a0,arr_b2], [arr_a1,arr_b2],...],
      ...]

    '''


    with tf.summary.FileWriter(tensorboard_log_dir, sess.graph) as writer:
        result_array = sess.run(tf.map_fn(calc_row_wrapper,a_b_itertools_product),
                                options=run_options,run_metadata=run_metadata)
        writer.add_run_metadata(run_metadata,"iteration {}".format(i))

    print(result_array.shape)
    print(result_array)
    print("")
    # result_array should be an array with 3 rows (1 for each binary vector in b) and 7 columns (1 for each row in a)

我可以想象,由于添加了额外的维度,因此不必要地消耗了内存。有没有一种方法可以模仿标准itertools.product()函数的结果,以便输出2个输入可迭代项中每个项目的可能组合的1个长列表?像这样的结果:

itertools.product([[1,2],[3,4]],[[5,6],[7,8]]) 
# [([1, 2], [5, 6]), ([1, 2], [7, 8]), ([3, 4], [5, 6]), ([3, 4], [7, 8])]

这样可以消除两次​​调用map_fn的需要。

如代码所示,在循环中调用map_fn时,是否会在每次迭代中生成图?在此代码的Tensorboardgraph中,每个迭代周期似乎都有一个很大的“ map_”节点。

Tensorboard Default View (not enough reputation yet)

当我基于Tensorboard中的标签选择特定的迭代时,只有与该迭代相对应的地图节点会突出显示,而所有其他节点都将变灰。这是否意味着对于该循环,仅存在该循环的映射节点(如果从上一个循环开始,其他节点不再存在于内存中)?

Tensorboard 1 iteration view

0 个答案:

没有答案