code: def biLSTM(f_lstm, b_lstm, inputs, batch_size=None, dropout_x=0., dropout_h=0.):
      
      for f, b in zip(f_lstm, b_lstm):
          inputs = nd.Dropout(inputs, dropout_x, axes=[0])  # important for variational dropout
          fo, fs = f.unroll(length=inputs.shape[0], inputs=inputs, layout='TNC', merge_outputs=True)
          bo, bs = b.unroll(length=inputs.shape[0], inputs=inputs.flip(axis=0), layout='TNC', merge_outputs=True)
          f.reset(), b.reset()
          inputs = nd.concat(fo, bo.flip(axis=0), dim=2)
      return inputs
docs: Feature extraction through BiLSTM
  
      Parameters
      ----------
      f_lstm : VariationalDropoutCell
          Forward cell
      b_lstm : VariationalDropoutCell
          Backward cell
      inputs : NDArray
          seq_len x batch_size
      dropout_x : float
          Variational dropout on inputs
      dropout_h :
          Not used
  
      Returns
      -------
      outputs : NDArray
          Outputs of BiLSTM layers, seq_len x 2 hidden_dims x batch_size