5

Tensorflowの次のコードGRUCellには、以前の隠れ状態がシーケンスの現在の入力とともに提供されるときに、更新された隠れ状態を取得するための一般的な操作が示されています。TensorflowのGRUセルの説明?

def __call__(self, inputs, state, scope=None): 
    """Gated recurrent unit (GRU) with nunits cells.""" 
    with vs.variable_scope(scope or type(self).__name__): # "GRUCell" 
     with vs.variable_scope("Gates"): # Reset gate and update gate. 
     # We start with bias of 1.0 to not reset and not update. 
     r, u = array_ops.split(1, 2, _linear([inputs, state], 
              2 * self._num_units, True, 1.0)) 
     r, u = sigmoid(r), sigmoid(u) 
     with vs.variable_scope("Candidate"): 
     c = self._activation(_linear([inputs, r * state], 
            self._num_units, True)) 
     new_h = u * state + (1 - u) * c 
return new_h, new_h 

しかし、私はここにweightsbiasesが表示されません。例: 私の理解は、ruを得ることは、更新された隠れ状態を得るために、現在の入力および/または隠​​れた状態で重みとバイアスを乗算する必要があるということでした。

次のように私はGRUユニットを書かれている:ここで

def gru_unit(previous_hidden_state, x): 
    r = tf.sigmoid(tf.matmul(x, Wr) + br) 
    z = tf.sigmoid(tf.matmul(x, Wz) + bz) 
    h_ = tf.tanh(tf.matmul(x, Wx) + tf.matmul(previous_hidden_state, Wh) * r) 
    current_hidden_state = tf.mul((1 - z), h_) + tf.mul(previous_hidden_state, z) 
    return current_hidden_state 

私は明示的などの重みWx, Wr, Wz, Whと偏見br, bh, bz、の使用は隠された状態に更新されますすることにします。これらの重みと偏りは、学習後に学習/チューニングされるものです。

上記と同じ結果を得るには、TensorflowのビルトインGRUCellをどうすれば使用できますか?

+0

彼らは一度にすべてを行うには、 'r'と' z'ゲートを連結、計算を節約できます。 –

答えて

3

_linear関数が重みとバイアスを追加するため、それらのコードには表示されません。

r, u = array_ops.split(1, 2, _linear([inputs, state], 
              2 * self._num_units, True, 1.0)) 

...

def _linear(args, output_size, bias, bias_start=0.0, scope=None): 
    """Linear map: sum_i(args[i] * W[i]), where W[i] is a variable. 

    Args: 
    args: a 2D Tensor or a list of 2D, batch x n, Tensors. 
    output_size: int, second dimension of W[i]. 
    bias: boolean, whether to add a bias term or not. 
    bias_start: starting value to initialize the bias; 0 by default. 
    scope: VariableScope for the created subgraph; defaults to "Linear". 

    Returns: 
    A 2D Tensor with shape [batch x output_size] equal to 
    sum_i(args[i] * W[i]), where W[i]s are newly created matrices. 

    Raises: 
    ValueError: if some of the arguments has unspecified or wrong shape. 
    """ 
    if args is None or (nest.is_sequence(args) and not args): 
    raise ValueError("`args` must be specified") 
    if not nest.is_sequence(args): 
    args = [args] 

    # Calculate the total size of arguments on dimension 1. 
    total_arg_size = 0 
    shapes = [a.get_shape().as_list() for a in args] 
    for shape in shapes: 
    if len(shape) != 2: 
     raise ValueError("Linear is expecting 2D arguments: %s" % str(shapes)) 
    if not shape[1]: 
     raise ValueError("Linear expects shape[1] of arguments: %s" % str(shapes)) 
    else: 
     total_arg_size += shape[1] 

    # Now the computation. 
    with vs.variable_scope(scope or "Linear"): 
    matrix = vs.get_variable("Matrix", [total_arg_size, output_size]) 
    if len(args) == 1: 
     res = math_ops.matmul(args[0], matrix) 
    else: 
     res = math_ops.matmul(array_ops.concat(1, args), matrix) 
    if not bias: 
     return res 
    bias_term = vs.get_variable(
     "Bias", [output_size], 
     initializer=init_ops.constant_initializer(bias_start)) 
    return res + bias_term 
+0

したがって、重みと偏りはオンデマンドで作成され、同じ変数スコープで呼び出された場合に同じものを返す 'get_variable'を使って時間ステップ間で共有されているようです。重み行列しかし初期化されます。 –

+0

私はそれが現在の変数スコープのデフォルトの初期化子を使用して初期化されると思います。 – chasep255

+0

これはテンソルフローについても私の他の[質問](http://stackoverflow.com/questions/39302344/tensorflow-rnn-input-size)にも答えると思います。 –