Как вы инициализируете state_size в настраиваемой RNN с учетом вложенного ввода? - PullRequest
0 голосов
/ 04 августа 2020

Итак, я не понимаю, как оболочка tf.keras.layers.RNN должна иметь инициализацию state_size для вложенных входов. Я хочу предсказать следующие N итераций. Ниже я сделал минимальный пример на основе модели Лоренца . Код основан на этих примерах API :

    import collections
    import tensorflow as tf
    
    common_dtype = tf.float32
    
    Variables = collections.namedtuple(
        typename='Variables',
        field_names=[
            'xy',
            'z',
        ],
        defaults=(
            tf.convert_to_tensor([1.509, -1.531], dtype=common_dtype),
            tf.convert_to_tensor(25.46, dtype=common_dtype)
        )
    )
    
    Parameters = collections.namedtuple(
        typename='Parameters',
        field_names=[
            'sigma',
            'rho',
            'beta'
        ],
        defaults=(
            tf.convert_to_tensor([10.0], dtype=common_dtype),
            tf.convert_to_tensor([28.0], dtype=common_dtype),
            tf.convert_to_tensor([8.0/3], dtype=common_dtype)
        )
    )
    
    VariableParameterPair = collections.namedtuple(
        typename='VariableParameterPair',
        field_names=[
            'vars', 
            'params'
        ],
        defaults=(
            Variables(), 
            Parameters()
        )
    )
    
    
    class MinimalRNNCell(tf.keras.layers.Layer):
    
        def __init__(self, units, **kwargs):
            self.dt = tf.constant(0.01, dtype=common_dtype)
            # self.state_size = [units, units, units, units, units, units]
            # self.units = units
            # self.state_size = [tf.TensorShape([2]), tf.TensorShape([1]), tf.TensorShape([1]), tf.TensorShape([1]), tf.TensorShape([1]), tf.TensorShape([1])]
            super(MinimalRNNCell, self).__init__(**kwargs)
    
        def call(self, inputs, states):
            var_params = states[0]
    
            xy = var_params.vars.xy
            z = var_params.vars.z
            sigma = var_params.params.sigma
            rho = var_params.params.rho
            beta = var_params.params.beta
    
            dx = sigma * (xy[1] - xy[0])
            dy = (rho * xy[0]) - xy[1] - (xy[0] * z)
            dz  = (xy[0] * xy[1]) - (beta * z)
    
            # time step scaled update (Forward Euler)
            dt_dx = self.dt * dx
            dt_dy = self.dt * dy
            dt_dz = self.dt * dz
    
            # Updated Vars
            x_new = xy[0] + dt_dx
            y_new = xy[1] + dt_dy
            z_new = z + dt_dz
            xy_new = tf.concat([x_new, y_new], axis=-1)
            updated_vars = tf.nest.pack_sequence_as(var_params.vars, [xy_new, z_new])
    
            # Update State
            Updated_State = VariableParameterPair(vars=updated_vars, params=var_params.params)
            return Updated_State, [Updated_State]
    
    # Initialize Inputs
    xy = tf.keras.Input((None, 2))
    z = tf.keras.Input((None, 1))
    sigma = tf.keras.Input((None, 1))
    rho = tf.keras.Input((None, 1))
    beta = tf.keras.Input((None, 1))
    
    Nested_Input = VariableParameterPair(vars=Variables(xy=xy, z=z), params=Parameters(sigma=sigma, rho=rho, beta=beta))
    
    
    # Let's use this cell in a RNN layer:
    # Is the 32 meant to be the number of iterations?
    cell = MinimalRNNCell(32)
    # y = cell([], [Nested_Input]) #This seems to work
    layer = tf.keras.layers.RNN(cell)
    y = layer(Nested_Input)

Может кто уточнить, как инициализировать размеры состояний? Если проблема не в этом, может кто-нибудь прояснить, что это такое?

NB. Это выполняется с использованием Tensorflow 2.X

...