import pytest
import numpy as np
import copy
from numpy.testing import assert_allclose
from keras.utils import CustomObjectScope
from keras.layers import wrappers, Input, Layer
from keras.layers import RNN
from keras import layers
from keras.models import Sequential, Model, model_from_json
from keras import backend as K
from keras.utils.generic_utils import object_list_uid, to_list


@pytest.mark.skipif(K.backend() == 'mxnet',
                    reason='MXNet backend does not support TimeDistributed and RNN yet')
def test_TimeDistributed():
    # first, test with Dense layer
    model = Sequential()
    model.add(wrappers.TimeDistributed(layers.Dense(2), input_shape=(3, 4)))
    model.add(layers.Activation('relu'))
    model.compile(optimizer='rmsprop', loss='mse')
    model.fit(np.random.random((10, 3, 4)), np.random.random((10, 3, 2)),
              epochs=1,
              batch_size=10)

    # test config
    model.get_config()

    # test when specifying a batch_input_shape
    test_input = np.random.random((1, 3, 4))
    test_output = model.predict(test_input)
    weights = model.layers[0].get_weights()

    reference = Sequential()
    reference.add(wrappers.TimeDistributed(layers.Dense(2),
                                           batch_input_shape=(1, 3, 4)))
    reference.add(layers.Activation('relu'))
    reference.compile(optimizer='rmsprop', loss='mse')
    reference.layers[0].set_weights(weights)

    reference_output = reference.predict(test_input)
    assert_allclose(test_output, reference_output, atol=1e-05)

    # test with Embedding
    model = Sequential()
    model.add(wrappers.TimeDistributed(layers.Embedding(5, 6),
                                       batch_input_shape=(10, 3, 4),
                                       dtype='int32'))
    model.compile(optimizer='rmsprop', loss='mse')
    model.fit(np.random.randint(5, size=(10, 3, 4), dtype='int32'),
              np.random.random((10, 3, 4, 6)), epochs=1, batch_size=10)

    # compare to not using batch_input_shape
    test_input = np.random.randint(5, size=(10, 3, 4), dtype='int32')
    test_output = model.predict(test_input)
    weights = model.layers[0].get_weights()

    reference = Sequential()
    reference.add(wrappers.TimeDistributed(layers.Embedding(5, 6),
                                           input_shape=(3, 4), dtype='int32'))
    reference.compile(optimizer='rmsprop', loss='mse')
    reference.layers[0].set_weights(weights)

    reference_output = reference.predict(test_input)
    assert_allclose(test_output, reference_output, atol=1e-05)

    # test with Conv2D
    model = Sequential()
    model.add(wrappers.TimeDistributed(layers.Conv2D(5, (2, 2),
                                                     padding='same'),
                                       input_shape=(2, 4, 4, 3)))
    model.add(layers.Activation('relu'))
    model.compile(optimizer='rmsprop', loss='mse')
    model.train_on_batch(np.random.random((1, 2, 4, 4, 3)),
                         np.random.random((1, 2, 4, 4, 5)))

    model = model_from_json(model.to_json())
    model.summary()

    # test stacked layers
    model = Sequential()
    model.add(wrappers.TimeDistributed(layers.Dense(2), input_shape=(3, 4)))
    model.add(wrappers.TimeDistributed(layers.Dense(3)))
    model.add(layers.Activation('relu'))
    model.compile(optimizer='rmsprop', loss='mse')

    model.fit(np.random.random((10, 3, 4)), np.random.random((10, 3, 3)),
              epochs=1, batch_size=10)

    # test wrapping Sequential model
    model = Sequential()
    model.add(layers.Dense(3, input_dim=2))
    outer_model = Sequential()
    outer_model.add(wrappers.TimeDistributed(model, input_shape=(3, 2)))
    outer_model.compile(optimizer='rmsprop', loss='mse')
    outer_model.fit(np.random.random((10, 3, 2)), np.random.random((10, 3, 3)),
                    epochs=1, batch_size=10)

    # test with functional API
    x = Input(shape=(3, 2))
    y = wrappers.TimeDistributed(model)(x)
    outer_model = Model(x, y)
    outer_model.compile(optimizer='rmsprop', loss='mse')
    outer_model.fit(np.random.random((10, 3, 2)), np.random.random((10, 3, 3)),
                    epochs=1, batch_size=10)

    # test with BatchNormalization
    model = Sequential()
    model.add(wrappers.TimeDistributed(
        layers.BatchNormalization(center=True, scale=True),
        name='bn', input_shape=(10, 2)))
    model.compile(optimizer='rmsprop', loss='mse')
    # Assert that mean and variance are 0 and 1.
    td = model.layers[0]
    assert np.array_equal(td.get_weights()[2], np.array([0, 0]))
    assert np.array_equal(td.get_weights()[3], np.array([1, 1]))
    # Train
    model.train_on_batch(np.random.normal(loc=2, scale=2, size=(1, 10, 2)),
                         np.broadcast_to(np.array([0, 1]), (1, 10, 2)))
    # Assert that mean and variance changed.
    assert not np.array_equal(td.get_weights()[2], np.array([0, 0]))
    assert not np.array_equal(td.get_weights()[3], np.array([1, 1]))
    # Verify input_map has one mapping from inputs to reshaped inputs.
    uid = object_list_uid(model.inputs)
    assert len(td._input_map.keys()) == 1
    assert uid in td._input_map
    assert K.int_shape(td._input_map[uid]) == (None, 2)


@pytest.mark.skipif(K.backend() == 'mxnet',
                    reason='MXNet backend does not support TimeDistributed and RNN yet')
@pytest.mark.skipif((K.backend() == 'cntk'),
                    reason='Flaky with CNTK backend')
def test_TimeDistributed_learning_phase():
    # test layers that need learning_phase to be set
    np.random.seed(1234)
    x = Input(shape=(3, 2))
    y = wrappers.TimeDistributed(layers.Dropout(.999))(x, training=True)
    model = Model(x, y)
    y = model.predict(np.random.random((10, 3, 2)))
    assert_allclose(np.mean(y), 0., atol=1e-1, rtol=1e-1)


@pytest.mark.skipif(K.backend() == 'mxnet',
                    reason='MXNet backend does not support TimeDistributed and RNN yet')
def test_TimeDistributed_trainable():
    # test layers that need learning_phase to be set
    x = Input(shape=(3, 2))
    layer = wrappers.TimeDistributed(layers.BatchNormalization())
    _ = layer(x)
    assert len(layer.updates) == 2
    assert len(layer.trainable_weights) == 2
    layer.trainable = False
    assert len(layer.updates) == 0
    assert len(layer.trainable_weights) == 0
    layer.trainable = True
    assert len(layer.updates) == 2
    assert len(layer.trainable_weights) == 2


@pytest.mark.skipif((K.backend() == 'cntk' or K.backend() == 'mxnet'),
                    reason='Unknown timestamps for RNN not supported in CNTK and MXNet.')
def test_TimeDistributed_with_masked_embedding_and_unspecified_shape():
    # test with unspecified shape and Embeddings with mask_zero
    model = Sequential()
    model.add(wrappers.TimeDistributed(layers.Embedding(5, 6, mask_zero=True),
                                       input_shape=(None, None)))
    # the shape so far: (N, t_1, t_2, 6)
    model.add(wrappers.TimeDistributed(layers.SimpleRNN(7, return_sequences=True)))
    model.add(wrappers.TimeDistributed(layers.SimpleRNN(8, return_sequences=False)))
    model.add(layers.SimpleRNN(1, return_sequences=False))
    model.compile(optimizer='rmsprop', loss='mse')
    model_input = np.random.randint(low=1, high=5, size=(10, 3, 4), dtype='int32')
    for i in range(4):
        model_input[i, i:, i:] = 0
    model.fit(model_input,
              np.random.random((10, 1)), epochs=1, batch_size=10)
    mask_outputs = [model.layers[0].compute_mask(model.input)]
    for layer in model.layers[1:]:
        mask_outputs.append(layer.compute_mask(layer.input, mask_outputs[-1]))
    func = K.function([model.input], mask_outputs[:-1])
    mask_outputs_val = func([model_input])
    ref_mask_val_0 = model_input > 0         # embedding layer
    ref_mask_val_1 = ref_mask_val_0          # first RNN layer
    ref_mask_val_2 = np.any(ref_mask_val_1, axis=-1)     # second RNN layer
    ref_mask_val = [ref_mask_val_0, ref_mask_val_1, ref_mask_val_2]
    for i in range(3):
        assert np.array_equal(mask_outputs_val[i], ref_mask_val[i])
    assert mask_outputs[-1] is None  # final layer


