2016-11-29 59 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()