2016-11-29 58 views
0

我想预先使用形状未知的变量,它会不时变化(尽管ndim已知且已修复)。动态形状优化变量

我宣布它像:

initializer = tf.random_uniform_initializer() 
shape = (s0, s1, s2) # these are symbolic vars 
foo_var = tf.Variable(initializer(shape=shape), name="foo", validate_shape=False) 

这似乎当我创建计算图最多,我想优化w.r.t.点工作这个变量,即:

optimizer = tf.train.AdamOptimizer(learning_rate=0.1, epsilon=1e-4) 
optim = optimizer.minimize(loss, var_list=[foo_var]) 

失败在优化中的一些功能create_zeros_slot它似乎取决于静态的形状信息(它使用primary.get_shape().as_list())。 (我上报了here。)

那么,使用优化器只能与静态形状的变量一起工作?

I.e.对于变量形状的每一个变化,我需要重建计算图? 或者有什么方法可以避免娱乐?

回答

0

你在做什么没有任何意义。如果动态变量的形状发生变化,你会如何优化动态变量的值?有时候价值会在那里,有时候不会。当你去保存这个图形时,变量应该在哪个形状中? adam优化器还需要将每个参数的信息存储在变量之间的变量之间,这是在不知道大小的情况下无法完成的。

现在,如果您要做的只是使用变量的一部分,那么您可以使用它的一部分并使用它们。只要变量具有片的最大边界的固定形状,这将工作得很好。例如...

initializer = tf.random_uniform_initializer() 
shape = (S0, S1, S2) # these are now constants for the max bounds of si 
foo_var = tf.Variable(initializer(shape=shape), name="foo") 

foo_var_sub = foo_var[:s0, :s1, :s2] 

在这种情况下,优化器只会作用于片段的foo_var部分。

+1

优化期间,它不会改变。在某些情况下,我会将其明确重置为一个新的值,该值可能会有另一种形状。然后我想再次进行优化。我不想每次重新创建计算图。 – Albert

+0

如果优化不影响它,请尝试将该变量设置为在创建时不可训练。 – chasep255

+0

但我想特别优化这个变量。 – Albert

0

我目前的解决方案有点难看,但有效。

def _tf_create_slot_var(primary, val, scope): 
    """Helper function for creating a slot variable.""" 

    from tensorflow.python.ops import variables 
    slot = variables.Variable(val, name=scope, trainable=False, validate_shape=primary.get_shape().is_fully_defined()) 
    # pylint: disable=protected-access 
    if isinstance(primary, variables.Variable) and primary._save_slice_info: 
    # Primary is a partitioned variable, so we need to also indicate that 
    # the slot is a partitioned variable. Slots have the same partitioning 
    # as their primaries. 
    real_slot_name = scope[len(primary.op.name + "/"):-1] 
    slice_info = primary._save_slice_info 
    slot._set_save_slice_info(variables.Variable.SaveSliceInfo(
     slice_info.full_name + "/" + real_slot_name, 
     slice_info.full_shape[:], 
     slice_info.var_offset[:], 
     slice_info.var_shape[:])) 
    # pylint: enable=protected-access 
    return slot 


def _tf_create_zeros_slot(primary, name, dtype=None, colocate_with_primary=True): 
    """Create a slot initialized to 0 with same shape as the primary object. 

    Args: 
    primary: The primary `Variable` or `Tensor`. 
    name: Name to use for the slot variable. 
    dtype: Type of the slot variable. Defaults to the type of `primary`. 
    colocate_with_primary: Boolean. If True the slot is located 
     on the same device as `primary`. 

    Returns: 
    A `Variable` object. 
    """ 
    if dtype is None: 
    dtype = primary.dtype 
    from tensorflow.python.ops import array_ops 
    val = array_ops.zeros(
     primary.get_shape().as_list() if primary.get_shape().is_fully_defined() else tf.shape(primary), 
     dtype=dtype) 
    from tensorflow.python.training import slot_creator 
    return slot_creator.create_slot(primary, val, name, colocate_with_primary=colocate_with_primary) 


def monkey_patch_tf_slot_creator(): 
    """ 
    The TensorFlow optimizers cannot handle variables with unknown shape. 
    We hack this. 
    """ 
    from tensorflow.python.training import slot_creator 
    slot_creator._create_slot_var = _tf_create_slot_var 
    slot_creator.create_zeros_slot = _tf_create_zeros_slot 

然后我需要在某个时候拨打monkey_patch_tf_slot_creator()