def _attack_training(
        self,
        x: np.ndarray,
        y: dict[str, list[np.ndarray]],
        mask: np.ndarray | None,
        target_class: int,
        victim_class: int,
        project_texture_op: "Tensor",
        current_image_assign_to_input_image_op: "Tensor",
        accumulated_gradients_op: "Tensor",
        final_attack_optimization_op: "Tensor",
        current_variable: "Tensor",
        current_value: "Tensor",
    ) -> list[np.ndarray]:
        """
        Do attack optimization.

        :param x: Sample image/texture.
        :param y: A dictionary of target labels for object detector. The fields of the dictionary are as follows:

                    - `groundtruth_boxes_list`: A list of `nb_samples` size of 2-D tf.float32 tensors of shape
                                                [num_boxes, 4] containing coordinates of the groundtruth boxes.
                                                Groundtruth boxes are provided in [y_min, x_min, y_max, x_max]
                                                format and also assumed to be normalized as well as clipped
                                                relative to the image window with conditions y_min <= y_max and
                                                x_min <= x_max.
                    - `groundtruth_classes_list`: A list of `nb_samples` size of 1-D tf.float32 tensors of shape
                                                  [num_boxes] containing the class targets with the zero index
                                                  assumed to map to the first non-background class.
                    - `groundtruth_weights_list`: A list of `nb_samples` size of 1-D tf.float32 tensors of shape
                                                  [num_boxes] containing weights for groundtruth boxes.
        :param mask: Input mask.
        :param target_class: Target class.
        :param victim_class: Victim class.
        :param project_texture_op: The project texture operator in the TensorFlow graph.
        :param current_image_assign_to_input_image_op: The current_image assigned to input_image operator in the
                                                       TensorFlow graph.
        :param accumulated_gradients_op: The accumulated gradients operator in the TensorFlow graph.
        :param final_attack_optimization_op: The final attack optimization operator in the TensorFlow graph.
        :param current_value: The current image/texture in the TensorFlow graph.
        :param current_variable: The current image/texture variable in the TensorFlow graph.

        :return: Adversarial image/texture.
        """
        import tensorflow as tf

        # Initialize session
        self.estimator.sess.run(tf.global_variables_initializer())
        self.estimator.sess.run(tf.local_variables_initializer())

        # Create common feed_dict
        feed_dict = {
            "initial_input:0": x,
            "learning_rate:0": self.learning_rate,
            "rpn_classifier_weight:0": self.rpn_classifier_weight,
            "rpn_localizer_weight:0": self.rpn_localizer_weight,
            "box_classifier_weight:0": self.box_classifier_weight,
            "box_localizer_weight:0": self.box_localizer_weight,
            "target_class_phd:0": target_class,
            "victim_class_phd:0": victim_class,
            "box_iou_threshold:0": self.box_iou_threshold,
            "box_target_weight:0": self.box_target_weight,
            "box_victim_weight:0": self.box_victim_weight,
            "box_target_cw_weight:0": self.box_target_cw_weight,
            "box_target_cw_confidence:0": self.box_target_cw_confidence,
            "box_victim_cw_weight:0": self.box_victim_cw_weight,
            "box_victim_cw_confidence:0": self.box_victim_cw_confidence,
            "rpn_iou_threshold:0": self.rpn_iou_threshold,
            "rpn_background_weight:0": self.rpn_background_weight,
            "rpn_foreground_weight:0": self.rpn_foreground_weight,
            "rpn_cw_weight:0": self.rpn_cw_weight,
            "rpn_cw_confidence:0": self.rpn_cw_confidence,
            "similarity_weight:0": self.similarity_weight,
        }

        # Add momentum to feed_dict
        if self.optimizer in ["RMSPropOptimizer", "MomentumOptimizer"]:
            feed_dict["momentum:0"] = self.momentum

        # Add decay to feed_dict
        if self.optimizer == "RMSPropOptimizer":
            feed_dict["decay:0"] = self.decay

        # Add mask to feed_dict
        if self.texture_as_input:
            feed_dict["mask_input:0"] = mask

        # Training loop for attack optimization
        for _ in range(self.max_iter):
            # Accumulate gradients
            for _ in range(self.random_size):
                if self.texture_as_input:
                    # Random transformation
                    background, image_frame, y_transform = self.random_transform(x)

                    # Add more to feed_dict
                    feed_dict["background_phd:0"] = background
                    feed_dict["image_frame_phd:0"] = image_frame

                    for i in range(x.shape[0]):
                        feed_dict[f"groundtruth_boxes_{i}:0"] = y_transform["groundtruth_boxes_list"][i]
                        feed_dict[f"groundtruth_classes_{i}:0"] = y_transform["groundtruth_classes_list"][i]
                        feed_dict[f"groundtruth_weights_{i}:0"] = y_transform["groundtruth_weights_list"][i]

                else:
                    # Random transformation
                    random_transformation = self.random_transform(x)

                    # Add more to feed_dict
                    feed_dict["random_transformation_phd:0"] = random_transformation

                    for i in range(x.shape[0]):
                        feed_dict[f"groundtruth_boxes_{i}:0"] = y["groundtruth_boxes_list"][i]
                        feed_dict[f"groundtruth_classes_{i}:0"] = y["groundtruth_classes_list"][i]
                        feed_dict[f"groundtruth_weights_{i}:0"] = y["groundtruth_weights_list"][i]

                # Accumulate gradients
                self.estimator.sess.run(current_image_assign_to_input_image_op, feed_dict)
                self.estimator.sess.run(accumulated_gradients_op, feed_dict)

            # Update image/texture variable
            self.estimator.sess.run(final_attack_optimization_op, feed_dict)

            if self.texture_as_input:
                self.estimator.sess.run(project_texture_op, feed_dict)

        result = self.estimator.sess.run([current_variable, current_value], feed_dict)

        return result

        Do attack optimization.

        :param x: Sample image/texture.
        :param y: A dictionary of target labels for object detector. The fields of the dictionary are as follows:

                    - `groundtruth_boxes_list`: A list of `nb_samples` size of 2-D tf.float32 tensors of shape
                                                [num_boxes, 4] containing coordinates of the groundtruth boxes.
                                                Groundtruth boxes are provided in [y_min, x_min, y_max, x_max]
                                                format and also assumed to be normalized as well as clipped
                                                relative to the image window with conditions y_min <= y_max and
                                                x_min <= x_max.
                    - `groundtruth_classes_list`: A list of `nb_samples` size of 1-D tf.float32 tensors of shape
                                                  [num_boxes] containing the class targets with the zero index
                                                  assumed to map to the first non-background class.
                    - `groundtruth_weights_list`: A list of `nb_samples` size of 1-D tf.float32 tensors of shape
                                                  [num_boxes] containing weights for groundtruth boxes.
        :param mask: Input mask.
        :param target_class: Target class.
        :param victim_class: Victim class.
        :param project_texture_op: The project texture operator in the TensorFlow graph.
        :param current_image_assign_to_input_image_op: The current_image assigned to input_image operator in the
                                                       TensorFlow graph.
        :param accumulated_gradients_op: The accumulated gradients operator in the TensorFlow graph.
        :param final_attack_optimization_op: The final attack optimization operator in the TensorFlow graph.
        :param current_value: The current image/texture in the TensorFlow graph.
        :param current_variable: The current image/texture variable in the TensorFlow graph.

        :return: Adversarial image/texture.
        
art/attacks/evasion/shapeshifter.py