class_docstr: Ecco's central class. A wrapper around language models. We use it to run the language models
  and collect important data like input saliency and neuron activations.
  
  A LM object is typically not created directly by users,
  it is returned by `ecco.from_pretrained()`.
  
  Usage:
  
  ```python
  import ecco
  
  lm = ecco.from_pretrained('distilgpt2')
  output = lm.generate("Hello computer")
  ```
docstr: Collects the activation for all tokens (input and output).
  The default activations collection method.
  
  Args:
      input_: activation tuple to capture. A tuple containing one tensor of
      dimensions (batch_size, sequence_length, neurons)
code: def _get_activations_hook(self, name: str, input_):
      """
      Collects the activation for all tokens (input and output).
      The default activations collection method.
  
      Args:
          input_: activation tuple to capture. A tuple containing one tensor of
          dimensions (batch_size, sequence_length, neurons)
      """
      # print('_get_activations_hook', name)
      # pprint(input_)
      # print(type(input_), len(input_), type(input_[0]), input_[0].shape, len(input_[0]), input_[0][0].shape)
      # in distilGPT and GPT2, the layer name is 'transformer.h.0.mlp.c_fc'
      # Extract the number of the layer from the name
      # TODO: it will not always be 2 for other models. Move to model-config
      # layer_number = int(name.split('.')[2])
      # Get the layer number. This will be an int with periods before aand after it.
      # (?<=\.) means look for a period before the int
      # \d+ means look for one or multiple digits
      # (?=\.) means look for a period after the int
      layer_number = re.search("(?<=\.)\d+(?=\.)", name).group(0)
      layer_type = (
          "encoder" if name.startswith("encoder.") else "decoder"
      )
      # print("layer number: ", layer_number)
  
      collecting_this_layer = (
          self.collect_activations_layer_nums is None
      ) or (layer_number in self.collect_activations_layer_nums)
  
      if collecting_this_layer:
          # Initialize the layer's key the first time we encounter it
          if layer_number not in self._all_activations_dict:
              self._all_activations_dict[layer_type][layer_number] = [0]
  
          # For MLM, we only run one inference step. We save it.
          # For Causal LM, we could be running multiple inference steps with generate(). In that case,
          # overwrite the previous step activations. This collects all activations in the last step
          # Assuming all input tokens are presented as input, no "past"
          # The inputs to c_proj already pass through the gelu activation function
          self._all_activations_dict[layer_type][layer_number] = (
              input_[0].detach().cpu().numpy()
          )
  
imports: from collections import defaultdict
  import inspect
  import json
  import os
  import random
  import torch
  import transformers
  from transformers import BatchEncoding
  import ecco
  import numpy
  from IPython import display
  from torch.nn import functional
  from ecco.attribution import compute_primary_attributions_scores
  from ecco.output import OutputSeq
  from typing import Optional, Any, List, Tuple, Dict, Union
  from operator import attrgetter
  import re
  from ecco.util import is_partial_token, strip_tokenizer_prefix
  from packaging import version
label_desc: Use image node_id 10 for calling the LM obj's underlying member method code with example usage: obj._get_activations_hook(name, input_) without return types