我想知道在为可变大小的输入(相对于固定大小的输入)创建TensorFlow占位符时是否存在任何实质性缺点(例如,关于计算效率,内存......)?
说,我正在进行小批量学习,并使用占位符初始化图形,我在前面假设一个固定的batch_size:
tf.placeholder(..., shape=[batch_size, ...])
或者,我可以初始化占位符变量,使其接受可变大小的输入:
tf.placeholder(..., shape=[None, ...])
我并不熟悉底层的低级张量流实现,但后者不必检查维度,分配内存,并在每次迭代时创建新数组以解决我的小批量大小的情况培训期间的变化?那么,根据实施情况,如果我使用固定的批量维度,那么在计算上是否会浪费?
答案 0 :(得分:6)
提供完全定义的形状(可以产生更好的性能)和允许尺寸变化(这使得数据流图更容易重复使用)之间存在明确的张力。正如您所怀疑的那样,使用变形tf.placeholder()
操作来表示TensorFlow模型中的输入有一些缺点:
TensorFlow通常能够在完全了解形状时简化数据流图。例如,对tf.shape(x)
的调用会返回包含张量<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<div class="row">
<div class="col-xs-8 col-xs-offset-2 text-left" style="padding: 10px; border: 1px solid gray; margin-top: 10px;">
<div class="col-xs-6">
<h5>
A simple text here. </h5>
</div>
<div class="col-xs-6 text-right">
<button name="spy" class="btn btn-info">Espionner</button>
<button name="attack" class="btn btn-danger">Attaquer</button>
</div>
</div>
</div>
的真实动态形状的tf.Tensor
。如果在图形构造时完全定义了该形状,TensorFlow将用tf.constant()
替换形状计算,这将用于常量折叠优化,以减少在运行时完成的工作量。
作为极端情况,XLA compiler要求在生成代码之前完全定义所有输入张量形状,以便它可以生成更高效的内核代码,其中数组边界(等)是编译的时间常数。 XLA为每个输入形状组合重新编译内核代码,因此使用固定大小的张量将避免重新编译开销。
TensorFlow的内存分配器当前 在每次调用x
时为每个中间和输出张量分配新数组。但是,底层内存分配器(GPU内存的BFC分配器,以及CPU内存的tf.Session.run()
或tcmalloc
)如果具有静态分配的分配请求,则往往表现更好(因为请求可以满足来自最近被释放的缓冲区。)