<br />

<button value="stable" default="">See Stable</button> <button value="nightly">See Nightly</button>

<br />

|---|
| [![](https://www.tensorflow.org/images/GitHub-Mark-32px.png) View source on GitHub](https://github.com/keras-team/keras/tree/v3.15.1/keras/src/layers/rnn/bidirectional.py#L13-L549) |

Bidirectional wrapper for RNNs.

Inherits From: [`Layer`](https://www.tensorflow.org/api_docs/python/tf/keras/Layer.md.txt), [`Operation`](https://www.tensorflow.org/api_docs/python/tf/keras/Operation.md.txt)

```python
tf.keras.layers.Bidirectional(
    layer,
    merge_mode='concat',
    weights=None,
    backward_layer=None,
    **kwargs
)
```

### Used in the notebooks

| Used in the tutorials |
|---|
| - [Text classification with an RNN](https://www.tensorflow.org/text/tutorials/text_classification_rnn.md.txt) - [Graph regularization for sentiment classification using synthesized graphs](https://www.tensorflow.org/neural_structured_learning/tutorials/graph_keras_lstm_imdb.md.txt) - [Neural machine translation with attention](https://www.tensorflow.org/text/tutorials/nmt_with_attention.md.txt) |

<br />

<br />

<br />

| ## Args ||
|---|---|
| `layer` | [`keras.layers.RNN`](https://www.tensorflow.org/api_docs/python/tf/keras/layers/RNN.md.txt) instance, such as [`keras.layers.LSTM`](https://www.tensorflow.org/api_docs/python/tf/keras/layers/LSTM.md.txt) or [`keras.layers.GRU`](https://www.tensorflow.org/api_docs/python/tf/keras/layers/GRU.md.txt). It could also be a [`keras.layers.Layer`](https://www.tensorflow.org/api_docs/python/tf/keras/Layer.md.txt) instance that meets the following criteria: <br /> 1. Be a sequence-processing layer (accepts 3D+ inputs). 2. Have a `go_backwards`, `return_sequences` and `return_state` attribute (with the same semantics as for the `RNN` class). 3. Have an `input_spec` attribute. 4. Implement serialization via `get_config()` and `from_config()`. Note that the recommended way to create new RNN layers is to write a custom RNN cell and use it with [`keras.layers.RNN`](https://www.tensorflow.org/api_docs/python/tf/keras/layers/RNN.md.txt), instead of subclassing [`keras.layers.Layer`](https://www.tensorflow.org/api_docs/python/tf/keras/Layer.md.txt) directly. When `return_sequences` is `True`, the output of the masked timestep will be zero regardless of the layer's original `zero_output_for_mask` value. |
| `merge_mode` | Mode by which outputs of the forward and backward RNNs will be combined. One of `{"sum", "mul", "concat", "ave", None}`. If `None`, the outputs will not be combined, they will be returned as a list. Defaults to `"concat"`. |
| `backward_layer` | Optional [`keras.layers.RNN`](https://www.tensorflow.org/api_docs/python/tf/keras/layers/RNN.md.txt), or [`keras.layers.Layer`](https://www.tensorflow.org/api_docs/python/tf/keras/Layer.md.txt) instance to be used to handle backwards input processing. If `backward_layer` is not provided, the layer instance passed as the `layer` argument will be used to generate the backward layer automatically. Note that the provided `backward_layer` layer should have properties matching those of the `layer` argument, in particular it should have the same values for `stateful`, `return_states`, `return_sequences`, etc. In addition, `backward_layer` and `layer` should have different `go_backwards` argument values. A `ValueError` will be raised if these requirements are not met. |

<br />

<br />

<br />

| ## Call arguments ||
|---|---|
| The call arguments for this layer are the same as those of the wrapped RNN layer. Beware that when passing the `initial_state` argument during the call of this layer, the first half in the list of elements in the `initial_state` list will be passed to the forward RNN call and the last half in the list of elements will be passed to the backward RNN call. ||

<br />

> [!NOTE]
> **Note:** instantiating a `Bidirectional` layer from an existing RNN layer instance will not reuse the weights state of the RNN layer instance -- the `Bidirectional` layer will have freshly initialized weights.

#### Examples:

```python
model = Sequential([
    Input(shape=(5, 10)),
    Bidirectional(LSTM(10, return_sequences=True),
    Bidirectional(LSTM(10)),
    Dense(5, activation="softmax"),
])
model.compile(loss='categorical_crossentropy', optimizer='rmsprop')

# With custom backward layer
forward_layer = LSTM(10, return_sequences=True)
backward_layer = LSTM(10, activation='relu', return_sequences=True,
                      go_backwards=True)
model = Sequential([
    Input(shape=(5, 10)),
    Bidirectional(forward_layer, backward_layer=backward_layer),
    Dense(5, activation="softmax"),
])
model.compile(loss='categorical_crossentropy', optimizer='rmsprop')
```

<br />

<br />

<br />

| ## Attributes ||
|---|---|
| `input` | Retrieves the input tensor(s) of a symbolic operation. <br /> Only returns the tensor(s) corresponding to the *first time* the operation was called. |
| `output` | Retrieves the output tensor(s) of a layer. <br /> Only returns the tensor(s) corresponding to the *first time* the operation was called. |
| `states` | <br /> <br /> |

<br />

## Methods

### `from_config`

[View source](https://github.com/keras-team/keras/tree/v3.15.1/keras/src/layers/rnn/bidirectional.py#L532-L549)

```python
@classmethod
from_config(
    config, custom_objects=None
)
```

Creates an operation from its config.

This method is the reverse of `get_config`, capable of instantiating the
same operation from the config dictionary.

> [!NOTE]
> **Note:** If you override this method, you might receive a serialized dtype config, which is a `dict`. You can deserialize it as follows:

```python
if "dtype" in config and isinstance(config["dtype"], dict):
    policy = dtype_policies.deserialize(config["dtype"])
```

<br />

<br />

<br />

| Args ||
|---|---|
| `config` | A Python dictionary, typically the output of `get_config`. |

<br />

<br />

<br />

<br />

| Returns ||
|---|---|
| An operation instance. ||

<br />

### `reset_state`

[View source](https://github.com/keras-team/keras/tree/v3.15.1/keras/src/layers/rnn/bidirectional.py#L485-L489)

```python
reset_state()
```

### `reset_states`

[View source](https://github.com/keras-team/keras/tree/v3.15.1/keras/src/layers/rnn/bidirectional.py#L481-L483)

```python
reset_states()
```