def generate(  # type: ignore
        self, x: np.ndarray, y: np.ndarray | None = None, **kwargs
    ) -> tuple[np.ndarray, np.ndarray]:
        """
        Generate an adversarial patch and return the patch and its mask in arrays.

        :param x: An array with the original input images of shape NHWC or input videos of shape NFHWC.
        :param y: An array with the original true labels.
        :param mask: A boolean array of shape equal to the shape of a single samples (1, H, W) or the shape of `x`
                     (N, H, W) without their channel dimensions. Any features for which the mask is True can be the
                     center location of the patch during sampling.
        :type mask: `np.ndarray`
        :param reset_patch: If `True` reset patch to initial values of mean of minimal and maximal clip value, else if
                            `False` (default) restart from previous patch values created by previous call to `generate`
                            or mean of minimal and maximal clip value if first call to `generate`.
        :type reset_patch: bool
        :return: An array with adversarial patch and an array of the patch mask.
        """
        import tensorflow as tf

        shuffle = kwargs.get("shuffle", True)
        mask = kwargs.get("mask")
        if mask is not None:
            mask = mask.copy()
        mask = self._check_mask(mask=mask, x=x)

        if y is None:  # pragma: no cover
            logger.info("Setting labels to estimator predictions and running untargeted attack because `y=None`.")
            y = to_categorical(np.argmax(self.estimator.predict(x=x), axis=1), nb_classes=self.estimator.nb_classes)

        if kwargs.get("reset_patch"):
            self.reset_patch(initial_patch_value=self._initial_value)

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

        # check if logits or probabilities
        y_pred = self.estimator.predict(x=x[[0]])

        if is_probability(y_pred):
            self.use_logits = False
        else:
            self.use_logits = True

        if mask is None:
            if shuffle:
                dataset = tf.data.Dataset.from_tensor_slices((x, y)).shuffle(10000).batch(self.batch_size)
            else:
                dataset = tf.data.Dataset.from_tensor_slices((x, y)).batch(self.batch_size)
        else:
            if shuffle:
                dataset = tf.data.Dataset.from_tensor_slices((x, y, mask)).shuffle(10000).batch(self.batch_size)
            else:
                dataset = tf.data.Dataset.from_tensor_slices((x, y, mask)).batch(self.batch_size)

        for i_iter in trange(self.max_iter, desc="Adversarial Patch TensorFlow v2", disable=not self.verbose):
            if mask is None:
                counter = 0
                for images, target in dataset:
                    counter += 1
                    _ = self._train_step(images=images, target=target, mask=None)
            else:
                for images, target, mask_i in dataset:
                    _ = self._train_step(images=images, target=target, mask=mask_i)

            # Write summary
            if self.summary_writer is not None:  # pragma: no cover
                x_patched = self._random_overlay(images=x, patch=self._patch, mask=mask)

                self.summary_writer.update(
                    batch_id=0,
                    global_step=i_iter,
                    grad=None,
                    patch=self._patch.numpy().transpose((2, 0, 1)),
                    estimator=self.estimator,
                    x=x_patched,
                    y=y,
                    targeted=self.targeted,
                )

        if self.summary_writer is not None:
            self.summary_writer.reset()

        return (
            self._patch.numpy(),
            self._get_circular_patch_mask(nb_samples=1).numpy()[0],
        )

        Generate an adversarial patch and return the patch and its mask in arrays.

        :param x: An array with the original input images of shape NHWC or input videos of shape NFHWC.
        :param y: An array with the original true labels.
        :param mask: A boolean array of shape equal to the shape of a single samples (1, H, W) or the shape of `x`
                     (N, H, W) without their channel dimensions. Any features for which the mask is True can be the
                     center location of the patch during sampling.
        :type mask: `np.ndarray`
        :param reset_patch: If `True` reset patch to initial values of mean of minimal and maximal clip value, else if
                            `False` (default) restart from previous patch values created by previous call to `generate`
                            or mean of minimal and maximal clip value if first call to `generate`.
        :type reset_patch: bool
        :return: An array with adversarial patch and an array of the patch mask.
        
art/attacks/evasion/adversarial_patch/adversarial_patch_tensorflow.py