def __init__(
        self,
        classifier: "CLASSIFIER_TYPE",
        backdoor: PoisoningAttackBackdoor,
        feature_layer: int | str,
        target: np.ndarray | list[tuple[np.ndarray, np.ndarray]],
        pp_poison: float | list[float] = 0.05,
        discriminator_layer_1: int = 256,
        discriminator_layer_2: int = 128,
        regularization: float = 10,
        learning_rate: float = 1e-4,
        clone=True,
    ):
        """
        Initialize a Feature Collision Clean-Label poisoning attack

        :param classifier: A neural network classifier.
        :param backdoor: The backdoor attack used to poison samples
        :param feature_layer: The layer of the original network to extract features from
        :param target: The target label to poison
        :param pp_poison: The percentage of training data to poison
        :param discriminator_layer_1: The size of the first discriminator layer
        :param discriminator_layer_2: The size of the second discriminator layer
        :param regularization: The regularization constant for the backdoor recognition part of the loss function
        :param learning_rate: The learning rate of clean-label attack optimization.
        :param clone: Whether to clone the model or apply the attack on the original model
        """
        super().__init__(classifier=classifier)
        self.backdoor = backdoor
        self.feature_layer = feature_layer
        self.target = target
        if isinstance(pp_poison, float):
            self.pp_poison = [pp_poison]
        else:
            self.pp_poison = pp_poison
        self.discriminator_layer_1 = discriminator_layer_1
        self.discriminator_layer_2 = discriminator_layer_2
        self.regularization = regularization
        self.train_data: np.ndarray | None = None
        self.train_labels: np.ndarray | None = None
        self.is_backdoor: np.ndarray | None = None
        self.learning_rate = learning_rate
        self._check_params()

        if isinstance(self.estimator, KerasClassifier):
            using_tf_keras = "tensorflow.python.keras" in str(type(self.estimator.model))
            if using_tf_keras:  # pragma: no cover
                from tensorflow.keras.models import Model, clone_model
                from tensorflow.keras.layers import (
                    GaussianNoise,
                    Dense,
                    BatchNormalization,
                    LeakyReLU,
                )
                from tensorflow.keras.optimizers.legacy import Adam

                opt = Adam(lr=self.learning_rate)

            else:
                from keras import Model
                from keras.models import clone_model
                from keras.layers import GaussianNoise, Dense, BatchNormalization, LeakyReLU

                try:
                    from keras.optimizers.legacy import Adam

                    opt = Adam(lr=self.learning_rate)
                except ImportError:
                    from keras.optimizers import adam_v2

                    opt = adam_v2.Adam(lr=self.learning_rate)

            if clone:
                self.orig_model = clone_model(self.estimator.model, input_tensors=self.estimator.model.inputs)
            else:
                self.orig_model = self.estimator.model
            model_input = self.orig_model.input
            init_model_output = self.orig_model(model_input)

            # Extracting feature tensor
            if isinstance(self.feature_layer, int):
                feature_layer_tensor = self.orig_model.layers[self.feature_layer].output
            else:
                feature_layer_tensor = self.orig_model.get_layer(name=feature_layer).output
            feature_layer_output = Model(inputs=[model_input], outputs=[feature_layer_tensor])

            # Architecture for discriminator
            discriminator_input = feature_layer_output(model_input)
            discriminator_input = GaussianNoise(stddev=1)(discriminator_input)
            dense_layer_1 = Dense(self.discriminator_layer_1)(discriminator_input)
            norm_1_layer = BatchNormalization()(dense_layer_1)
            leaky_layer_1 = LeakyReLU(alpha=0.2)(norm_1_layer)
            dense_layer_2 = Dense(self.discriminator_layer_2)(leaky_layer_1)
            norm_2_layer = BatchNormalization()(dense_layer_2)
            leaky_layer_2 = LeakyReLU(alpha=0.2)(norm_2_layer)
            backdoor_detect = Dense(2, activation="softmax", name="backdoor_detect")(leaky_layer_2)

            # Creating embedded model
            self.embed_model = Model(inputs=self.orig_model.inputs, outputs=[init_model_output, backdoor_detect])

            # Add backdoor detection loss
            model_name = self.orig_model.name
            model_loss = self.estimator.model.loss
            loss_name = "backdoor_detect"
            loss_type = "binary_crossentropy"
            if isinstance(model_loss, str):
                losses = {model_name: model_loss, loss_name: loss_type}
                loss_weights = {model_name: 1.0, loss_name: -self.regularization}
            elif isinstance(model_loss, dict):
                losses = model_loss
                losses[loss_name] = loss_type
                loss_weights = self.orig_model.loss_weights
                loss_weights[loss_name] = -self.regularization
            else:
                raise TypeError(f"Cannot read model loss value of type {type(model_loss)}")

            self.embed_model.compile(optimizer=opt, loss=losses, loss_weights=loss_weights, metrics=["accuracy"])
        else:
            raise NotImplementedError("This attack currently only supports Keras.")

        Initialize a Feature Collision Clean-Label poisoning attack

        :param classifier: A neural network classifier.
        :param backdoor: The backdoor attack used to poison samples
        :param feature_layer: The layer of the original network to extract features from
        :param target: The target label to poison
        :param pp_poison: The percentage of training data to poison
        :param discriminator_layer_1: The size of the first discriminator layer
        :param discriminator_layer_2: The size of the second discriminator layer
        :param regularization: The regularization constant for the backdoor recognition part of the loss function
        :param learning_rate: The learning rate of clean-label attack optimization.
        :param clone: Whether to clone the model or apply the attack on the original model
        
art/attacks/poisoning/adversarial_embedding_attack.py