//  [python]
def attack_stage2(
        self,
        audios,
        trans,
        adv,
        th_batch,
        psd_max_batch,
        maxlen,
        sample_rate,
        masks,
        masks_freq,
        num_loop,
        data,
        lr_stage2,
    ):
        sess = self.sess
        # initialize and load the pretrained model
        sess.run(tf.initializers.global_variables())
        saver = tf.train.Saver(
            [x for x in tf.global_variables() if x.name.startswith("librispeech")]
        )
        saver.restore(sess, FLAGS.checkpoint)

        sess.run(
            tf.assign(self.rescale, np.ones((self.batch_size, 1), dtype=np.float32))
        )
        sess.run(
            tf.assign(self.alpha, np.ones((self.batch_size), dtype=np.float32) * 0.05)
        )

        # reassign the variables
        sess.run(tf.assign(self.delta_large, adv))

        # noise = np.random.normal(scale=2, size=audios.shape)
        noise = np.zeros(audios.shape)
        feed_dict = {
            self.input_tf: audios,
            self.tgt_tf: trans,
            self.sample_rate_tf: sample_rate,
            self.th: th_batch,
            self.psd_max_ori: psd_max_batch,
            self.mask: masks,
            self.mask_freq: masks_freq,
            self.noise: noise,
            self.maxlen: maxlen,
            self.lr_stage2: lr_stage2,
        }
        losses, predictions = sess.run((self.celoss, self.decoded), feed_dict)

        # show the initial predictions
        for i in range(self.batch_size):
            print(
                "example: {}, loss: {}".format(
                    num_loop * self.batch_size + i, losses[i]
                )
            )
            print("pred:{}".format(predictions["topk_decoded"][i, 0]))
            print("targ:{}".format(trans[i].lower()))
            print("true: {}".format(data[1, i].lower()))

        # We'll make a bunch of iterations of gradient descent here
        now = time.time()
        MAX = self.num_iter_stage2
        loss_th = [np.inf] * self.batch_size
        final_deltas = [None] * self.batch_size
        final_alpha = [None] * self.batch_size
        # final_th = [None] * self.batch_size
        clock = 0
        min_th = 0.0005
        for i in range(MAX):
            now = time.time()
            if i == 3000:
                # min_th = -np.inf
                lr_stage2 = 0.1
                feed_dict = {
                    self.input_tf: audios,
                    self.tgt_tf: trans,
                    self.sample_rate_tf: sample_rate,
                    self.th: th_batch,
                    self.psd_max_ori: psd_max_batch,
                    self.mask: masks,
                    self.mask_freq: masks_freq,
                    self.noise: noise,
                    self.maxlen: maxlen,
                    self.lr_stage2: lr_stage2,
                }

            # Actually do the optimization
            sess.run(self.train2, feed_dict)

            if i % 10 == 0:
                d, cl, l, predictions, new_input = sess.run(
                    (
                        self.delta,
                        self.celoss,
                        self.loss_th,
                        self.decoded,
                        self.new_input,
                    ),
                    feed_dict,
                )

            for ii in range(self.batch_size):
                # print out the prediction each 100 iterations
                if i % 1000 == 0:
                    print("pred:{}".format(predictions["topk_decoded"][ii, 0]))
                    # print("rescale: {}".format(sess.run(self.rescale[ii])))
                if i % 10 == 0:
                    # print("example: {}".format(num_loop * self.batch_size + ii))

                    alpha = sess.run(self.alpha)
                    if i % 100 == 0:
                        print("example: {}".format(num_loop * self.batch_size + ii))
                        print(
                            "iteration: %d, alpha: %f, loss_ce: %f, loss_th: %f"
                            % (i, alpha[ii], cl[ii], l[ii])
                        )

                    # if the network makes the targeted prediction
                    if predictions["topk_decoded"][ii, 0] == trans[ii].lower():
                        if l[ii] < loss_th[ii]:
                            final_deltas[ii] = new_input[ii]
                            loss_th[ii] = l[ii]
                            final_alpha[ii] = alpha[ii]
                            print(
                                "-------------------------------------Succeed---------------------------------"
                            )
                            print(
                                "save the best example=%d at iteration= %d, alpha = %f"
                                % (ii, i, alpha[ii])
                            )

                        # increase the alpha each 20 iterations
                        if i % 20 == 0:
                            alpha[ii] *= 1.2
                            sess.run(tf.assign(self.alpha, alpha))

                    # if the network fails to make the targeted prediction, reduce alpha each 50 iterations
                    if (
                        i % 50 == 0
                        and predictions["topk_decoded"][ii, 0] != trans[ii].lower()
                    ):
                        alpha[ii] *= 0.8
                        alpha[ii] = max(alpha[ii], min_th)
                        sess.run(tf.assign(self.alpha, alpha))

                # in case no final_delta return
                if i == MAX - 1 and final_deltas[ii] is None:
                    final_deltas[ii] = new_input[ii]
            if i % 500 == 0:
                print("alpha is {}, loss_th is {}".format(final_alpha, loss_th))
            if i % 10 == 0:
                print("ten iterations take around {} ".format(clock))
                clock = 0

            clock += time.time() - now

        return final_deltas, loss_th, final_alpha