@pytest.mark.skipif(K.backend() == 'mxnet',
                    reason='MXNet backend does not support TimeDistributed and RNN yet')
def test_TimeDistributed_with_masking_layer():
    # test with Masking layer
    model = Sequential()
    model.add(wrappers.TimeDistributed(layers.Masking(mask_value=0.,),
                                       input_shape=(None, 4)))
    model.add(wrappers.TimeDistributed(layers.Dense(5)))
    model.compile(optimizer='rmsprop', loss='mse')
    model_input = np.random.randint(low=1, high=5, size=(10, 3, 4))
    for i in range(4):
        model_input[i, i:, :] = 0.
    model.compile(optimizer='rmsprop', loss='mse')
    model.fit(model_input,
              np.random.random((10, 3, 5)), epochs=1, batch_size=6)
    mask_outputs = [model.layers[0].compute_mask(model.input)]
    mask_outputs += [model.layers[1].compute_mask(model.layers[1].input,
                                                  mask_outputs[-1])]
    func = K.function([model.input], mask_outputs)
    mask_outputs_val = func([model_input])
    assert np.array_equal(mask_outputs_val[0], np.any(model_input, axis=-1))
    assert np.array_equal(mask_outputs_val[1], np.any(model_input, axis=-1))


def test_regularizers():
    model = Sequential()
    model.add(wrappers.TimeDistributed(
        layers.Dense(2, kernel_regularizer='l1'), input_shape=(3, 4)))
    model.add(layers.Activation('relu'))
    model.compile(optimizer='rmsprop', loss='mse')
    assert len(model.layers[0].layer.losses) == 1
    assert len(model.layers[0].losses) == 1
    assert len(model.layers[0].get_losses_for(None)) == 1
    assert len(model.losses) == 1

    model = Sequential()
    model.add(wrappers.TimeDistributed(
        layers.Dense(2, activity_regularizer='l1'), input_shape=(3, 4)))
    model.add(layers.Activation('relu'))
    model.compile(optimizer='rmsprop', loss='mse')
    assert len(model.losses) == 1


def test_Bidirectional():
    rnn = layers.SimpleRNN
    samples = 2
    dim = 2
    timesteps = 2
    output_dim = 2
    dropout_rate = 0.2
    for mode in ['sum', 'concat']:
        x = np.random.random((samples, timesteps, dim))
        target_dim = 2 * output_dim if mode == 'concat' else output_dim
        y = np.random.random((samples, target_dim))

        # test with Sequential model
        model = Sequential()
        model.add(wrappers.Bidirectional(rnn(output_dim, dropout=dropout_rate,
                                             recurrent_dropout=dropout_rate),
                                         merge_mode=mode,
                                         input_shape=(timesteps, dim)))
        model.compile(loss='mse', optimizer='sgd')
        model.fit(x, y, epochs=1, batch_size=1)

        # test config
        model.get_config()
        model = model_from_json(model.to_json())
        model.summary()

        # test stacked bidirectional layers
        model = Sequential()
        model.add(wrappers.Bidirectional(rnn(output_dim,
                                             return_sequences=True),
                                         merge_mode=mode,
                                         input_shape=(timesteps, dim)))
        model.add(wrappers.Bidirectional(rnn(output_dim), merge_mode=mode))
        model.compile(loss='mse', optimizer='sgd')
        model.fit(x, y, epochs=1, batch_size=1)

        # test with functional API
        inputs = Input((timesteps, dim))
        outputs = wrappers.Bidirectional(rnn(output_dim, dropout=dropout_rate,
                                             recurrent_dropout=dropout_rate),
                                         merge_mode=mode)(inputs)
        model = Model(inputs, outputs)
        model.compile(loss='mse', optimizer='sgd')
        model.fit(x, y, epochs=1, batch_size=1)

        # Bidirectional and stateful
        inputs = Input(batch_shape=(1, timesteps, dim))
        outputs = wrappers.Bidirectional(rnn(output_dim, stateful=True),
                                         merge_mode=mode)(inputs)
        model = Model(inputs, outputs)
        model.compile(loss='mse', optimizer='sgd')
        model.fit(x, y, epochs=1, batch_size=1)


@pytest.mark.skipif((K.backend() == 'cntk'),
                    reason='Unknown timestamps not supported in CNTK.')
def test_Bidirectional_dynamic_timesteps():
    # test with functional API with dynamic length
    rnn = layers.SimpleRNN
    samples = 2
    dim = 2
    timesteps = 2
    output_dim = 2
    dropout_rate = 0.2
    for mode in ['sum', 'concat']:
        x = np.random.random((samples, timesteps, dim))
        target_dim = 2 * output_dim if mode == 'concat' else output_dim
        y = np.random.random((samples, target_dim))

        inputs = Input((None, dim))
        outputs = wrappers.Bidirectional(rnn(output_dim, dropout=dropout_rate,
                                             recurrent_dropout=dropout_rate),
                                         merge_mode=mode)(inputs)
        model = Model(inputs, outputs)
        model.compile(loss='mse', optimizer='sgd')
        model.fit(x, y, epochs=1, batch_size=1)


@pytest.mark.parametrize('merge_mode', ['sum', 'mul', 'ave', 'concat', None])
def test_Bidirectional_merged_value(merge_mode):
    rnn = layers.LSTM
    samples = 2
    dim = 5
    timesteps = 3
    units = 3
    X = [np.random.rand(samples, timesteps, dim)]

    if merge_mode == 'sum':
        merge_func = lambda y, y_rev: y + y_rev
    elif merge_mode == 'mul':
        merge_func = lambda y, y_rev: y * y_rev
    elif merge_mode == 'ave':
        merge_func = lambda y, y_rev: (y + y_rev) / 2
    elif merge_mode == 'concat':
        merge_func = lambda y, y_rev: np.concatenate((y, y_rev), axis=-1)
    else:
        merge_func = lambda y, y_rev: [y, y_rev]

    # basic case
    inputs = Input((timesteps, dim))
    layer = wrappers.Bidirectional(rnn(units, return_sequences=True),
                                   merge_mode=merge_mode)
    f_merged = K.function([inputs], to_list(layer(inputs)))
    f_forward = K.function([inputs], [layer.forward_layer.call(inputs)])
    f_backward = K.function([inputs],
                            [K.reverse(layer.backward_layer.call(inputs), 1)])

    y_merged = f_merged(X)
    y_expected = to_list(merge_func(f_forward(X)[0], f_backward(X)[0]))
    assert len(y_merged) == len(y_expected)
    for x1, x2 in zip(y_merged, y_expected):
        assert_allclose(x1, x2, atol=1e-5)

    # test return_state
    inputs = Input((timesteps, dim))
    layer = wrappers.Bidirectional(rnn(units, return_state=True),
                                   merge_mode=merge_mode)
    f_merged = K.function([inputs], layer(inputs))
    f_forward = K.function([inputs], layer.forward_layer.call(inputs))
    f_backward = K.function([inputs], layer.backward_layer.call(inputs))
    n_states = len(layer.layer.states)

    y_merged = f_merged(X)
    y_forward = f_forward(X)
    y_backward = f_backward(X)
    y_expected = to_list(merge_func(y_forward[0], y_backward[0]))
    assert len(y_merged) == len(y_expected) + n_states * 2
    for x1, x2 in zip(y_merged, y_expected):
        assert_allclose(x1, x2, atol=1e-5)

    # test if the state of a BiRNN is the concatenation of the underlying RNNs
    y_merged = y_merged[-n_states * 2:]
    y_forward = y_forward[-n_states:]
    y_backward = y_backward[-n_states:]
    for state_birnn, state_inner in zip(y_merged, y_forward + y_backward):
        assert_allclose(state_birnn, state_inner, atol=1e-5)


