def fit(
        self, x: np.ndarray, y: np.ndarray, batch_size: int = 128, nb_epochs: int = 20, **kwargs
    ) -> None:  # pragma: no cover
        """
        Fit the classifier on the training set `(inputs, outputs)`.

        :param x: Training data.
        :param y: Target values (class labels) one-hot-encoded of shape (nb_samples, nb_classes) or index labels of
                  shape (nb_samples,).
        :param batch_size: Size of batches.
        :param nb_epochs: Number of epochs to use for training.
        :param kwargs: Dictionary of framework-specific arguments. This parameter is not currently supported for MXNet
               and providing it takes no effect.
        """
        import mxnet as mx

        if self.optimizer is None:
            raise ValueError("An MXNet optimizer is required for fitting the model.")

        training_mode = True

        y = check_and_transform_label_format(y, nb_classes=self.nb_classes)

        # Apply preprocessing
        x_preprocessed, y_preprocessed = self._apply_preprocessing(x, y, fit=True)
        y_preprocessed = np.argmax(y_preprocessed, axis=1)
        nb_batch = int(np.ceil(len(x_preprocessed) / batch_size))
        ind = np.arange(len(x_preprocessed))

        for _ in range(nb_epochs):
            # Shuffle the examples
            np.random.shuffle(ind)

            # Train for one epoch
            for m in range(nb_batch):
                x_batch = mx.nd.array(
                    x_preprocessed[ind[m * batch_size : (m + 1) * batch_size]].astype(config.ART_NUMPY_DTYPE)
                ).as_in_context(self.ctx)
                y_batch = mx.nd.array(y_preprocessed[ind[m * batch_size : (m + 1) * batch_size]]).as_in_context(
                    self.ctx
                )

                with mx.autograd.record(train_mode=training_mode):
                    # Perform prediction
                    preds = self._model(x_batch)

                    # Apply postprocessing
                    preds = self._apply_postprocessing(preds=preds, fit=True)

                    # Form the loss function
                    loss = self.loss(preds, y_batch)

                loss.backward()

                # Update parameters
                self.optimizer.step(batch_size)

        Fit the classifier on the training set `(inputs, outputs)`.

        :param x: Training data.
        :param y: Target values (class labels) one-hot-encoded of shape (nb_samples, nb_classes) or index labels of
                  shape (nb_samples,).
        :param batch_size: Size of batches.
        :param nb_epochs: Number of epochs to use for training.
        :param kwargs: Dictionary of framework-specific arguments. This parameter is not currently supported for MXNet
               and providing it takes no effect.
        
art/estimators/classification/mxnet.py