2017-03-02 19 views
6

我想知道在为可变尺寸输入创建TensorFlow占位符(与固定大小的输入)相比,是否存在任何实质性的缺点(例如,关于计算效率,内存...)?创建TensorFlow占位符可变大小还是固定大小输入有什么缺点吗?

说,我做小批量的学习,并与其中I假设固定的batch_size前期的占位符初始化图形:

tf.placeholder(..., shape=[batch_size, ...]) 

可替换地,我可以使得它接受可变大小的输入初始化所述占位符变量:

tf.placeholder(..., shape=[None, ...]) 

我不是那个熟悉的低水平tensorflow引擎盖下的实现,但不会后者必须检查尺寸,分配内存,并在每个迭代创建新的阵列占的情况米y训练期间小批量大小发生变化?那么,根据实现情况,如果我使用固定批处理维度,那么这不会在计算上浪费吗?

回答

5

提供完全定义的形状(可以产生更好的性能)和允许维度变化(这使得数据流图更易于重用)之间存在一定的紧张关系。如你怀疑,也有一些缺点,使用可变形tf.placeholder() OPS来表示一个TensorFlow模型输入:

  • TensorFlow往往能够简化数据流图时的形状是完全已知的。例如,致电tf.shape(x)返回tf.Tensor包含张量的真实动态形状x。如果该形状在图构建时完全定义,则TensorFlow将用tf.constant()代替形状计算,并且这将用于常数折叠优化以减少运行时完成的工作量。

  • 作为一个极端的情况下,XLA compiler要求生成代码之前所有的输入张量形状来完全定义,所以,它可以产生更有效的内核代码,其中数组边界(等)是编译时间常数。 XLA重新编译每个输入形状组合的内核代码,因此使用固定大小的张量将避免重新编译开销。

  • TensorFlow的内存分配器目前确实在每次调用tf.Session.run()每个中间和输出张量分配新的阵列。但是,底层内存分配器(GPU存储器的BFC分配器,CPU内存的或jemalloc)如果它们具有分配请求的静态分配(因为可以从最近释放的缓冲区中满足请求),它们往往表现更好。

+0

感谢您的这个好的和全面的解释!因此,对于大型(长途火车)车型,它可能会更有效地修复批量大小。但是,对于验证和评估(验证和测试集合),必须有一个并行图表,这个图表可以提供训练图的变量,这可能会超过优势。 – Sebastian

+1

这可能是真的。要确定相对性能是非常棘手的,但是我们已经看到使用静态形状信息的运行时间提高了5%,所以如果你有一个长期运行的程序,可能需要使用单独的程序进行训练/尽可能多地评估静态信息。 – mrry