张量数组与tf.add_n的python和

时间:2018-06-05 17:31:16

标签: python tensorflow

所以我有一些代码

private String createOrderSummary(Editable userEnteredString, int price, boolean isWhippedCreamBoxChecked, boolean isChocalateBoxChecked) {

String priceMessage = "Name:" + userEnteredString + "\nAdd whipped cream?" + isWhippedCreamBoxChecked + "\nAdd chocalate?" + isChocalateBoxChecked + "\nQuantity:" + quantity + "\nTotal:$" + price + "\nThank you!\n";
return priceMessage;

如果我将最后一行更改为

tensors = [] //its filled with 3D float tensors
total = sum(tensors)

然后代码生成相同的输出,但运行速度要慢得多,很快就会导致 内存异常。这里发生了什么?有人可以解释一下sum函数中的pythons和tf.add_n分别与一系列张量相互作用,以及为什么pythons sum看起来只是一个更好的版本?

2 个答案:

答案 0 :(得分:1)

当你使用sum时,你调用一个标准的python算法,在数组的元素上递归调用__add__。由于__add__(或+)确实在tensorflow的张量上超载,因此它按预期工作:它创建一个可在会话期间执行的图形。但是,它并不是最优的,因为您添加了与列表中的元素一样多的操作;另外,您正在执行操作的顺序(添加前两个元素,然后将第三个元素添加到结果中,依此类推),这也不是最佳的。

相比之下,add_n是一种专门的操作。看图表真的说明了我的想法:

import tensorflow as tf

with tf.variable_scope('sum'):
  xs = [tf.zeros(()) for _ in range(10)]
  sum(xs)

with tf.variable_scope('add_n'):
  xs = [tf.zeros(()) for _ in range(10)]
  tf.add_n(xs)

enter image description here

然而 - 与我之前的想法相反 - add_n占用更多内存,因为它在存储之前等待 - 并存储 - 所有输入输入。如果输入数量很大,则差异可能很大。

我期望add_n的行为,即输入的可用总和,实际上是由tf.accumulate_n实现的。这应该是更好的选择,因为它比add_n占用更少的内存,但不强制执行sum之类的求和顺序。

为什么tensorflow-wavenet的作者使用sum代替tf.accumulate_n?当然因为在此之前这个功能不可区分TF< 1.7。所以,如果你必须支持TF< 1.7 具有内存效率,良好的旧sum实际上是一个很好的选择。

答案 1 :(得分:0)

sum() built-in只接受迭代,因此似乎可以获得在内存配置文件方面使用生成器的优势。

张量的add_n() function采用张量列表,并且在整个处理过程中似乎保留了数据结构,这是基于形状比较的要求。

In [29]: y = [1,2,3,4,5,6,7,8,9,10]  

In [30]: y.__sizeof__()
Out[30]: 120

In [31]: x = iter(y)

In [32]: x.__sizeof__()
Out[32]: 32