def diffuse(self, target, context, center_x, center_y, crop_x, crop_y, num_viz=0):
    'Diffuses the target image to a context image.\n\n    Basically, this function is a motified version of `self.invert()`. More\n    concretely, the encoder regularizer is removed from the objectives and the\n    reconstruction loss is computed from the masked region.\n\n    Args:\n      target: Target image (foreground).\n      context: Context image (background).\n      center_x: The x-coordinate of the crop center.\n      center_y: The y-coordinate of the crop center.\n      crop_x: The crop size along the x-axis.\n      crop_y: The crop size along the y-axis.\n      num_viz: Number of intermediate outputs to visualize. (default: 0)\n\n    Returns:\n      A two-element tuple. First one is the inverted code. Second one is a list\n        of intermediate results, where first image is the direct copy-paste\n        image, second one is the reconstructed result from the initial latent\n        code, remainings are from the optimization process every\n        `self.iteration // num_viz` steps.\n    '
    image_shape = (self.G.image_channels, self.G.resolution, self.G.resolution)
    mask = np.zeros((1, *image_shape), dtype=np.float32)
    xx = (center_x - (crop_x // 2))
    yy = (center_y - (crop_y // 2))
    mask[:, :, yy:(yy + crop_y), xx:(xx + crop_x)] = 1.0
    target = target[np.newaxis]
    context = context[np.newaxis]
    x = ((target * mask) + (context * (1 - mask)))
    x = self.G.to_tensor(x.astype(np.float32))
    x.requires_grad = False
    mask = self.G.to_tensor(mask.astype(np.float32))
    mask.requires_grad = False
    init_z = _get_tensor_value(self.E.net(x).view(1, *self.encode_dim))
    init_z = init_z.astype(np.float32)
    z = torch.Tensor(init_z).to(self.run_device)
    z.requires_grad = True
    optimizer = torch.optim.Adam([z], lr=self.learning_rate)
    viz_results = []
    viz_results.append(self.G.postprocess(_get_tensor_value(x))[0])
    x_init_inv = self.G.net.synthesis(z)
    viz_results.append(self.G.postprocess(_get_tensor_value(x_init_inv))[0])
    pbar = tqdm(range(1, (self.iteration + 1)), leave=True)
    for step in pbar:
        loss = 0.0
        x_rec = self.G.net.synthesis(z)
        loss_pix = torch.mean((((x - x_rec) * mask) ** 2))
        loss = (loss + (loss_pix * self.loss_pix_weight))
        log_message = f'loss_pix: {_get_tensor_value(loss_pix):.3f}'
        if self.loss_feat_weight:
            x_feat = self.F.net((x * mask))
            x_rec_feat = self.F.net((x_rec * mask))
            loss_feat = torch.mean(((x_feat - x_rec_feat) ** 2))
            loss = (loss + (loss_feat * self.loss_feat_weight))
            log_message += f', loss_feat: {_get_tensor_value(loss_feat):.3f}'
        log_message += f', loss: {_get_tensor_value(loss):.3f}'
        pbar.set_description_str(log_message)
        if self.logger:
            self.logger.debug(f'Step: {step:05d}, lr: {self.learning_rate:.2e}, {log_message}')
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        if ((num_viz > 0) and ((step % (self.iteration // num_viz)) == 0)):
            viz_results.append(self.G.postprocess(_get_tensor_value(x_rec))[0])
    return (_get_tensor_value(z), viz_results)
Diffuses the target image to a context image.

Basically, this function is a motified version of `self.invert()`. More
concretely, the encoder regularizer is removed from the objectives and the
reconstruction loss is computed from the masked region.

Args:
  target: Target image (foreground).
  context: Context image (background).
  center_x: The x-coordinate of the crop center.
  center_y: The y-coordinate of the crop center.
  crop_x: The crop size along the x-axis.
  crop_y: The crop size along the y-axis.
  num_viz: Number of intermediate outputs to visualize. (default: 0)

Returns:
  A two-element tuple. First one is the inverted code. Second one is a list
    of intermediate results, where first image is the direct copy-paste
    image, second one is the reconstructed result from the initial latent
    code, remainings are from the optimization process every
    `self.iteration // num_viz` steps.
def diffuse(self, target, context, center_x, center_y, crop_x, crop_y, num_viz=0):
    'Diffuses the target image to a context image.\n\n    Basically, this function is a motified version of `self.invert()`. More\n    concretely, the encoder regularizer is removed from the objectives and the\n    reconstruction loss is computed from the masked region.\n\n    Args:\n      target: Target image (foreground).\n      context: Context image (background).\n      center_x: The x-coordinate of the crop center.\n      center_y: The y-coordinate of the crop center.\n      crop_x: The crop size along the x-axis.\n      crop_y: The crop size along the y-axis.\n      num_viz: Number of intermediate outputs to visualize. (default: 0)\n\n    Returns:\n      A two-element tuple. First one is the inverted code. Second one is a list\n        of intermediate results, where first image is the direct copy-paste\n        image, second one is the reconstructed result from the initial latent\n        code, remainings are from the optimization process every\n        `self.iteration // num_viz` steps.\n    '
    image_shape = (self.G.image_channels, self.G.resolution, self.G.resolution)
    mask = np.zeros((1, *image_shape), dtype=np.float32)
    xx = (center_x - (crop_x // 2))
    yy = (center_y - (crop_y // 2))
    mask[:, :, yy:(yy + crop_y), xx:(xx + crop_x)] = 1.0
    target = target[np.newaxis]
    context = context[np.newaxis]
    x = ((target * mask) + (context * (1 - mask)))
    x = self.G.to_tensor(x.astype(np.float32))
    x.requires_grad = False
    mask = self.G.to_tensor(mask.astype(np.float32))
    mask.requires_grad = False
    init_z = _get_tensor_value(self.E.net(x).view(1, *self.encode_dim))
    init_z = init_z.astype(np.float32)
    z = torch.Tensor(init_z).to(self.run_device)
    z.requires_grad = True
    optimizer = torch.optim.Adam([z], lr=self.learning_rate)
    viz_results = []
    viz_results.append(self.G.postprocess(_get_tensor_value(x))[0])
    x_init_inv = self.G.net.synthesis(z)
    viz_results.append(self.G.postprocess(_get_tensor_value(x_init_inv))[0])
    pbar = tqdm(range(1, (self.iteration + 1)), leave=True)
    for step in pbar:
        loss = 0.0
        x_rec = self.G.net.synthesis(z)
        loss_pix = torch.mean((((x - x_rec) * mask) ** 2))
        loss = (loss + (loss_pix * self.loss_pix_weight))
        log_message = f'loss_pix: {_get_tensor_value(loss_pix):.3f}'
        if self.loss_feat_weight:
            x_feat = self.F.net((x * mask))
            x_rec_feat = self.F.net((x_rec * mask))
            loss_feat = torch.mean(((x_feat - x_rec_feat) ** 2))
            loss = (loss + (loss_feat * self.loss_feat_weight))
            log_message += f', loss_feat: {_get_tensor_value(loss_feat):.3f}'
        log_message += f', loss: {_get_tensor_value(loss):.3f}'
        pbar.set_description_str(log_message)
        if self.logger:
            self.logger.debug(f'Step: {step:05d}, lr: {self.learning_rate:.2e}, {log_message}')
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        if ((num_viz > 0) and ((step % (self.iteration // num_viz)) == 0)):
            viz_results.append(self.G.postprocess(_get_tensor_value(x_rec))[0])
    return (_get_tensor_value(z), viz_results)