class_docstr: Long Short Term Memory (LSTM) Layer.
  
  Parameters
  ----------
  {BaseRNNLayer.n_units}
  
  {BaseRNNLayer.only_return_final}
  
  input_weights : Initializer, ndarray
      Weight parameters for input connection.
      Defaults to :class:`HeNormal() <neupy.init.HeNormal>`.
  
  hidden_weights : Initializer, ndarray
      Weight parameters for hidden connection.
      Defaults to :class:`HeNormal() <neupy.init.HeNormal>`.
  
  cell_weights : Initializer, ndarray
      Weight parameters for cell connection. Require only when
      ``peepholes=True`` otherwise it will be ignored.
      Defaults to :class:`HeNormal() <neupy.init.HeNormal>`.
  
  bias : Initializer, ndarray
      Bias parameters for all gates.
      Defaults to :class:`Constant(0) <neupy.init.Constant>`.
  
  ingate : function
      Activation function for the input gate.
      Defaults to ``tf.nn.sigmoid``.
  
  forgetgate : function
      Activation function for the forget gate.
      Defaults to ``tf.nn.sigmoid``.
  
  outgate : function
      Activation function for the output gate.
      Defaults to ``tf.nn.sigmoid``.
  
  cell : function
      Activation function for the cell.
      Defaults to ``tf.tanh``.
  
  learn_init : bool
      If ``True``, make ``cell_init`` and ``hidden_init`` trainable
      variables. Defaults to ``False``.
  
  cell_init : array-like, Tensorfow variable, scalar or Initializer
      Initializer for initial cell state (:math:`c_0`).
      Defaults to :class:`Constant(0) <neupy.init.Constant>`.
  
  hidden_init : array-like, Tensorfow variable, scalar or Initializer
      Initializer for initial hidden state (:math:`h_0`).
      Defaults to :class:`Constant(0) <neupy.init.Constant>`.
  
  backwards : bool
      If ``True``, process the sequence backwards and then reverse the
      output again such that the output from the layer is always
      from :math:`x_1` to :math:`x_n`. Defaults to ``False``
  
  peepholes : bool
      If ``True``, the LSTM uses peephole connections.
      When ``False``, cell parameters  are ignored.
      Defaults to ``False``.
  
  unroll_scan : bool
      If ``True`` the recursion is unrolled instead of using scan.
      For some graphs this gives a significant speed up but it
      might also consume more memory. When ``unroll_scan=True``,
      backpropagation always includes the full sequence, so
      ``n_gradient_steps`` must be set to ``-1`` and the input
      sequence length must be known at compile time (i.e.,
      cannot be given as ``None``). Defaults to ``False``.
  
  gradient_clipping : float or int
      If nonzero, the gradient messages are clipped to the
      given value during the backward pass. Defaults to ``0``.
  
  {BaseLayer.name}
  
  Notes
  -----
  Code was adapted from the
  `Lasagne <https://github.com/Lasagne/Lasagne>`_ library.
  
  Examples
  --------
  Sequence classification
  
  >>> from neupy.layers import *
  >>>
  >>> n_time_steps = 40
  >>> n_categories = 20
  >>> embedded_size = 10
  >>>
  >>> network = join(
  ...     Input(n_time_steps),
  ...     Embedding(n_categories, embedded_size),
  ...     LSTM(20),
  ...     Sigmoid(1),
  ... )
  >>> network
  (?, 40) -> [... 4 layers ...] -> (?, 1)
code: def output(self, input, **kwargs):
      # Because scan iterates over the first dimension we
      # dimshuffle to (n_time_steps, n_samples, n_features)
      input = tf.transpose(input, [1, 0, 2])
  
      def one_lstm_step(states, input_n):
          with tf.name_scope("lstm-cell"):
              cell_previous, hid_previous = states
              input_n = (
                  tf.matmul(input_n, self.input_weights) + self.biases
              )
  
              # Calculate gates pre-activations and slice
              gates = input_n + tf.matmul(
                  hid_previous, self.hidden_weights
              )
  
              # Clip gradients
              if self.gradient_clipping != 0:
                  gates = clip_gradient(gates, self.gradient_clipping)
  
              # Extract the pre-activation gate values
              ingate, forgetgate, cell_input, outgate = tf.split(
                  gates, 4, axis=1
              )
  
              if self.peepholes:
                  # Compute peephole connections
                  ingate += cell_previous * self.weight_cell_to_ingate
                  forgetgate += (
                      cell_previous * self.weight_cell_to_forgetgate
                  )
  
              # Apply nonlinearities
              ingate = self.ingate(ingate)
              forgetgate = self.forgetgate(forgetgate)
              cell_input = self.cell(cell_input)
  
              # Compute new cell value
              cell = forgetgate * cell_previous + ingate * cell_input
  
              if self.peepholes:
                  outgate += cell * self.weight_cell_to_outgate
  
              outgate = self.outgate(outgate)
  
              # Compute new hidden unit activation
              hid = outgate * tf.tanh(cell)
              return [cell, hid]
  
      input_shape = tf.shape(input)
      n_samples = input_shape[1]  # batch dim has been moved
      cell_init = tf.tile(self.cell_init, (n_samples, 1))
      hidden_init = tf.tile(self.hidden_init, (n_samples, 1))
      sequence = input
  
      if self.backwards:
          sequence = tf.reverse(sequence, axis=[0])
  
      if self.unroll_scan:
          # Explicitly unroll the recurrence instead of using scan
          hid_out = unroll_scan(
              fn=one_lstm_step,
              sequence=sequence,
              outputs_info=[cell_init, hidden_init],
          )
      else:
          _, hid_out = tf.scan(
              fn=one_lstm_step,
              elems=sequence,
              initializer=[cell_init, hidden_init],
              name="lstm-scan",
          )
  
      # When it is requested that we only return the final sequence step,
      # we need to slice it out immediately after scan is applied
      if self.only_return_final:
          return hid_out[-1]
  
      # if scan is backward reverse the output
      if self.backwards:
          hid_out = tf.reverse(hid_out, axis=[0])
  
      # dimshuffle back to (n_samples, n_time_steps, n_features))
      hid_out = tf.transpose(hid_out, [1, 0, 2])
  
      return hid_out
  
imports: import types
  import tensorflow
  from neupy import init
  from neupy.utils import tensorflow_session
  from neupy.exceptions import LayerConnectionError
  from neupy.core.properties import IntProperty, Property, NumberProperty, ParameterProperty
  from .base import BaseLayer
label_desc: Use image node_id 3 for calling the LSTM obj's underlying member method code with example usage: obj.output(input) and returns: hid_out, hid_out, list