def _init_guess(
        self, tile_mat: dict, x_init: "torch.Tensor", x_org: "torch.Tensor", tile_size: int, n_samples: int
    ) -> Tuple["torch.Tensor", dict]:
        """
        Generate an initial perturbation for each grid.

        :param tile_mat: Internal structure used to store patches for each mesh.
        :param x_init: Perturbed images from previous runs.
        :param x_org: The original images.
        :param tile_size: The size of each tile.
        :return: Guessed images and internal structure.
        """
        import torch

        TRIAL = 10  # pylint: disable=C0103
        patches = self.candidates
        masks = [None] * len(self.candidates)
        for _ in range(TRIAL):
            x_cand = torch.zeros(
                (n_samples, 3, x_init.shape[-2], x_init.shape[-1]), dtype=x_init.dtype, device=self.estimator.device
            )

            # generate tiles
            # To save the computing time, we generate some tiles in advance.
            # partial tiles are updated on-the-fly
            r_tile = torch.zeros((0, 3, tile_size, tile_size), device=self.estimator.device)
            r_mask = torch.zeros((0, 3, tile_size, tile_size), device=self.estimator.device)
            while r_tile.shape[0] < n_samples:
                t_tile, t_mask = generate_tile(patches, masks, tile_size, [1, 2])
                r_tile = torch.cat([r_tile, t_tile], dim=0)
                r_mask = torch.cat([r_mask, t_mask], dim=0)

            for _, obj in tile_mat.items():
                # select n_samples
                while r_tile.shape[0] < int(1.5 * n_samples):
                    t_tile, t_mask = generate_tile(patches, masks, tile_size, [1, 2])
                    r_tile = torch.cat([r_tile, t_tile], dim=0)
                    r_mask = torch.cat([r_mask, t_mask], dim=0)

                idx_perm = torch.randperm(r_tile.shape[0])
                idx_perm = idx_perm[:n_samples]
                tile_perm = r_tile[idx_perm, :]
                mask_perm = r_mask[idx_perm, :]

                # merge tiles
                box_1 = obj.xyxy
                [x_1, y_1, x_2, y_2] = box_1.type(torch.IntTensor)
                x_ref = x_init[:, :, y_1:y_2, x_1:x_2]
                x_new = ((1.0 - mask_perm) * x_ref) + mask_perm * (0.0 * x_ref + 1.0 * tile_perm)

                # randomly roll-back
                rand_rb = torch.rand([n_samples, 1, 1, 1], device=self.estimator.device)
                x_new = torch.where(rand_rb < 0.8, x_new, x_ref)
                x_cand[:, :, y_1:y_2, x_1:x_2] = x_new

            # spatial drop
            n_mask = drop_block2d(x_cand, 0.05, 3)
            x_cand = (1.0 - n_mask) * x_org + n_mask * x_cand
            # x_cand = smooth_image(x_cand, x_org, epsilon, 10)
            x_cand = torch.round(x_cand * 255.0) / 255.0
            x_cand = torch.clamp(x_cand, x_org - 2.5 * self.eps, x_org + 2.5 * self.eps)
            x_cand = torch.clamp(x_cand, 0.0, 1.0)

            # update results
            _, adv_position = self.collector(self.estimator, x_cand)
            for idx in range(n_samples):
                cur_position = adv_position[idx]

                for key, obj in tile_mat.items():

                    idx_i, idx_j = key
                    box_1 = obj.xyxy
                    obj_threshold = obj.threshold
                    [x_1, y_1, x_2, y_2] = box_1.type(torch.IntTensor)
                    overlay = bbox_ioa(box_1.type(torch.FloatTensor), cur_position.type(torch.FloatTensor))
                    bcount = torch.sum(overlay > 0.0).item()

                    x_ref = x_org[:, :, y_1:y_2, x_1:x_2]
                    x_cur = x_cand[idx, :, y_1:y_2, x_1:x_2].clone()

                    pert = x_cur - x_ref
                    loss = self._get_loss(pert, self.eps)
                    eligible = torch.max(torch.abs(pert)) < self.eps and bcount >= obj_threshold
                    tpatch_cur = TileObj(tile_size=tile_size, device=self.estimator.device)
                    tpatch_cur.update(eligible, bcount, torch.sum(loss), x_cur)
                    # insert op
                    prev = tile_mat[(idx_i, idx_j)]
                    prev.insert(tpatch_cur)
                    tile_mat[(idx_i, idx_j)] = prev

        # clean non-active regions
        x_out = x_init.clone()
        x_eval = self._assemble(tile_mat, x_org)
        _, adv_position = self.collector(self.estimator, x_eval)
        cur_position = adv_position[0]
        for key, obj in tile_mat.items():
            idx_i, idx_j = key
            box_1 = obj.xyxy
            [x_1, y_1, x_2, y_2] = box_1.type(torch.IntTensor)
            overlay = bbox_ioa(box_1.type(torch.FloatTensor), cur_position.type(torch.FloatTensor))
            bcount = torch.sum(overlay > 0.0).item()

            x_ref = x_init[:, :, y_1:y_2, x_1:x_2]
            x_tag = x_eval[:, :, y_1:y_2, x_1:x_2]
            cur_mask = torch.zeros_like(x_ref)
            if bcount > 1:
                bbox = cur_position[overlay > 0.0]
                for box in bbox:
                    bx1 = torch.clamp_min(box[0] - x_1, 0)
                    by1 = torch.clamp_min(box[1] - y_1, 0)
                    bx2 = torch.clamp_max(box[2] - x_1, (x_2 - x_1 - 1).to(self.estimator.device))
                    by2 = torch.clamp_max(box[3] - y_1, (y_2 - y_1 - 1).to(self.estimator.device))
                    cur_mask[:, :, by1:by2, bx1:bx2] = 1.0
            else:
                prev = tile_mat[(idx_i, idx_j)]
                prev.pop()
                tile_mat[(idx_i, idx_j)] = prev

            a_mask = drop_block2d(x_ref, 0.05, 1)
            cur_mask = cur_mask * a_mask
            updated = ((1.0 - cur_mask) * x_ref) + cur_mask * (0.0 * x_ref + 1.0 * x_tag)
            updated = ((1.0 - cur_mask) * x_ref) + cur_mask * (0.0 * x_ref + 1.0 * updated)

            x_out[:, :, y_1:y_2, x_1:x_2] = updated

        return x_out, tile_mat

        Generate an initial perturbation for each grid.

        :param tile_mat: Internal structure used to store patches for each mesh.
        :param x_init: Perturbed images from previous runs.
        :param x_org: The original images.
        :param tile_size: The size of each tile.
        :return: Guessed images and internal structure.
        
art/attacks/evasion/steal_now_attack_later/steal_now_attack_later.py