@pytest.mark.skipif(K.backend() == 'theano' or K.backend() == 'mxnet', reason='Not supported.')
@pytest.mark.parametrize('merge_mode', ['sum', 'concat', None])
def test_Bidirectional_dropout(merge_mode):
    rnn = layers.LSTM
    samples = 2
    dim = 5
    timesteps = 3
    units = 3
    X = [np.random.rand(samples, timesteps, dim)]

    inputs = Input((timesteps, dim))
    wrapped = wrappers.Bidirectional(rnn(units, dropout=0.2, recurrent_dropout=0.2),
                                     merge_mode=merge_mode)
    outputs = to_list(wrapped(inputs, training=True))
    assert all(not getattr(x, '_uses_learning_phase') for x in outputs)

    inputs = Input((timesteps, dim))
    wrapped = wrappers.Bidirectional(rnn(units, dropout=0.2, return_state=True),
                                     merge_mode=merge_mode)
    outputs = to_list(wrapped(inputs))
    assert all(x._uses_learning_phase for x in outputs)

    model = Model(inputs, outputs)
    assert model.uses_learning_phase
    y1 = to_list(model.predict(X))
    y2 = to_list(model.predict(X))
    for x1, x2 in zip(y1, y2):
        assert_allclose(x1, x2, atol=1e-5)


def test_Bidirectional_state_reuse():
    rnn = layers.LSTM
    samples = 2
    dim = 5
    timesteps = 3
    units = 3

    input1 = Input((timesteps, dim))
    layer = wrappers.Bidirectional(rnn(units, return_state=True,
                                       return_sequences=True))
    state = layer(input1)[1:]

    # test passing invalid initial_state: passing a tensor
    input2 = Input((timesteps, dim))
    with pytest.raises(ValueError):
        output = wrappers.Bidirectional(rnn(units))(input2, initial_state=state[0])

    # test valid usage: passing a list
    output = wrappers.Bidirectional(rnn(units))(input2, initial_state=state)
    model = Model([input1, input2], output)
    assert len(model.layers) == 4
    assert isinstance(model.layers[-1].input, list)
    inputs = [np.random.rand(samples, timesteps, dim),
              np.random.rand(samples, timesteps, dim)]
    outputs = model.predict(inputs)


@pytest.mark.skipif(K.backend() == 'mxnet',
                    reason='MXNet backend does not support custom RNN cell yet')
def test_Bidirectional_with_constants():
    class RNNCellWithConstants(Layer):
        def __init__(self, units, **kwargs):
            self.units = units
            self.state_size = units
            super(RNNCellWithConstants, self).__init__(**kwargs)

        def build(self, input_shape):
            if not isinstance(input_shape, list):
                raise TypeError('expects constants shape')
            [input_shape, constant_shape] = input_shape
            # will (and should) raise if more than one constant passed

            self.input_kernel = self.add_weight(
                shape=(input_shape[-1], self.units),
                initializer='uniform',
                name='kernel')
            self.recurrent_kernel = self.add_weight(
                shape=(self.units, self.units),
                initializer='uniform',
                name='recurrent_kernel')
            self.constant_kernel = self.add_weight(
                shape=(constant_shape[-1], self.units),
                initializer='uniform',
                name='constant_kernel')
            self.built = True

        def call(self, inputs, states, constants):
            [prev_output] = states
            [constant] = constants
            h_input = K.dot(inputs, self.input_kernel)
            h_state = K.dot(prev_output, self.recurrent_kernel)
            h_const = K.dot(constant, self.constant_kernel)
            output = h_input + h_state + h_const
            return output, [output]

        def get_config(self):
            config = {'units': self.units}
            base_config = super(RNNCellWithConstants, self).get_config()
            return dict(list(base_config.items()) + list(config.items()))

    # Test basic case.
    x = Input((5, 5))
    c = Input((3,))
    cell = RNNCellWithConstants(32)
    custom_objects = {'RNNCellWithConstants': RNNCellWithConstants}
    with CustomObjectScope(custom_objects):
        layer = wrappers.Bidirectional(RNN(cell))
    y = layer(x, constants=c)
    model = Model([x, c], y)
    model.compile(optimizer='rmsprop', loss='mse')
    model.train_on_batch(
        [np.zeros((6, 5, 5)), np.zeros((6, 3))],
        np.zeros((6, 64))
    )

    # Test basic case serialization.
    x_np = np.random.random((6, 5, 5))
    c_np = np.random.random((6, 3))
    y_np = model.predict([x_np, c_np])
    weights = model.get_weights()
    config = layer.get_config()
    with CustomObjectScope(custom_objects):
        layer = wrappers.Bidirectional.from_config(copy.deepcopy(config))
    y = layer(x, constants=c)
    model = Model([x, c], y)
    model.set_weights(weights)
    y_np_2 = model.predict([x_np, c_np])
    assert_allclose(y_np, y_np_2, atol=1e-4)

    # test flat list inputs
    with CustomObjectScope(custom_objects):
        layer = wrappers.Bidirectional.from_config(copy.deepcopy(config))
    y = layer([x, c])
    model = Model([x, c], y)
    model.set_weights(weights)
    y_np_3 = model.predict([x_np, c_np])
    assert_allclose(y_np, y_np_3, atol=1e-4)


@pytest.mark.skipif(K.backend() == 'mxnet',
                    reason='MXNet backend does not support custom RNN cell yet')
def test_Bidirectional_with_constants_layer_passing_initial_state():
    class RNNCellWithConstants(Layer):
        def __init__(self, units, **kwargs):
            self.units = units
            self.state_size = units
            super(RNNCellWithConstants, self).__init__(**kwargs)

        def build(self, input_shape):
            if not isinstance(input_shape, list):
                raise TypeError('expects constants shape')
            [input_shape, constant_shape] = input_shape
            # will (and should) raise if more than one constant passed

            self.input_kernel = self.add_weight(
                shape=(input_shape[-1], self.units),
                initializer='uniform',
                name='kernel')
            self.recurrent_kernel = self.add_weight(
                shape=(self.units, self.units),
                initializer='uniform',
                name='recurrent_kernel')
            self.constant_kernel = self.add_weight(
                shape=(constant_shape[-1], self.units),
                initializer='uniform',
                name='constant_kernel')
            self.built = True

        def call(self, inputs, states, constants):
            [prev_output] = states
            [constant] = constants
            h_input = K.dot(inputs, self.input_kernel)
            h_state = K.dot(prev_output, self.recurrent_kernel)
            h_const = K.dot(constant, self.constant_kernel)
            output = h_input + h_state + h_const
            return output, [output]

        def get_config(self):
            config = {'units': self.units}
            base_config = super(RNNCellWithConstants, self).get_config()
            return dict(list(base_config.items()) + list(config.items()))

    # Test basic case.
    x = Input((5, 5))
    c = Input((3,))
    s_for = Input((32,))
    s_bac = Input((32,))
    cell = RNNCellWithConstants(32)
    custom_objects = {'RNNCellWithConstants': RNNCellWithConstants}
    with CustomObjectScope(custom_objects):
        layer = wrappers.Bidirectional(RNN(cell))
    y = layer(x, initial_state=[s_for, s_bac], constants=c)
    model = Model([x, s_for, s_bac, c], y)
    model.compile(optimizer='rmsprop', loss='mse')
    model.train_on_batch(
        [np.zeros((6, 5, 5)), np.zeros((6, 32)),
         np.zeros((6, 32)), np.zeros((6, 3))],
        np.zeros((6, 64))
    )

    # Test basic case serialization.
    x_np = np.random.random((6, 5, 5))
    s_fw_np = np.random.random((6, 32))
    s_bk_np = np.random.random((6, 32))
    c_np = np.random.random((6, 3))
    y_np = model.predict([x_np, s_fw_np, s_bk_np, c_np])
    weights = model.get_weights()
    config = layer.get_config()
    with CustomObjectScope(custom_objects):
        layer = wrappers.Bidirectional.from_config(copy.deepcopy(config))
    y = layer(x, initial_state=[s_for, s_bac], constants=c)
    model = Model([x, s_for, s_bac, c], y)
    model.set_weights(weights)
    y_np_2 = model.predict([x_np, s_fw_np, s_bk_np, c_np])
    assert_allclose(y_np, y_np_2, atol=1e-4)

    # verify that state is used
    y_np_2_different_s = model.predict([x_np, s_fw_np + 10., s_bk_np + 10., c_np])
    with pytest.raises(AssertionError):
        assert_allclose(y_np, y_np_2_different_s, atol=1e-4)

    # test flat list inputs
    with CustomObjectScope(custom_objects):
        layer = wrappers.Bidirectional.from_config(copy.deepcopy(config))
    y = layer([x, s_for, s_bac, c])
    model = Model([x, s_for, s_bac, c], y)
    model.set_weights(weights)
    y_np_3 = model.predict([x_np, s_fw_np, s_bk_np, c_np])
    assert_allclose(y_np, y_np_3, atol=1e-4)


