class_docstr: Trainer is training and eval loop for adversarial training.
  
  It is designed to work with PyTorch and Transformers models.
  
  Args:
      model_wrapper (:class:`~textattack.models.wrappers.ModelWrapper`):
          Model wrapper containing both the model and the tokenizer.
      task_type (:obj:`str`, `optional`, defaults to :obj:`"classification"`):
          The task that the model is trained to perform.
          Currently, :class:`~textattack.Trainer` supports two tasks: (1) :obj:`"classification"`, (2) :obj:`"regression"`.
      attack (:class:`~textattack.Attack`):
          :class:`~textattack.Attack` used to generate adversarial examples for training.
      train_dataset (:class:`~textattack.datasets.Dataset`):
          Dataset for training.
      eval_dataset (:class:`~textattack.datasets.Dataset`):
          Dataset for evaluation
      training_args (:class:`~textattack.TrainingArgs`):
          Arguments for training.
  
  Example::
  
      >>> import textattack
      >>> import transformers
  
      >>> model = transformers.AutoModelForSequenceClassification.from_pretrained("bert-base-uncased")
      >>> tokenizer = transformers.AutoTokenizer.from_pretrained("bert-base-uncased")
      >>> model_wrapper = textattack.models.wrappers.HuggingFaceModelWrapper(model, tokenizer)
  
      >>> # We only use DeepWordBugGao2018 to demonstration purposes.
      >>> attack = textattack.attack_recipes.DeepWordBugGao2018.build(model_wrapper)
      >>> train_dataset = textattack.datasets.HuggingFaceDataset("imdb", split="train")
      >>> eval_dataset = textattack.datasets.HuggingFaceDataset("imdb", split="test")
  
      >>> # Train for 3 epochs with 1 initial clean epochs, 1000 adversarial examples per epoch, learning rate of 5e-5, and effective batch size of 32 (8x4).
      >>> training_args = textattack.TrainingArgs(
      ...     num_epochs=3,
      ...     num_clean_epochs=1,
      ...     num_train_adv_examples=1000,
      ...     learning_rate=5e-5,
      ...     per_device_train_batch_size=8,
      ...     gradient_accumulation_steps=4,
      ...     log_to_tb=True,
      ... )
  
      >>> trainer = textattack.Trainer(
      ...     model_wrapper,
      ...     "classification",
      ...     attack,
      ...     train_dataset,
      ...     eval_dataset,
      ...     training_args
      ... )
      >>> trainer.train()
  
  .. note::
      When using :class:`~textattack.Trainer` with `parallel=True` in :class:`~textattack.TrainingArgs`,
      make sure to protect the “entry point” of the program by using :obj:`if __name__ == '__main__':`.
      If not, each worker process used for generating adversarial examples will execute the training code again.
