Keras,tensorflow:变量...的初始化器来自控制流构造,循环或条件

时间:2018-01-30 06:17:00

标签: tensorflow keras

我正在训练一个面具r-cnn模型参考github上的这个代表: https://github.com/matterport/Mask_RCNN

我遇到一个似乎是使用Keras问题的问题,所以我来到这里。

代码计算感兴趣区域(rois)和特征图的掩码:

mrcnn_mask = build_fpn_mask_graph(rois, mrcnn_feature_maps,
    config.IMAGE_SHAPE,
    config.MASK_POOL_SIZE,
    config.NUM_CLASSES)

然而,有时候rois可能都是零,在这种情况下我想直接返回所有零。所以,我像这样使用tf.cond:

def ff_true():
    mrcnn_mask = build_fpn_mask_graph(rois, mrcnn_feature_maps,
       config.IMAGE_SHAPE,
       config.MASK_POOL_SIZE,
       config.NUM_CLASSES)

def ff_false():
    return tf.zeros_like(target_mask)

mrcnn_mask = KL.Lambda(lambda x: tf.cond(tf.equal(tf.reduce_mean(x), 0), 
    ff_true, ff_true)) (rois)

这会引发错误:

  

ValueError:变量lambda_5 / cond / mrcnn_mask_conv1 / kernel /的初始化器来自控制流构造内部,例如循环或条件。在循环或条件内创建变量时,使用lambda作为初始值。

我谷歌但没有有用的信息。 这似乎是错误地使用keras / tensorflow的问题。 任何线索都会受到欢迎!

顺便说一句,如果我使用这段代码,那就没有错误(但我不想提前计算):

a = build_fpn_mask_graph(rois, mrcnn_feature_maps,
    config.IMAGE_SHAPE,
    config.MASK_POOL_SIZE,
    config.NUM_CLASSES)   
def ff_true():
    return a
def ff_false():
    return tf.zeros_like(target_mask)

mrcnn_mask = KL.Lambda(lambda x: tf.cond(tf.equal(tf.reduce_mean(x), 0), 
    ff_true, ff_true)) (rois)

2 个答案:

答案 0 :(得分:10)

该错误基本上就是该消息所显示的内容。您不能在条件中包含变量初始值设定项。与普通编程语言的粗略类比是:

if my_condition:
    a = 1
print a    # can't do this. a might be uninitialized.

这是一个简单的示例,用于说明此问题和错误消息中建议的修复程序:

import tensorflow as tf

def cond(i, _):
  return i < 10

def body(i, _):
  zero = tf.zeros([], dtype=tf.int32)
  v = tf.Variable(initial_value=zero)
  return (i + 1, v.read_value())

def body_ok(i, _):
  zero = lambda: tf.zeros([], dtype=tf.int32)
  v = tf.Variable(initial_value=zero, dtype=tf.int32)
  return (i + 1, v.read_value())

tf.while_loop(cond, body, [0, 0])

这正在使用tf.while_loop,但为此目的与tf.cond相同。如果按原样运行此代码,则会收到相同的错误。如果将body替换为body_ok,一切都会好的。原因是,当初始化器是一个函数时,tensorflow可以将其放置在“控制流上下文之外”,以确保其始终运行。

为澄清将来的读者可能的困惑,“首先计算a”的方法不是理想的,而是出于一个微妙的原因。首先,请记住,您在这里正在建立一个计算图(假设您没有使用eager execution)。因此,您实际上并不是在计算a。您只是在定义 的计算方式。 Tensorflow运行时根据session.run()的参数来决定在运行时需要计算什么。因此,人们可能希望如果条件为假,则将不执行返回a的分支(因为不需要)。不幸的是,这不是TensorFlow运行时的工作方式。您可以在第一个答案here中找到更多详细信息,但简要地说,TensorFlow运行时将为任一个分支执行所有依赖项,仅执行{{1 }}将有条件地执行。

答案 1 :(得分:1)

在将CNN-LSTM与keras一起使用时,我也遇到了同样的问题。该代码在GPU服务器上运行良好,但是当我尝试在本地计算机上运行该代码时,出现了这个奇怪的错误。

以下技巧对我有用。

解决方案:清除变量并重新启动内核。这项工作对我来说。也许其他人遇到我正在经历的完全相同的问题会有所帮助。