tf.cond降低了训练速度

zhr*_*201 5 machine-learning tensorflow

我正在使用tensorflowcifar10模型一样的输入管道tensorflow并试图tf.cond用来做验证,我写了这样的东西

train_data = model.input(istrain=True)
val_data = model.input(istrain=False)

# This selects which stream to use.
select_val = tf.placeholder(dtype=bool,shape=[],name='select_test')
data = tf.cond(
    select_val,
    lambda:val_data,
    lambda:train_data
)

# Here is the model.
loss = ...
train_op = ...
...

with tf.Session():
    ...
Run Code Online (Sandbox Code Playgroud)

如果我删除cond并只使用训练数据,速度为4000样本/秒,如果我使用上面的代码,速度降低到2300样本/秒.验证管道容量设置得非常小,因此GPU中不会占用太多内存.进行验证的频率也很低.我不确定出了什么问题,请帮助我.

gol*_*enk 5

tf.cond不是完全懒惰.cond即使需要它的分支不是要执行的分支,也将运行任一分支所需的任何操作.所以你的情况,无论是model.input(istrain=True)model.input(istrain=False)正在执行每次你的时间data运被调用.其中一个的结果被忽略了.

文档提供cond了一个最小的代码示例:

请注意,条件执行仅适用于fn1和fn2中定义的操作.考虑以下简单程序:

z = tf.multiply(a, b)
result = tf.cond(x < y, lambda: tf.add(x, z), lambda: tf.square(y))
Run Code Online (Sandbox Code Playgroud)

如果x <y,则执行tf.add操作并且不执行tf.square操作.由于cond的至少一个分支需要z,因此无条件地始终执行tf.mul操作.虽然这种行为与TensorFlow的数据流模型一致,但它偶尔会让一些期望更懒惰语义的用户感到惊讶.

另请注意,这意味着如果您model.input从较大的池中提取一些数据集(例如,来自整个数据集的批处理),则每次cond运行时,都会从验证和培训中获取数据,并且只会抛出一组数据远.在某些情况下,这可能导致比低效率更严重的问题.例如,如果您只处理一定数量的纪元,那么使用此代码您实际上并没有处理这个纪元数,因为数据被拉不使用.