class_docstr: Abstract class for defining tasks.
  
  To create your own task, please refer to the provided ABSATask and WSCTask as examples for how to do so.
  There are 4 abstract methods that must be defined: _init_tsne_layout(), _init_table_cols_layout(),
  get_val_to_label_map(), get_tsne_rows(). These definitions will all depend on how the input dataframe
  is structured.
  
  Attributes:
      mode: 'normal' if a single model is loaded, else 'compare'
      num_layers: number of transformer layers in the model
      model_ids: ["model1"] or ["model1", "model2"], used internally
      model_names: a list of the given model names to be displayed in app (correspond to above model_ids)
      collateral_paths: list of filepaths to the model collaterals (attn, hidden_states)
      df_paths: list of filepaths to model dataframe (everything else)
  
      tsne_internal_options: list of column names from the dataframe to color the tsne plot with
      tsne_displayed_options: list of names to display corresponding to the above plot options
      tsne_plot_description: string title for the tsne plot
      attn_map_options: list of options to display for attention map plot
      head_matrix_options: list of options to display for head matrix plot
      table_cols: list of columns to display for the summary table
  
      map_model_id_to_name: dictionary mapping "model1"/"model2" (used internally) to map_model_to_path
      map_model_to_full_df:dict mapping model_ids to dataframes (after _preprocess_df)
      map_model_to_df: dict mapping model_ids to dataframes (after _preprocess_df and _process_all_df)
      map_model_to_collateral: dict mapping model_ids to collateral pahts
code: def __init__(
      self,
      mode: str,
      num_layers: int,
      model_names: List[str],
      collaterals_paths: List[str],
      df_paths: List[str],
  ):
      # General attributes and filepaths
      self.mode = mode
      self.num_layers = num_layers
      self.model_ids = [
          f"model{i + 1}" for i in range(len(collaterals_paths))
      ]
      self.model_names = (
          model_names if model_names is not None else self.model_ids
      )
      self.collaterals_paths = collaterals_paths
      self.df_paths = df_paths
  
      # Mappings to and from user-provided model names (e.g. "BERT", "LiBERT") to internally used model name ("model1", "model2")
      (
          self.map_model_id_to_name,
          self.map_model_name_to_id,
      ) = self._init_model_maps()
  
      # Layout options
      (
          self.tsne_internal_options,
          self.tsne_displayed_options,
          self.tsne_plot_description,
      ) = self._init_tsne_layout()
      self.attn_map_options = self._init_attn_layout()
      self.head_matrix_options = self._init_head_matrix_layout()
      self.table_cols = self._init_table_cols_layout()
  
      # Mappings to from model names to different data sources (dataframe, collateral)
      (
          self.map_model_to_full_df,
          self.map_model_to_df,
      ) = self._init_df_maps()
      self.map_model_to_collateral = self._init_collateral_map()
  
imports: from typing import List, Tuple, Dict, Union
  from abc import ABC, abstractmethod
  import torch
  import pandas
  import numpy
label_desc: Use image node_id 1 to create a new Task object from inherited base classes: ABC with example: obj = Task(mode, num_layers, model_names, collaterals_paths, df_paths)