text: from nnunet.training.network_training.nnUNetTrainer import nnUNetTrainer
  from nnunet.training.network_training.nnUNetTrainerV2 import nnUNetTrainerV2
  from torch.optim import lr_scheduler
  from radam.radam import RAdam
  
  
  class nnUNetTrainerV2_RAdam(nnUNetTrainerV2):
      def __init__(self, plans_file, fold, output_folder=None, dataset_directory=None, batch_dice=True, stage=None,
                   unpack_data=True, deterministic=True, fp16=False):
          super().__init__(plans_file, fold, output_folder, dataset_directory, batch_dice, stage, unpack_data,
                           deterministic, fp16)
  
      def initialize_optimizer_and_scheduler(self):
          assert self.network is not None, "self.initialize_network must be called first"
          print("Use RAdam with lr reduced on plateau")
          self.optimizer = RAdam(
              self.network.parameters(),
              lr=self.initial_lr,
              weight_decay=self.weight_decay,
          )
          self.lr_scheduler = lr_scheduler.ReduceLROnPlateau(self.optimizer, mode='min', factor=0.2,
                                                             patience=self.lr_scheduler_patience,
                                                             verbose=True, threshold=self.lr_scheduler_eps,
                                                             threshold_mode="abs")
  
      def maybe_update_lr(self, epoch=None):
          # maybe update learning rate
          if self.lr_scheduler is not None:
              assert isinstance(self.lr_scheduler, (lr_scheduler.ReduceLROnPlateau, lr_scheduler._LRScheduler))
  
              if isinstance(self.lr_scheduler, lr_scheduler.ReduceLROnPlateau):
                  # lr scheduler is updated with moving average val loss. should be more robust
                  if self.epoch > 0 and self.train_loss_MA is not None:  # otherwise self.train_loss_MA is None
                      self.lr_scheduler.step(self.train_loss_MA)
              else:
                  self.lr_scheduler.step(self.epoch + 1)
          self.print_to_log_file("lr is now (scheduler) %s" % str(self.optimizer.param_groups[0]['lr']))
  
      def on_epoch_end(self):
          return nnUNetTrainer.on_epoch_end(self)
  