2016-11-29 8 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.を最適化したいポイントまでの計算グラフを作成するときに動作するようです静的形状情報に依存すると思われるいくつかの機能create_zeros_slotにオプティマイザに失敗し、この変数、すなわち:

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

は(それがprimary.get_shape().as_list()を使用します)。 (私はこれを上流に報告しましたhere

したがって、オプティマイザを使用すると静的な形状の変数でのみ動作しますか?

I.e.変数の形の変更ごとに、私は計算グラフを再構築する必要がありますか? レクリエーションを避ける方法はありますか?

答えて

0

あなたがしていることは意味をなさない。動的変数の形状が変化している場合、動的変数の値をどのように最適化しますか?時には価値があり、時には価値がないこともあります。変数をどのような形状にするかをグラフに保存するには?また、アダム・オプティマイザは、サイズを知らなくても実行できない実行間で、各パラメータに関する情報を変数に格納する必要があります。

ここでは、変数の一部を一度に使用するだけで、スライスをスライスして使用することができます。これは、変数がスライスの最大範囲の固定された形状を持つ限り、正常に動作します。たとえば...

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()に電話する必要があります。

関連する問題