//  [python]
def __init__(self, sess, mlmodel: MLModel, hyperparams: Dict = None):

        supported_backends = ["tensorflow"]
        if mlmodel.backend not in supported_backends:
            raise ValueError(
                f"{mlmodel.backend} is not in supported backends {supported_backends}"
            )

        self.sess = sess  # Tensorflow session
        self._hyperparams = merge_default_parameters(
            hyperparams, self._DEFAULT_HYPERPARAMS
        )

        self._kappa = self._hyperparams["kappa"]
        self._mode = self._hyperparams["mode"]

        batch_size = self._hyperparams["batch_size"]
        num_classes = self._hyperparams["num_classes"]
        beta = self._hyperparams["beta"]
        gamma = self._hyperparams["gamma"]

        super().__init__(mlmodel)
        shape_batch = (batch_size, len(mlmodel.feature_input_order))

        self._AE = self._load_ae(self._hyperparams, mlmodel)

        self._initialize_tf_variables(batch_size, num_classes, shape_batch)

        """Fast Iterative Soft Thresholding"""
        """--------------------------------"""
        # Commented by us:
        # BEGIN: conditions to compute the ell1 regularization
        # this should be the function S_beta(z) in the paper
        if self._mode not in ["PP", "PN"]:
            raise ValueError("Mode not known, please use either PP or PN")

        zt = tf.divide(self._global_step, self._global_step + tf.cast(3, tf.float32))

        self._assign_adv = self._compute_adv(self._orig, self._adv_s, beta)
        self._assign_adv_s = self._compute_adv_s(
            zt, self._orig, self._adv, self._assign_adv
        )

        self._adv_updater = tf.assign(self._adv, self._assign_adv)
        self._adv_updater_s = tf.assign(self._adv_s, self._assign_adv_s)

        # deviation delta
        delta = self._orig - self._adv
        delta_s = self._orig - self._adv_s

        # distance to the input data
        L1_dist, L2_dist = self._compute_l_norm(delta)
        _, L2_dist_s = self._compute_l_norm(delta_s)

        self._ToEnforceLabel_Score = self._get_label_score(delta, self._adv)
        ToEnforceLabel_Score_s = self._get_label_score(delta_s, self._adv_s)

        # composite distance loss
        self._L2_L1_dist = L2_dist + tf.multiply(L1_dist, beta)

        self._target_lab_score = self._compute_target_lab_score(
            self._target_label, self._ToEnforceLabel_Score
        )
        target_lab_score_s = self._compute_target_lab_score(
            self._target_label, ToEnforceLabel_Score_s
        )

        self._max_nontarget_lab_score = self._compute_non_target_lab_score(
            self._target_label, self._ToEnforceLabel_Score
        )
        max_nontarget_lab_score_s = self._compute_non_target_lab_score(
            self._target_label, ToEnforceLabel_Score_s
        )

        # sum up the losses
        self._Loss_L1Dist = tf.reduce_sum(L1_dist)
        (
            self._Loss_L2Dist,
            self._Loss_Attack,
            self._Loss_AE_Dist,
            Loss_ToOptimize,
        ) = self._compute_losses(
            delta,
            self._adv,
            L2_dist,
            self._max_nontarget_lab_score,
            self._target_lab_score,
            gamma,
        )
        (_, _, _, Loss_ToOptimize_s,) = self._compute_losses(
            delta_s,
            self._adv_s,
            L2_dist_s,
            max_nontarget_lab_score_s,
            target_lab_score_s,
            gamma,
        )
        self._Loss_Overall = Loss_ToOptimize + tf.multiply(beta, self._Loss_L1Dist)

        learning_rate = tf.train.polynomial_decay(
            self._hyperparams["init_learning_rate"],
            self._global_step,
            self._hyperparams["max_iterations"],
            0,
            power=0.5,
        )

        self._train = self._optimization(Loss_ToOptimize_s, self._adv_s, learning_rate)
        start_vars = set(x.name for x in tf.global_variables())
        new_vars = [x for x in tf.global_variables() if x.name not in start_vars]

        # these are the variables to initialize when we run
        self._setup = self._set_setup()

        self._init = tf.variables_initializer(
            var_list=[self._global_step] + [self._adv_s] + [self._adv] + new_vars
        )