def test_Bidirectional_trainable():
    # test layers that need learning_phase to be set
    x = Input(shape=(3, 2))
    layer = wrappers.Bidirectional(layers.SimpleRNN(3))
    _ = layer(x)
    assert len(layer.trainable_weights) == 6
    layer.trainable = False
    assert len(layer.trainable_weights) == 0
    layer.trainable = True
    assert len(layer.trainable_weights) == 6


def test_Bidirectional_updates():
    x = Input(shape=(3, 2))
    layer = wrappers.Bidirectional(layers.SimpleRNN(3))
    assert len(layer.updates) == 0
    assert len(layer.get_updates_for(None)) == 0
    assert len(layer.get_updates_for(x)) == 0
    layer.forward_layer.add_update(0, inputs=x)
    layer.forward_layer.add_update(1, inputs=None)
    layer.backward_layer.add_update(0, inputs=x)
    layer.backward_layer.add_update(1, inputs=None)
    assert len(layer.updates) == 4
    assert len(layer.get_updates_for(None)) == 2
    assert len(layer.get_updates_for(x)) == 2


def test_Bidirectional_losses():
    x = Input(shape=(3, 2))
    layer = wrappers.Bidirectional(
        layers.SimpleRNN(3, kernel_regularizer='l1', bias_regularizer='l1'))
    _ = layer(x)
    assert len(layer.losses) == 4
    assert len(layer.get_losses_for(None)) == 4
    assert len(layer.get_losses_for(x)) == 0
    layer.forward_layer.add_loss(0, inputs=x)
    layer.forward_layer.add_loss(1, inputs=None)
    layer.backward_layer.add_loss(0, inputs=x)
    layer.backward_layer.add_loss(1, inputs=None)
    assert len(layer.losses) == 8
    assert len(layer.get_losses_for(None)) == 6
    assert len(layer.get_losses_for(x)) == 2


if __name__ == '__main__':
    pytest.main([__file__])

