本文介绍了Keras, tensorflow: Initializer for variable... 来自控制流构造、循环或条件的内部的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am training a mask r-cnn model refer to this rep on github:https://github.com/matterport/Mask_RCNN

我遇到了一个似乎是使用 Keras 的问题,所以我来了.

I meet a problem which seems to be an issue of using Keras, so I come here.

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

The code calculates masks from region of interest(rois) and feature map:

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

但是,有时 rois 可能全为零,在这种情况下,我想直接返回全零.所以,我像这样使用 tf.cond:

However, sometimes rois maybe all zeros, in which case I want to return all zeros directly. So, I use tf.cond like this:

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 的问题.欢迎任何线索!

I google it but no useful info got.This seems to be an issue of falsely using keras/tensorflow.Any clue will be welcomed!

顺便说一句,如果我使用这段代码,就不会出错(但我不想提前计算 a):

BTW, if I use this code, it will be no error(but I don't want to calculate a in advance):

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)

推荐答案

错误基本上就是消息所说的.条件中不能有变量初始值设定项.对普通编程语言的粗略类比是:

The error is basically what the message says. You cannot have a variable initializer inside a conditional. A crude analogy to normal programming languages is:

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

这是一个简单的例子来说明这个问题和错误消息中建议的修复:

Here is a simple example to illustrate this issue and the fix suggested in the error message:

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_ok 替换 body 一切都会好的.原因是当初始化器是一个函数时,tensorflow 可以将它放在控制流上下文之外"以确保它始终运行.

This is using tf.while_loop but it is the same as tf.cond for this purposes. If you run this code as is, you will get the same error. If you replace body with body_ok everything will be fine. The reason is that when the initializer is a function, tensorflow can place it "outside of the control flow context" to make sure it always runs.

为了给未来的读者澄清一个可能的混淆,先计算 a"的方法并不理想,但有一个微妙的原因.首先,请记住您在这里所做的是构建一个计算图(假设您没有使用 eager execution).因此,您实际上并不是在计算 a.您只是定义了可以如何计算.Tensorflow 运行时根据 session.run() 的参数决定需要在运行时计算什么.因此,人们可能期望如果条件为假,则不会执行返回 a 的分支(因为不需要它).不幸的是,这不是 TensorFlow 运行时的工作方式.您可以在第一个答案此处中找到更多详细信息,但简要地说,TensorFlow 运行时将执行 任一 分支的所有依赖项,只有 true_fn/false_fn 内部的操作将有条件地执行.

To clarify a possible confusion for future readers, the approach to "compute a first" is not ideal but for a subtle reason. First, remember that what you are doing here is building a computation graph (assuming you are not using eager execution). So, you are not actually computing a. You are just defining how it can be computed. Tensorflow runtime decides what needs to be computed at runtime, depending on the arguments to session.run(). So, one might expect that the if the condition is false, the branch returning a will not be executed (since it is not needed). Unfortunately, this is not how TensorFlow runtime works. You can find more details in the first answer here, but briefly, TensorFlow runtime will execute all dependencies for either branch, only the operations inside the true_fn/false_fn will be executed conditionally.

这篇关于Keras, tensorflow: Initializer for variable... 来自控制流构造、循环或条件的内部的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

11-02 12:28