class_docstr_tok: ["Trainer","is","training","and","eval","loop","for","adversarial","training",".","It","is","designed","to","work","with","PyTorch","and","Transformers","models",".","Args",":","model_wrapper","(",":","class",":","`","~textattack.models.wrappers.ModelWrapper","`",")",":","Model","wrapper","containing","both","the","model","and","the","tokenizer",".","task_type","(",":","obj",":","`","str","`",",","`","optional","`",",","defaults","to",":","obj",":","`","``","classification","''","`",")",":","The","task","that","the","model","is","trained","to","perform",".","Currently",",",":","class",":","`","~textattack.Trainer","`","supports","two","tasks",":","(","1",")",":","obj",":","`","``","classification","''","`",",","(","2",")",":","obj",":","`","``","regression","''","`",".","attack","(",":","class",":","`","~textattack.Attack","`",")",":",":","class",":","`","~textattack.Attack","`","used","to","generate","adversarial","examples","for","training",".","train_dataset","(",":","class",":","`","~textattack.datasets.Dataset","`",")",":","Dataset","for","training",".","eval_dataset","(",":","class",":","`","~textattack.datasets.Dataset","`",")",":","Dataset","for","evaluation","training_args","(",":","class",":","`","~textattack.TrainingArgs","`",")",":","Arguments","for","training",".","Example",":",":",">",">",">","import","textattack",">",">",">","import","transformers",">",">",">","model","=","transformers.AutoModelForSequenceClassification.from_pretrained","(","``","bert-base-uncased","''",")",">",">",">","tokenizer","=","transformers.AutoTokenizer.from_pretrained","(","``","bert-base-uncased","''",")",">",">",">","model_wrapper","=","textattack.models.wrappers.HuggingFaceModelWrapper","(","model",",","tokenizer",")",">",">",">","#","We","only","use","DeepWordBugGao2018","to","demonstration","purposes",".",">",">",">","attack","=","textattack.attack_recipes.DeepWordBugGao2018.build","(","model_wrapper",")",">",">",">","train_dataset","=","textattack.datasets.HuggingFaceDataset","(","``","imdb","''",",","split=","''","train","''",")",">",">",">","eval_dataset","=","textattack.datasets.HuggingFaceDataset","(","``","imdb","''",",","split=","''","test","''",")",">",">",">","#","Train","for","3","epochs","with","1","initial","clean","epochs",",","1000","adversarial","examples","per","epoch",",","learning","rate","of","5e-5",",","and","effective","batch","size","of","32","(","8x4",")",".",">",">",">","training_args","=","textattack.TrainingArgs","(","...","num_epochs=3",",","...","num_clean_epochs=1",",","...","num_train_adv_examples=1000",",","...","learning_rate=5e-5",",","...","per_device_train_batch_size=8",",","...","gradient_accumulation_steps=4",",","...","log_to_tb=True",",","...",")",">",">",">","trainer","=","textattack.Trainer","(","...","model_wrapper",",","...","``","classification","''",",","...","attack",",","...","train_dataset",",","...","eval_dataset",",","...","training_args","...",")",">",">",">","trainer.train","(",")","..","note",":",":","When","using",":","class",":","`","~textattack.Trainer","`","with","`","parallel=True","`","in",":","class",":","`","~textattack.TrainingArgs","`",",","make","sure","to","protect","the","\u201c","entry","point","\u201d","of","the","program","by","using",":","obj",":","`","if","__name__","==","'__main__","'",":","`",".","If","not",",","each","worker","process","used","for","generating","adversarial","examples","will","execute","the","training","code","again","."]
code: def _write_readme(
      self, best_eval_score, best_eval_score_epoch, train_batch_size
  ):
      if isinstance(self.training_args, CommandLineTrainingArgs):
          model_name = self.training_args.model_name_or_path
      elif isinstance(
          self.model_wrapper.model, transformers.PreTrainedModel
      ):
          if (
              hasattr(self.model_wrapper.model.config, "_name_or_path")
              and self.model_wrapper.model.config._name_or_path
              in HUGGINGFACE_MODELS
          ):
              # TODO Better way than just checking HUGGINGFACE_MODELS ?
              model_name = self.model_wrapper.model.config._name_or_path
          elif hasattr(self.model_wrapper.model.config, "model_type"):
              model_name = self.model_wrapper.model.config.model_type
          else:
              model_name = ""
      else:
          model_name = ""
  
      if model_name:
          model_name = f"`{model_name}`"
  
      if (
          isinstance(self.training_args, CommandLineTrainingArgs)
          and self.training_args.model_max_length
      ):
          model_max_length = self.training_args.model_max_length
      elif isinstance(
          self.model_wrapper.model,
          (
              transformers.PreTrainedModel,
              LSTMForClassification,
              WordCNNForClassification,
          ),
      ):
          model_max_length = (
              self.model_wrapper.tokenizer.model_max_length
          )
      else:
          model_max_length = None
  
      if model_max_length:
          model_max_length_str = (
              f" a maximum sequence length of {model_max_length},"
          )
      else:
          model_max_length_str = ""
  
      if isinstance(
          self.train_dataset, textattack.datasets.HuggingFaceDataset
      ) and hasattr(self.train_dataset, "_name"):
          dataset_name = self.train_dataset._name
          if hasattr(self.train_dataset, "_subset"):
              dataset_name += f" ({self.train_dataset._subset})"
      elif isinstance(
          self.eval_dataset, textattack.datasets.HuggingFaceDataset
      ) and hasattr(self.eval_dataset, "_name"):
          dataset_name = self.eval_dataset._name
          if hasattr(self.eval_dataset, "_subset"):
              dataset_name += f" ({self.eval_dataset._subset})"
      else:
          dataset_name = None
  
      if dataset_name:
          dataset_str = "and the `{dataset_name}` dataset loaded using the `datasets` library"
      else:
          dataset_str = ""
  
      loss_func = (
          "mean squared error"
          if self.task_type == "regression"
          else "cross-entropy"
      )
      metric_name = (
          "pearson correlation"
          if self.task_type == "regression"
          else "accuracy"
      )
      epoch_info = f"{best_eval_score_epoch} epoch" + (
          "s" if best_eval_score_epoch > 1 else ""
      )
      readme_text = f"""
              ## TextAttack Model Card
  
              This {model_name} model was fine-tuned using TextAttack{dataset_str}. The model was fine-tuned
              for {self.training_args.num_epochs} epochs with a batch size of {train_batch_size},
              {model_max_length_str} and an initial learning rate of {self.training_args.learning_rate}.
              Since this was a {self.task_type} task, the model was trained with a {loss_func} loss function.
              The best score the model achieved on this task was {best_eval_score}, as measured by the
              eval set {metric_name}, found after {epoch_info}.
  
              For more information, check out [TextAttack on Github](https://github.com/QData/TextAttack).
  
              """
  
      readme_save_path = os.path.join(
          self.training_args.output_dir, "README.md"
      )
      with open(readme_save_path, "w", encoding="utf-8") as f:
          f.write(readme_text.strip() + "\n")
      logger.info(f"Wrote README to {readme_save_path}.")
  
imports: import collections
  import json
  import logging
  import math
  import os
  import scipy
  import torch
  import tqdm
  import transformers
  import textattack
  from textattack.shared.utils import logger
  from .attack import Attack
  from .attack_args import AttackArgs
  from .attack_results import MaximizedAttackResult, SuccessfulAttackResult
  from .attacker import Attacker
  from .model_args import HUGGINGFACE_MODELS
  from .models.helpers import LSTMForClassification, WordCNNForClassification
  from .models.wrappers import ModelWrapper
  from .training_args import CommandLineTrainingArgs, TrainingArgs
label_desc: Use image node_id 14 for calling the Trainer obj's underlying member method code with example usage: obj._write_readme(best_eval_score, best_eval_score_epoch, train_batch_size) without return types