[((13283, 13359), 'pytest.mark.parametrize', 'pytest.mark.parametrize', (['"""merge_mode"""', "['sum', 'mul', 'ave', 'concat', None]"], {}), "('merge_mode', ['sum', 'mul', 'ave', 'concat', None])\n", (13306, 13359), False, 'import pytest\n'), ((15765, 15827), 'pytest.mark.parametrize', 'pytest.mark.parametrize', (['"""merge_mode"""', "['sum', 'concat', None]"], {}), "('merge_mode', ['sum', 'concat', None])\n", (15788, 15827), False, 'import pytest\n'), ((595, 607), 'keras.models.Sequential', 'Sequential', ([], {}), '()\n', (605, 607), False, 'from keras.models import Sequential, Model, model_from_json\n'), ((1011, 1038), 'numpy.random.random', 'np.random.random', (['(1, 3, 4)'], {}), '((1, 3, 4))\n', (1027, 1038), True, 'import numpy as np\n'), ((1144, 1156), 'keras.models.Sequential', 'Sequential', ([], {}), '()\n', (1154, 1156), False, 'from keras.models import Sequential, Model, model_from_json\n'), ((1493, 1551), 'numpy.testing.assert_allclose', 'assert_allclose', (['test_output', 'reference_output'], {'atol': '(1e-05)'}), '(test_output, reference_output, atol=1e-05)\n', (1508, 1551), False, 'from numpy.testing import assert_allclose\n'), ((1591, 1603), 'keras.models.Sequential', 'Sequential', ([], {}), '()\n', (1601, 1603), False, 'from keras.models import Sequential, Model, model_from_json\n'), ((2045, 2097), 'numpy.random.randint', 'np.random.randint', (['(5)'], {'size': '(10, 3, 4)', 'dtype': '"""int32"""'}), "(5, size=(10, 3, 4), dtype='int32')\n", (2062, 2097), True, 'import numpy as np\n'), ((2203, 2215), 'keras.models.Sequential', 'Sequential', ([], {}), '()\n', (2213, 2215), False, 'from keras.models import Sequential, Model, model_from_json\n'), ((2520, 2578), 'numpy.testing.assert_allclose', 'assert_allclose', (['test_output', 'reference_output'], {'atol': '(1e-05)'}), '(test_output, reference_output, atol=1e-05)\n', (2535, 2578), False, 'from numpy.testing import assert_allclose\n'), ((2615, 2627), 'keras.models.Sequential', 'Sequential', ([], {}), '()\n', (2625, 2627), False, 'from keras.models import Sequential, Model, model_from_json\n'), ((3145, 3157), 'keras.models.Sequential', 'Sequential', ([], {}), '()\n', (3155, 3157), False, 'from keras.models import Sequential, Model, model_from_json\n'), ((3548, 3560), 'keras.models.Sequential', 'Sequential', ([], {}), '()\n', (3558, 3560), False, 'from keras.models import Sequential, Model, model_from_json\n'), ((3623, 3635), 'keras.models.Sequential', 'Sequential', ([], {}), '()\n', (3633, 3635), False, 'from keras.models import Sequential, Model, model_from_json\n'), ((3931, 3950), 'keras.layers.Input', 'Input', ([], {'shape': '(3, 2)'}), '(shape=(3, 2))\n', (3936, 3950), False, 'from keras.layers import wrappers, Input, Layer\n'), ((4012, 4023), 'keras.models.Model', 'Model', (['x', 'y'], {}), '(x, y)\n', (4017, 4023), False, 'from keras.models import Sequential, Model, model_from_json\n'), ((4254, 4266), 'keras.models.Sequential', 'Sequential', ([], {}), '()\n', (4264, 4266), False, 'from keras.models import Sequential, Model, model_from_json\n'), ((5087, 5116), 'keras.utils.generic_utils.object_list_uid', 'object_list_uid', (['model.inputs'], {}), '(model.inputs)\n', (5102, 5116), False, 'from keras.utils.generic_utils import object_list_uid, to_list\n'), ((5581, 5601), 'numpy.random.seed', 'np.random.seed', (['(1234)'], {}), '(1234)\n', (5595, 5601), True, 'import numpy as np\n'), ((5610, 5629), 'keras.layers.Input', 'Input', ([], {'shape': '(3, 2)'}), '(shape=(3, 2))\n', (5615, 5629), False, 'from keras.layers import wrappers, Input, Layer\n'), ((5715, 5726), 'keras.models.Model', 'Model', (['x', 'y'], {}), '(x, y)\n', (5720, 5726), False, 'from keras.models import Sequential, Model, model_from_json\n'), ((6071, 6090), 'keras.layers.Input', 'Input', ([], {'shape': '(3, 2)'}), '(shape=(3, 2))\n', (6076, 6090), False, 'from keras.layers import wrappers, Input, Layer\n'), ((6780, 6792), 'keras.models.Sequential', 'Sequential', ([], {}), '()\n', (6790, 6792), False, 'from keras.models import Sequential, Model, model_from_json\n'), ((7276, 7340), 'numpy.random.randint', 'np.random.randint', ([], {'low': '(1)', 'high': '(5)', 'size': '(10, 3, 4)', 'dtype': '"""int32"""'}), "(low=1, high=5, size=(10, 3, 4), dtype='int32')\n", (7293, 7340), True, 'import numpy as np\n'), ((7680, 7724), 'keras.backend.function', 'K.function', (['[model.input]', 'mask_outputs[:-1]'], {}), '([model.input], mask_outputs[:-1])\n', (7690, 7724), True, 'from keras import backend as K\n'), ((7915, 7946), 'numpy.any', 'np.any', (['ref_mask_val_1'], {'axis': '(-1)'}), '(ref_mask_val_1, axis=-1)\n', (7921, 7946), True, 'import numpy as np\n'), ((8404, 8416), 'keras.models.Sequential', 'Sequential', ([], {}), '()\n', (8414, 8416), False, 'from keras.models import Sequential, Model, model_from_json\n'), ((8677, 8726), 'numpy.random.randint', 'np.random.randint', ([], {'low': '(1)', 'high': '(5)', 'size': '(10, 3, 4)'}), '(low=1, high=5, size=(10, 3, 4))\n', (8694, 8726), True, 'import numpy as np\n'), ((9147, 9186), 'keras.backend.function', 'K.function', (['[model.input]', 'mask_outputs'], {}), '([model.input], mask_outputs)\n', (9157, 9186), True, 'from keras import backend as K\n'), ((9423, 9435), 'keras.models.Sequential', 'Sequential', ([], {}), '()\n', (9433, 9435), False, 'from keras.models import Sequential, Model, model_from_json\n'), ((9838, 9850), 'keras.models.Sequential', 'Sequential', ([], {}), '()\n', (9848, 9850), False, 'from keras.models import Sequential, Model, model_from_json\n'), ((13977, 14000), 'keras.layers.Input', 'Input', (['(timesteps, dim)'], {}), '((timesteps, dim))\n', (13982, 14000), False, 'from keras.layers import wrappers, Input, Layer\n'), ((14649, 14672), 'keras.layers.Input', 'Input', (['(timesteps, dim)'], {}), '((timesteps, dim))\n', (14654, 14672), False, 'from keras.layers import wrappers, Input, Layer\n'), ((16018, 16041), 'keras.layers.Input', 'Input', (['(timesteps, dim)'], {}), '((timesteps, dim))\n', (16023, 16041), False, 'from keras.layers import wrappers, Input, Layer\n'), ((16327, 16350), 'keras.layers.Input', 'Input', (['(timesteps, dim)'], {}), '((timesteps, dim))\n', (16332, 16350), False, 'from keras.layers import wrappers, Input, Layer\n'), ((16600, 16622), 'keras.models.Model', 'Model', (['inputs', 'outputs'], {}), '(inputs, outputs)\n', (16605, 16622), False, 'from keras.models import Sequential, Model, model_from_json\n'), ((16940, 16963), 'keras.layers.Input', 'Input', (['(timesteps, dim)'], {}), '((timesteps, dim))\n', (16945, 16963), False, 'from keras.layers import wrappers, Input, Layer\n'), ((17195, 17218), 'keras.layers.Input', 'Input', (['(timesteps, dim)'], {}), '((timesteps, dim))\n', (17200, 17218), False, 'from keras.layers import wrappers, Input, Layer\n'), ((17468, 17499), 'keras.models.Model', 'Model', (['[input1, input2]', 'output'], {}), '([input1, input2], output)\n', (17473, 17499), False, 'from keras.models import Sequential, Model, model_from_json\n'), ((19601, 19614), 'keras.layers.Input', 'Input', (['(5, 5)'], {}), '((5, 5))\n', (19606, 19614), False, 'from keras.layers import wrappers, Input, Layer\n'), ((19623, 19634), 'keras.layers.Input', 'Input', (['(3,)'], {}), '((3,))\n', (19628, 19634), False, 'from keras.layers import wrappers, Input, Layer\n'), ((19875, 19891), 'keras.models.Model', 'Model', (['[x, c]', 'y'], {}), '([x, c], y)\n', (19880, 19891), False, 'from keras.models import Sequential, Model, model_from_json\n'), ((20099, 20126), 'numpy.random.random', 'np.random.random', (['(6, 5, 5)'], {}), '((6, 5, 5))\n', (20115, 20126), True, 'import numpy as np\n'), ((20138, 20162), 'numpy.random.random', 'np.random.random', (['(6, 3)'], {}), '((6, 3))\n', (20154, 20162), True, 'import numpy as np\n'), ((20428, 20444), 'keras.models.Model', 'Model', (['[x, c]', 'y'], {}), '([x, c], y)\n', (20433, 20444), False, 'from keras.models import Sequential, Model, model_from_json\n'), ((20521, 20563), 'numpy.testing.assert_allclose', 'assert_allclose', (['y_np', 'y_np_2'], {'atol': '(0.0001)'}), '(y_np, y_np_2, atol=0.0001)\n', (20536, 20563), False, 'from numpy.testing import assert_allclose\n'), ((20743, 20759), 'keras.models.Model', 'Model', (['[x, c]', 'y'], {}), '([x, c], y)\n', (20748, 20759), False, 'from keras.models import Sequential, Model, model_from_json\n'), ((20836, 20878), 'numpy.testing.assert_allclose', 'assert_allclose', (['y_np', 'y_np_3'], {'atol': '(0.0001)'}), '(y_np, y_np_3, atol=0.0001)\n', (20851, 20878), False, 'from numpy.testing import assert_allclose\n'), ((22774, 22787), 'keras.layers.Input', 'Input', (['(5, 5)'], {}), '((5, 5))\n', (22779, 22787), False, 'from keras.layers import wrappers, Input, Layer\n'), ((22796, 22807), 'keras.layers.Input', 'Input', (['(3,)'], {}), '((3,))\n', (22801, 22807), False, 'from keras.layers import wrappers, Input, Layer\n'), ((22820, 22832), 'keras.layers.Input', 'Input', (['(32,)'], {}), '((32,))\n', (22825, 22832), False, 'from keras.layers import wrappers, Input, Layer\n'), ((22845, 22857), 'keras.layers.Input', 'Input', (['(32,)'], {}), '((32,))\n', (22850, 22857), False, 'from keras.layers import wrappers, Input, Layer\n'), ((23128, 23158), 'keras.models.Model', 'Model', (['[x, s_for, s_bac, c]', 'y'], {}), '([x, s_for, s_bac, c], y)\n', (23133, 23158), False, 'from keras.models import Sequential, Model, model_from_json\n'), ((23413, 23440), 'numpy.random.random', 'np.random.random', (['(6, 5, 5)'], {}), '((6, 5, 5))\n', (23429, 23440), True, 'import numpy as np\n'), ((23455, 23480), 'numpy.random.random', 'np.random.random', (['(6, 32)'], {}), '((6, 32))\n', (23471, 23480), True, 'import numpy as np\n'), ((23495, 23520), 'numpy.random.random', 'np.random.random', (['(6, 32)'], {}), '((6, 32))\n', (23511, 23520), True, 'import numpy as np\n'), ((23532, 23556), 'numpy.random.random', 'np.random.random', (['(6, 3)'], {}), '((6, 3))\n', (23548, 23556), True, 'import numpy as np\n'), ((23870, 23900), 'keras.models.Model', 'Model', (['[x, s_for, s_bac, c]', 'y'], {}), '([x, s_for, s_bac, c], y)\n', (23875, 23900), False, 'from keras.models import Sequential, Model, model_from_json\n'), ((23995, 24037), 'numpy.testing.assert_allclose', 'assert_allclose', (['y_np', 'y_np_2'], {'atol': '(0.0001)'}), '(y_np, y_np_2, atol=0.0001)\n', (24010, 24037), False, 'from numpy.testing import assert_allclose\n'), ((24448, 24478), 'keras.models.Model', 'Model', (['[x, s_for, s_bac, c]', 'y'], {}), '([x, s_for, s_bac, c], y)\n', (24453, 24478), False, 'from keras.models import Sequential, Model, model_from_json\n'), ((24573, 24615), 'numpy.testing.assert_allclose', 'assert_allclose', (['y_np', 'y_np_3'], {'atol': '(0.0001)'}), '(y_np, y_np_3, atol=0.0001)\n', (24588, 24615), False, 'from numpy.testing import assert_allclose\n'), ((24713, 24732), 'keras.layers.Input', 'Input', ([], {'shape': '(3, 2)'}), '(shape=(3, 2))\n', (24718, 24732), False, 'from keras.layers import wrappers, Input, Layer\n'), ((25040, 25059), 'keras.layers.Input', 'Input', ([], {'shape': '(3, 2)'}), '(shape=(3, 2))\n', (25045, 25059), False, 'from keras.layers import wrappers, Input, Layer\n'), ((25619, 25638), 'keras.layers.Input', 'Input', ([], {'shape': '(3, 2)'}), '(shape=(3, 2))\n', (25624, 25638), False, 'from keras.layers import wrappers, Input, Layer\n'), ((26248, 26271), 'pytest.main', 'pytest.main', (['[__file__]'], {}), '([__file__])\n', (26259, 26271), False, 'import pytest\n'), ((699, 724), 'keras.layers.Activation', 'layers.Activation', (['"""relu"""'], {}), "('relu')\n", (716, 724), False, 'from keras import layers\n'), ((791, 819), 'numpy.random.random', 'np.random.random', (['(10, 3, 4)'], {}), '((10, 3, 4))\n', (807, 819), True, 'import numpy as np\n'), ((821, 849), 'numpy.random.random', 'np.random.random', (['(10, 3, 2)'], {}), '((10, 3, 2))\n', (837, 849), True, 'import numpy as np\n'), ((1308, 1333), 'keras.layers.Activation', 'layers.Activation', (['"""relu"""'], {}), "('relu')\n", (1325, 1333), False, 'from keras import layers\n'), ((1856, 1908), 'numpy.random.randint', 'np.random.randint', (['(5)'], {'size': '(10, 3, 4)', 'dtype': '"""int32"""'}), "(5, size=(10, 3, 4), dtype='int32')\n", (1873, 1908), True, 'import numpy as np\n'), ((1924, 1955), 'numpy.random.random', 'np.random.random', (['(10, 3, 4, 6)'], {}), '((10, 3, 4, 6))\n', (1940, 1955), True, 'import numpy as np\n'), ((2842, 2867), 'keras.layers.Activation', 'layers.Activation', (['"""relu"""'], {}), "('relu')\n", (2859, 2867), False, 'from keras import layers\n'), ((2945, 2978), 'numpy.random.random', 'np.random.random', (['(1, 2, 4, 4, 3)'], {}), '((1, 2, 4, 4, 3))\n', (2961, 2978), True, 'import numpy as np\n'), ((3005, 3038), 'numpy.random.random', 'np.random.random', (['(1, 2, 4, 4, 5)'], {}), '((1, 2, 4, 4, 5))\n', (3021, 3038), True, 'import numpy as np\n'), ((3306, 3331), 'keras.layers.Activation', 'layers.Activation', (['"""relu"""'], {}), "('relu')\n", (3323, 3331), False, 'from keras import layers\n'), ((3399, 3427), 'numpy.random.random', 'np.random.random', (['(10, 3, 4)'], {}), '((10, 3, 4))\n', (3415, 3427), True, 'import numpy as np\n'), ((3429, 3457), 'numpy.random.random', 'np.random.random', (['(10, 3, 3)'], {}), '((10, 3, 3))\n', (3445, 3457), True, 'import numpy as np\n'), ((3575, 3603), 'keras.layers.Dense', 'layers.Dense', (['(3)'], {'input_dim': '(2)'}), '(3, input_dim=2)\n', (3587, 3603), False, 'from keras import layers\n'), ((3656, 3707), 'keras.layers.wrappers.TimeDistributed', 'wrappers.TimeDistributed', (['model'], {'input_shape': '(3, 2)'}), '(model, input_shape=(3, 2))\n', (3680, 3707), False, 'from keras.layers import wrappers, Input, Layer\n'), ((3786, 3814), 'numpy.random.random', 'np.random.random', (['(10, 3, 2)'], {}), '((10, 3, 2))\n', (3802, 3814), True, 'import numpy as np\n'), ((3816, 3844), 'numpy.random.random', 'np.random.random', (['(10, 3, 3)'], {}), '((10, 3, 3))\n', (3832, 3844), True, 'import numpy as np\n'), ((3959, 3990), 'keras.layers.wrappers.TimeDistributed', 'wrappers.TimeDistributed', (['model'], {}), '(model)\n', (3983, 3990), False, 'from keras.layers import wrappers, Input, Layer\n'), ((4101, 4129), 'numpy.random.random', 'np.random.random', (['(10, 3, 2)'], {}), '((10, 3, 2))\n', (4117, 4129), True, 'import numpy as np\n'), ((4131, 4159), 'numpy.random.random', 'np.random.random', (['(10, 3, 3)'], {}), '((10, 3, 3))\n', (4147, 4159), True, 'import numpy as np\n'), ((4580, 4596), 'numpy.array', 'np.array', (['[0, 0]'], {}), '([0, 0])\n', (4588, 4596), True, 'import numpy as np\n'), ((4645, 4661), 'numpy.array', 'np.array', (['[1, 1]'], {}), '([1, 1])\n', (4653, 4661), True, 'import numpy as np\n'), ((4700, 4749), 'numpy.random.normal', 'np.random.normal', ([], {'loc': '(2)', 'scale': '(2)', 'size': '(1, 10, 2)'}), '(loc=2, scale=2, size=(1, 10, 2))\n', (4716, 4749), True, 'import numpy as np\n'), ((5202, 5233), 'keras.backend.int_shape', 'K.int_shape', (['td._input_map[uid]'], {}), '(td._input_map[uid])\n', (5213, 5233), True, 'from keras import backend as K\n'), ((407, 418), 'keras.backend.backend', 'K.backend', ([], {}), '()\n', (416, 418), True, 'from keras import backend as K\n'), ((5749, 5777), 'numpy.random.random', 'np.random.random', (['(10, 3, 2)'], {}), '((10, 3, 2))\n', (5765, 5777), True, 'import numpy as np\n'), ((5799, 5809), 'numpy.mean', 'np.mean', (['y'], {}), '(y)\n', (5806, 5809), True, 'import numpy as np\n'), ((5269, 5280), 'keras.backend.backend', 'K.backend', ([], {}), '()\n', (5278, 5280), True, 'from keras import backend as K\n'), ((5403, 5414), 'keras.backend.backend', 'K.backend', ([], {}), '()\n', (5412, 5414), True, 'from keras import backend as K\n'), ((6128, 6155), 'keras.layers.BatchNormalization', 'layers.BatchNormalization', ([], {}), '()\n', (6153, 6155), False, 'from keras import layers\n'), ((5859, 5870), 'keras.backend.backend', 'K.backend', ([], {}), '()\n', (5868, 5870), True, 'from keras import backend as K\n'), ((7162, 7205), 'keras.layers.SimpleRNN', 'layers.SimpleRNN', (['(1)'], {'return_sequences': '(False)'}), '(1, return_sequences=False)\n', (7178, 7205), False, 'from keras import layers\n'), ((7440, 7465), 'numpy.random.random', 'np.random.random', (['(10, 1)'], {}), '((10, 1))\n', (7456, 7465), True, 'import numpy as np\n'), ((8076, 8128), 'numpy.array_equal', 'np.array_equal', (['mask_outputs_val[i]', 'ref_mask_val[i]'], {}), '(mask_outputs_val[i], ref_mask_val[i])\n', (8090, 8128), True, 'import numpy as np\n'), ((8877, 8905), 'numpy.random.random', 'np.random.random', (['(10, 3, 5)'], {}), '((10, 3, 5))\n', (8893, 8905), True, 'import numpy as np\n'), ((9277, 9305), 'numpy.any', 'np.any', (['model_input'], {'axis': '(-1)'}), '(model_input, axis=-1)\n', (9283, 9305), True, 'import numpy as np\n'), ((9354, 9382), 'numpy.any', 'np.any', (['model_input'], {'axis': '(-1)'}), '(model_input, axis=-1)\n', (9360, 9382), True, 'import numpy as np\n'), ((8202, 8213), 'keras.backend.backend', 'K.backend', ([], {}), '()\n', (8211, 8213), True, 'from keras import backend as K\n'), ((9561, 9586), 'keras.layers.Activation', 'layers.Activation', (['"""relu"""'], {}), "('relu')\n", (9578, 9586), False, 'from keras import layers\n'), ((9978, 10003), 'keras.layers.Activation', 'layers.Activation', (['"""relu"""'], {}), "('relu')\n", (9995, 10003), False, 'from keras import layers\n'), ((10280, 10323), 'numpy.random.random', 'np.random.random', (['(samples, timesteps, dim)'], {}), '((samples, timesteps, dim))\n', (10296, 10323), True, 'import numpy as np\n'), ((10408, 10447), 'numpy.random.random', 'np.random.random', (['(samples, target_dim)'], {}), '((samples, target_dim))\n', (10424, 10447), True, 'import numpy as np\n'), ((10502, 10514), 'keras.models.Sequential', 'Sequential', ([], {}), '()\n', (10512, 10514), False, 'from keras.models import Sequential, Model, model_from_json\n'), ((11085, 11097), 'keras.models.Sequential', 'Sequential', ([], {}), '()\n', (11095, 11097), False, 'from keras.models import Sequential, Model, model_from_json\n'), ((11582, 11605), 'keras.layers.Input', 'Input', (['(timesteps, dim)'], {}), '((timesteps, dim))\n', (11587, 11605), False, 'from keras.layers import wrappers, Input, Layer\n'), ((11845, 11867), 'keras.models.Model', 'Model', (['inputs', 'outputs'], {}), '(inputs, outputs)\n', (11850, 11867), False, 'from keras.models import Sequential, Model, model_from_json\n'), ((12022, 12060), 'keras.layers.Input', 'Input', ([], {'batch_shape': '(1, timesteps, dim)'}), '(batch_shape=(1, timesteps, dim))\n', (12027, 12060), False, 'from keras.layers import wrappers, Input, Layer\n'), ((12216, 12238), 'keras.models.Model', 'Model', (['inputs', 'outputs'], {}), '(inputs, outputs)\n', (12221, 12238), False, 'from keras.models import Sequential, Model, model_from_json\n'), ((12714, 12757), 'numpy.random.random', 'np.random.random', (['(samples, timesteps, dim)'], {}), '((samples, timesteps, dim))\n', (12730, 12757), True, 'import numpy as np\n'), ((12842, 12881), 'numpy.random.random', 'np.random.random', (['(samples, target_dim)'], {}), '((samples, target_dim))\n', (12858, 12881), True, 'import numpy as np\n'), ((12900, 12918), 'keras.layers.Input', 'Input', (['(None, dim)'], {}), '((None, dim))\n', (12905, 12918), False, 'from keras.layers import wrappers, Input, Layer\n'), ((13158, 13180), 'keras.models.Model', 'Model', (['inputs', 'outputs'], {}), '(inputs, outputs)\n', (13163, 13180), False, 'from keras.models import Sequential, Model, model_from_json\n'), ((12361, 12372), 'keras.backend.backend', 'K.backend', ([], {}), '()\n', (12370, 12372), True, 'from keras import backend as K\n'), ((13500, 13539), 'numpy.random.rand', 'np.random.rand', (['samples', 'timesteps', 'dim'], {}), '(samples, timesteps, dim)\n', (13514, 13539), True, 'import numpy as np\n'), ((14576, 14611), 'numpy.testing.assert_allclose', 'assert_allclose', (['x1', 'x2'], {'atol': '(1e-05)'}), '(x1, x2, atol=1e-05)\n', (14591, 14611), False, 'from numpy.testing import assert_allclose\n'), ((15297, 15332), 'numpy.testing.assert_allclose', 'assert_allclose', (['x1', 'x2'], {'atol': '(1e-05)'}), '(x1, x2, atol=1e-05)\n', (15312, 15332), False, 'from numpy.testing import assert_allclose\n'), ((15613, 15666), 'numpy.testing.assert_allclose', 'assert_allclose', (['state_birnn', 'state_inner'], {'atol': '(1e-05)'}), '(state_birnn, state_inner, atol=1e-05)\n', (15628, 15666), False, 'from numpy.testing import assert_allclose\n'), ((15963, 16002), 'numpy.random.rand', 'np.random.rand', (['samples', 'timesteps', 'dim'], {}), '(samples, timesteps, dim)\n', (15977, 16002), True, 'import numpy as np\n'), ((16769, 16804), 'numpy.testing.assert_allclose', 'assert_allclose', (['x1', 'x2'], {'atol': '(1e-05)'}), '(x1, x2, atol=1e-05)\n', (16784, 16804), False, 'from numpy.testing import assert_allclose\n'), ((17228, 17253), 'pytest.raises', 'pytest.raises', (['ValueError'], {}), '(ValueError)\n', (17241, 17253), False, 'import pytest\n'), ((17600, 17639), 'numpy.random.rand', 'np.random.rand', (['samples', 'timesteps', 'dim'], {}), '(samples, timesteps, dim)\n', (17614, 17639), True, 'import numpy as np\n'), ((17655, 17694), 'numpy.random.rand', 'np.random.rand', (['samples', 'timesteps', 'dim'], {}), '(samples, timesteps, dim)\n', (17669, 17694), True, 'import numpy as np\n'), ((19748, 19781), 'keras.utils.CustomObjectScope', 'CustomObjectScope', (['custom_objects'], {}), '(custom_objects)\n', (19765, 19781), False, 'from keras.utils import CustomObjectScope\n'), ((20026, 20043), 'numpy.zeros', 'np.zeros', (['(6, 64)'], {}), '((6, 64))\n', (20034, 20043), True, 'import numpy as np\n'), ((20277, 20310), 'keras.utils.CustomObjectScope', 'CustomObjectScope', (['custom_objects'], {}), '(custom_objects)\n', (20294, 20310), False, 'from keras.utils import CustomObjectScope\n'), ((20600, 20633), 'keras.utils.CustomObjectScope', 'CustomObjectScope', (['custom_objects'], {}), '(custom_objects)\n', (20617, 20633), False, 'from keras.utils import CustomObjectScope\n'), ((17754, 17765), 'keras.backend.backend', 'K.backend', ([], {}), '()\n', (17763, 17765), True, 'from keras import backend as K\n'), ((22971, 23004), 'keras.utils.CustomObjectScope', 'CustomObjectScope', (['custom_objects'], {}), '(custom_objects)\n', (22988, 23004), False, 'from keras.utils import CustomObjectScope\n'), ((23340, 23357), 'numpy.zeros', 'np.zeros', (['(6, 64)'], {}), '((6, 64))\n', (23348, 23357), True, 'import numpy as np\n'), ((23689, 23722), 'keras.utils.CustomObjectScope', 'CustomObjectScope', (['custom_objects'], {}), '(custom_objects)\n', (23706, 23722), False, 'from keras.utils import CustomObjectScope\n'), ((24161, 24190), 'pytest.raises', 'pytest.raises', (['AssertionError'], {}), '(AssertionError)\n', (24174, 24190), False, 'import pytest\n'), ((24200, 24254), 'numpy.testing.assert_allclose', 'assert_allclose', (['y_np', 'y_np_2_different_s'], {'atol': '(0.0001)'}), '(y_np, y_np_2_different_s, atol=0.0001)\n', (24215, 24254), False, 'from numpy.testing import assert_allclose\n'), ((24291, 24324), 'keras.utils.CustomObjectScope', 'CustomObjectScope', (['custom_objects'], {}), '(custom_objects)\n', (24308, 24324), False, 'from keras.utils import CustomObjectScope\n'), ((20899, 20910), 'keras.backend.backend', 'K.backend', ([], {}), '()\n', (20908, 20910), True, 'from keras import backend as K\n'), ((24768, 24787), 'keras.layers.SimpleRNN', 'layers.SimpleRNN', (['(3)'], {}), '(3)\n', (24784, 24787), False, 'from keras import layers\n'), ((25095, 25114), 'keras.layers.SimpleRNN', 'layers.SimpleRNN', (['(3)'], {}), '(3)\n', (25111, 25114), False, 'from keras import layers\n'), ((25683, 25750), 'keras.layers.SimpleRNN', 'layers.SimpleRNN', (['(3)'], {'kernel_regularizer': '"""l1"""', 'bias_regularizer': '"""l1"""'}), "(3, kernel_regularizer='l1', bias_regularizer='l1')\n", (25699, 25750), False, 'from keras import layers\n'), ((647, 662), 'keras.layers.Dense', 'layers.Dense', (['(2)'], {}), '(2)\n', (659, 662), False, 'from keras import layers\n'), ((1200, 1215), 'keras.layers.Dense', 'layers.Dense', (['(2)'], {}), '(2)\n', (1212, 1215), False, 'from keras import layers\n'), ((1643, 1665), 'keras.layers.Embedding', 'layers.Embedding', (['(5)', '(6)'], {}), '(5, 6)\n', (1659, 1665), False, 'from keras import layers\n'), ((2259, 2281), 'keras.layers.Embedding', 'layers.Embedding', (['(5)', '(6)'], {}), '(5, 6)\n', (2275, 2281), False, 'from keras import layers\n'), ((2667, 2707), 'keras.layers.Conv2D', 'layers.Conv2D', (['(5)', '(2, 2)'], {'padding': '"""same"""'}), "(5, (2, 2), padding='same')\n", (2680, 2707), False, 'from keras import layers\n'), ((3197, 3212), 'keras.layers.Dense', 'layers.Dense', (['(2)'], {}), '(2)\n', (3209, 3212), False, 'from keras import layers\n'), ((3274, 3289), 'keras.layers.Dense', 'layers.Dense', (['(3)'], {}), '(3)\n', (3286, 3289), False, 'from keras import layers\n'), ((4315, 4365), 'keras.layers.BatchNormalization', 'layers.BatchNormalization', ([], {'center': '(True)', 'scale': '(True)'}), '(center=True, scale=True)\n', (4340, 4365), False, 'from keras import layers\n'), ((4792, 4808), 'numpy.array', 'np.array', (['[0, 1]'], {}), '([0, 1])\n', (4800, 4808), True, 'import numpy as np\n'), ((4919, 4935), 'numpy.array', 'np.array', (['[0, 0]'], {}), '([0, 0])\n', (4927, 4935), True, 'import numpy as np\n'), ((4988, 5004), 'numpy.array', 'np.array', (['[1, 1]'], {}), '([1, 1])\n', (4996, 5004), True, 'import numpy as np\n'), ((5663, 5684), 'keras.layers.Dropout', 'layers.Dropout', (['(0.999)'], {}), '(0.999)\n', (5677, 5684), False, 'from keras import layers\n'), ((6832, 6870), 'keras.layers.Embedding', 'layers.Embedding', (['(5)', '(6)'], {'mask_zero': '(True)'}), '(5, 6, mask_zero=True)\n', (6848, 6870), False, 'from keras import layers\n'), ((7018, 7060), 'keras.layers.SimpleRNN', 'layers.SimpleRNN', (['(7)'], {'return_sequences': '(True)'}), '(7, return_sequences=True)\n', (7034, 7060), False, 'from keras import layers\n'), ((7102, 7145), 'keras.layers.SimpleRNN', 'layers.SimpleRNN', (['(8)'], {'return_sequences': '(False)'}), '(8, return_sequences=False)\n', (7118, 7145), False, 'from keras import layers\n'), ((6492, 6503), 'keras.backend.backend', 'K.backend', ([], {}), '()\n', (6501, 6503), True, 'from keras import backend as K\n'), ((6517, 6528), 'keras.backend.backend', 'K.backend', ([], {}), '()\n', (6526, 6528), True, 'from keras import backend as K\n'), ((8456, 8486), 'keras.layers.Masking', 'layers.Masking', ([], {'mask_value': '(0.0)'}), '(mask_value=0.0)\n', (8470, 8486), False, 'from keras import layers\n'), ((8590, 8605), 'keras.layers.Dense', 'layers.Dense', (['(5)'], {}), '(5)\n', (8602, 8605), False, 'from keras import layers\n'), ((9484, 9524), 'keras.layers.Dense', 'layers.Dense', (['(2)'], {'kernel_regularizer': '"""l1"""'}), "(2, kernel_regularizer='l1')\n", (9496, 9524), False, 'from keras import layers\n'), ((9899, 9941), 'keras.layers.Dense', 'layers.Dense', (['(2)'], {'activity_regularizer': '"""l1"""'}), "(2, activity_regularizer='l1')\n", (9911, 9941), False, 'from keras import layers\n'), ((15688, 15699), 'keras.backend.backend', 'K.backend', ([], {}), '()\n', (15697, 15699), True, 'from keras import backend as K\n'), ((15715, 15726), 'keras.backend.backend', 'K.backend', ([], {}), '()\n', (15724, 15726), True, 'from keras import backend as K\n'), ((19106, 19138), 'keras.backend.dot', 'K.dot', (['inputs', 'self.input_kernel'], {}), '(inputs, self.input_kernel)\n', (19111, 19138), True, 'from keras import backend as K\n'), ((19161, 19202), 'keras.backend.dot', 'K.dot', (['prev_output', 'self.recurrent_kernel'], {}), '(prev_output, self.recurrent_kernel)\n', (19166, 19202), True, 'from keras import backend as K\n'), ((19225, 19262), 'keras.backend.dot', 'K.dot', (['constant', 'self.constant_kernel'], {}), '(constant, self.constant_kernel)\n', (19230, 19262), True, 'from keras import backend as K\n'), ((19822, 19831), 'keras.layers.RNN', 'RNN', (['cell'], {}), '(cell)\n', (19825, 19831), False, 'from keras.layers import RNN\n'), ((19978, 19997), 'numpy.zeros', 'np.zeros', (['(6, 5, 5)'], {}), '((6, 5, 5))\n', (19986, 19997), True, 'import numpy as np\n'), ((19999, 20015), 'numpy.zeros', 'np.zeros', (['(6, 3)'], {}), '((6, 3))\n', (20007, 20015), True, 'import numpy as np\n'), ((20363, 20384), 'copy.deepcopy', 'copy.deepcopy', (['config'], {}), '(config)\n', (20376, 20384), False, 'import copy\n'), ((20686, 20707), 'copy.deepcopy', 'copy.deepcopy', (['config'], {}), '(config)\n', (20699, 20707), False, 'import copy\n'), ((22279, 22311), 'keras.backend.dot', 'K.dot', (['inputs', 'self.input_kernel'], {}), '(inputs, self.input_kernel)\n', (22284, 22311), True, 'from keras import backend as K\n'), ((22334, 22375), 'keras.backend.dot', 'K.dot', (['prev_output', 'self.recurrent_kernel'], {}), '(prev_output, self.recurrent_kernel)\n', (22339, 22375), True, 'from keras import backend as K\n'), ((22398, 22435), 'keras.backend.dot', 'K.dot', (['constant', 'self.constant_kernel'], {}), '(constant, self.constant_kernel)\n', (22403, 22435), True, 'from keras import backend as K\n'), ((23045, 23054), 'keras.layers.RNN', 'RNN', (['cell'], {}), '(cell)\n', (23048, 23054), False, 'from keras.layers import RNN\n'), ((23245, 23264), 'numpy.zeros', 'np.zeros', (['(6, 5, 5)'], {}), '((6, 5, 5))\n', (23253, 23264), True, 'import numpy as np\n'), ((23266, 23283), 'numpy.zeros', 'np.zeros', (['(6, 32)'], {}), '((6, 32))\n', (23274, 23283), True, 'import numpy as np\n'), ((23294, 23311), 'numpy.zeros', 'np.zeros', (['(6, 32)'], {}), '((6, 32))\n', (23302, 23311), True, 'import numpy as np\n'), ((23313, 23329), 'numpy.zeros', 'np.zeros', (['(6, 3)'], {}), '((6, 3))\n', (23321, 23329), True, 'import numpy as np\n'), ((23775, 23796), 'copy.deepcopy', 'copy.deepcopy', (['config'], {}), '(config)\n', (23788, 23796), False, 'import copy\n'), ((24377, 24398), 'copy.deepcopy', 'copy.deepcopy', (['config'], {}), '(config)\n', (24390, 24398), False, 'import copy\n'), ((13851, 13886), 'numpy.concatenate', 'np.concatenate', (['(y, y_rev)'], {'axis': '(-1)'}), '((y, y_rev), axis=-1)\n', (13865, 13886), True, 'import numpy as np\n')]