首页 文章

为可变大小和固定大小的输入创建TensorFlow占位符是否有任何缺点?

提问于
浏览
8

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

比如说,我正在进行小批量学习,并使用占位符初始化图形,我假设一个固定的batch_size:

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

或者,我可以初始化占位符变量,以便它接受可变大小的输入:

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

我并不熟悉底层的低级张量流实现,但后者不会在每次迭代时检查维度,分配内存和创建新数组,以解释我的小批量大小在培训期间发生变化的情况吗?那么,根据实施情况,如果我使用固定的批量维度,那么计算上的浪费是不是很大?

1 回答

  • 6

    提供完全定义的形状(可以产生更好的性能)和允许尺寸变化(这使得数据流图更容易重复使用)之间存在明确的张力 . 正如您所怀疑的那样,使用变形tf.placeholder() ops来表示TensorFlow模型中的输入有一些缺点:

    • TensorFlow通常能够在完全了解形状时简化数据流图 . 例如,对tf.shape(x)的调用返回 tf.Tensor ,其中包含张量 x 的真实动态形状 . 如果在图形构造时完全定义了该形状,TensorFlow将使用tf.constant()替换形状计算,这将用于常量折叠优化,以减少运行时完成的工作量 .

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

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

相关问题