def __init__(
        self,
        classifier: "CERTIFIER_TYPE",
        nb_epochs: int | None = 20,
        bound: float = 0.1,
        loss_weighting: float = 0.1,
        batch_size: int = 10,
        use_certification_schedule: bool = True,
        certification_schedule: Any | None = None,
        augment_with_pgd: bool = True,
        pgd_params: "PGDParamDict" | None = None,
    ) -> None:
        """
        Create an :class:`.AdversarialTrainerCertified` instance.

        Default values are for MNIST in pixel range 0-1.

        :param classifier: Classifier to train adversarially.
        :param pgd_params: A dictionary containing the specific parameters relating to regular PGD training.
                           If not provided, we will default to typical MNIST values.
                           Otherwise, must contain the following keys:

                           * *eps*: Maximum perturbation that the attacker can introduce.
                           * *eps_step*: Attack step size (input variation) at each iteration.
                           * *max_iter*: The maximum number of iterations.
                           * *batch_size*: Size of the batch on which adversarial samples are generated.
                           * *num_random_init*: Number of random initialisations within the epsilon ball.
        :param bound: The perturbation range for the zonotope. Will be ignored if a certification_schedule is used.
        :param loss_weighting: Weighting factor for the certified loss.
        :param nb_epochs: Number of training epochs.
        :param use_certification_schedule: If to use a training schedule for the certification radius.
        :param certification_schedule: Schedule for gradually increasing the certification radius. Empirical studies
                                       have shown that this is often required to achieve the best performance.
                                       Either True to use the default linear scheduler,
                                       or a class with a .step() method that returns the updated bound every epoch.
        :param batch_size: Size of batches to use for certified training. NB, this will run the data
                           sequentially accumulating gradients over the batch size.
        """
        from art.estimators.certification.deep_z.pytorch import PytorchDeepZ

        if not isinstance(classifier, PytorchDeepZ):
            raise ValueError(
                "The classifier to pass in should be of type PytorchDeepZ which can be found in "
                "art.estimators.certification.deep_z.pytorch.PytorchDeepZ"
            )
        super().__init__(classifier=classifier)
        self.classifier: "CERTIFIER_TYPE"
        self.pgd_params: "PGDParamDict"

        if pgd_params is None:
            self.pgd_params = {"eps": 0.3, "eps_step": 0.05, "max_iter": 20, "batch_size": 128, "num_random_init": 1}
        else:
            self.pgd_params = pgd_params

        self.nb_epochs = nb_epochs
        self.loss_weighting = loss_weighting
        self.bound = bound
        self.use_certification_schedule = use_certification_schedule
        self.certification_schedule = certification_schedule
        self.batch_size = batch_size
        self.augment_with_pgd = augment_with_pgd
        # Setting up adversary and perform adversarial training:
        self.attack = ProjectedGradientDescent(
            estimator=self.classifier,
            eps=self.pgd_params["eps"],
            eps_step=self.pgd_params["eps_step"],
            max_iter=self.pgd_params["max_iter"],
            num_random_init=self.pgd_params["num_random_init"],
        )

        Create an :class:`.AdversarialTrainerCertified` instance.

        Default values are for MNIST in pixel range 0-1.

        :param classifier: Classifier to train adversarially.
        :param pgd_params: A dictionary containing the specific parameters relating to regular PGD training.
                           If not provided, we will default to typical MNIST values.
                           Otherwise, must contain the following keys:

                           * *eps*: Maximum perturbation that the attacker can introduce.
                           * *eps_step*: Attack step size (input variation) at each iteration.
                           * *max_iter*: The maximum number of iterations.
                           * *batch_size*: Size of the batch on which adversarial samples are generated.
                           * *num_random_init*: Number of random initialisations within the epsilon ball.
        :param bound: The perturbation range for the zonotope. Will be ignored if a certification_schedule is used.
        :param loss_weighting: Weighting factor for the certified loss.
        :param nb_epochs: Number of training epochs.
        :param use_certification_schedule: If to use a training schedule for the certification radius.
        :param certification_schedule: Schedule for gradually increasing the certification radius. Empirical studies
                                       have shown that this is often required to achieve the best performance.
                                       Either True to use the default linear scheduler,
                                       or a class with a .step() method that returns the updated bound every epoch.
        :param batch_size: Size of batches to use for certified training. NB, this will run the data
                           sequentially accumulating gradients over the batch size.
        
art/defences/trainer/certified_adversarial_trainer_pytorch.py