class_docstr: As the joint influence from external environment and internal cognition, different kinds of user interests are
  evolving over time. Interest Evolving Layer can capture interest evolving process that is relative to the target
  item.
code: def forward(self, queries, keys, keys_length):
      hist_len = keys.shape[1]  # T
      keys_length_cpu = keys_length.cpu()
      if self.gru == "GRU":
          packed_keys = pack_padded_sequence(
              input=keys,
              lengths=keys_length_cpu,
              batch_first=True,
              enforce_sorted=False,
          )
          packed_rnn_outputs, _ = self.dynamic_rnn(packed_keys)
          rnn_outputs, _ = pad_packed_sequence(
              packed_rnn_outputs,
              batch_first=True,
              padding_value=0.0,
              total_length=hist_len,
          )
          att_outputs = self.attention_layer(
              queries, rnn_outputs, keys_length
          )
          outputs = att_outputs.squeeze(1)
  
      # AIGRU
      elif self.gru == "AIGRU":
          att_outputs = self.attention_layer(queries, keys, keys_length)
          interest = keys * att_outputs.transpose(1, 2)
          packed_rnn_outputs = pack_padded_sequence(
              interest,
              lengths=keys_length_cpu,
              batch_first=True,
              enforce_sorted=False,
          )
          _, outputs = self.dynamic_rnn(packed_rnn_outputs)
          outputs = outputs.squeeze(0)
  
      elif self.gru == "AGRU" or self.gru == "AUGRU":
          att_outputs = self.attention_layer(
              queries, keys, keys_length
          ).squeeze(
              1
          )  # [B, T]
          packed_rnn_outputs = pack_padded_sequence(
              keys,
              lengths=keys_length_cpu,
              batch_first=True,
              enforce_sorted=False,
          )
          packed_att_outputs = pack_padded_sequence(
              att_outputs,
              lengths=keys_length_cpu,
              batch_first=True,
              enforce_sorted=False,
          )
          outputs = self.dynamic_rnn(
              packed_rnn_outputs, packed_att_outputs
          )
          outputs, _ = pad_packed_sequence(
              outputs,
              batch_first=True,
              padding_value=0.0,
              total_length=hist_len,
          )
          outputs = self.final_output(outputs, keys_length)  # [B, H]
  
      return outputs
  
imports: import torch
  import torch.nn
  import torch.nn.functional
  from torch.nn.init import xavier_normal_, constant_
  from torch.nn.utils.rnn import pack_padded_sequence, pad_packed_sequence, PackedSequence
  from recbole.utils import ModelType, InputType, FeatureType
  from recbole.model.layers import FMEmbedding, MLPLayers, ContextSeqEmbLayer, SequenceAttLayer
  from recbole.model.abstract_recommender import SequentialRecommender
label_desc: Use image node_id 3 for calling the InterestEvolvingLayer obj's underlying member method code with example usage: obj.forward(queries, keys, keys_length) and returns: outputs